日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

input type类型_设备树下的input子系统

發(fā)布時(shí)間:2025/3/15 windows 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 input type类型_设备树下的input子系统 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

更多文章請(qǐng)關(guān)注公眾號(hào) :麻瓜技術(shù)閑談

input 就是輸入的意思,因此 input 子系統(tǒng)就是管理輸入的子系統(tǒng),和 pinctrl 和 gpio 子系統(tǒng)一樣,都是 Linux 內(nèi)核針對(duì)某一類設(shè)備而創(chuàng)建的框架。比如按鍵輸入、鍵盤、鼠標(biāo)、觸摸屏等等這些都屬于輸入設(shè)備,不同的輸入設(shè)備所代表的含義不同,按鍵和鍵盤就是代表按鍵信息,鼠標(biāo)和觸摸屏代表坐標(biāo)信息,因此在應(yīng)用層的處理就不同,對(duì)于驅(qū)動(dòng)編寫(xiě)者而言不需要去關(guān)心應(yīng)用層的事情,我們只需要按照要求上報(bào)這些輸入事件即可。為此 input子系統(tǒng)分為 input 驅(qū)動(dòng)層、input 核心層、input 事件處理層,最終給用戶空間提供可訪問(wèn)的設(shè)備節(jié)點(diǎn),input 子系統(tǒng)框架如圖 58.1.1.1 所示:

圖 58.1.1.1 中左邊就是最底層的具體設(shè)備,比如按鍵、USB 鍵盤/鼠標(biāo)等,中間部分屬于Linux 內(nèi)核空間,分為驅(qū)動(dòng)層、核心層和事件層,最右邊的就是用戶空間,所有的輸入設(shè)備以文件的形式供用戶應(yīng)用程序使用。可以看出 input 子系統(tǒng)用到了我們前面講解的驅(qū)動(dòng)分層模型,我們編寫(xiě)驅(qū)動(dòng)程序的時(shí)候只需要關(guān)注中間的驅(qū)動(dòng)層、核心層和事件層,這三個(gè)層的分工如下: 驅(qū)動(dòng)層:輸入設(shè)備的具體驅(qū)動(dòng)程序,比如按鍵驅(qū)動(dòng)程序,向內(nèi)核層報(bào)告輸入內(nèi)容。 核心層:承上啟下,為驅(qū)動(dòng)層提供輸入設(shè)備注冊(cè)和操作接口。通知事件層對(duì)輸入事件進(jìn)行處理。 事件層:主要和用戶空間進(jìn)行交互。

input 驅(qū)動(dòng)編寫(xiě)流程

1767 struct class input_class = { 1768 .name = "input", 1769 .devnode = input_devnode, 1770 }; ...... 2414 static int __init input_init(void) 2415 { 2416 int err; 2418 err = class_register(&input_class); 2419 if (err) { 2420 pr_err("unable to register input_dev classn"); 2421 return err; 2422 } 2423 2424 err = input_proc_init(); 2425 if (err) 2426 goto fail1; 2427 2428 err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0), 2429 INPUT_MAX_CHAR_DEVICES, "input"); 2430 if (err) { 2431 pr_err("unable to register char major %d",INPUT_MAJOR); 2432 goto fail2; 2433 } 2434 2435 return 0; 2436 2437 fail2: input_proc_exit(); 2438 fail1: class_unregister(&input_class); 2439 return err; 2440 }

1、注冊(cè) input_dev 在使用 input 子系統(tǒng)的時(shí)候我們只需要注冊(cè)一個(gè) input 設(shè)備即可,input_dev 結(jié)構(gòu)體表示 input 設(shè)備,此結(jié)構(gòu)體定義在 include/linux/input.h 文件中,定義如下(有省略):

示例代碼 58.1.2.2 input_dev 結(jié)構(gòu)體 121 struct input_dev { 122 const char *name; 123 const char *phys; 124 const char *uniq; 125 struct input_id id; 126 127 unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; 128 129 unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; /* 事件類型的位圖 */ 130 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; /* 按鍵值的位圖 */ 131 unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; /* 相對(duì)坐標(biāo)的位圖 */ 132 unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; /* 絕對(duì)坐標(biāo)的位圖 */ 133 unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; /* 雜項(xiàng)事件的位圖 */ 134 unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; /*LED 相關(guān)的位圖 */ 135 unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];/* sound 有關(guān)的位圖 */ 136 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; /* 壓力反饋的位圖 */ 137 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; /*開(kāi)關(guān)狀態(tài)的位圖 */ ...... 189 bool devres_managed; 190 };

第 129 行,evbit 表示輸入事件類型,可選的事件類型定義在 include/uapi/linux/input.h 文件 中,事件類型如下:

示例代碼 58.1.2.3 事件類型 #define EV_SYN 0x00 /* 同步事件 */ #define EV_KEY 0x01 /* 按鍵事件 */ #define EV_REL 0x02 /* 相對(duì)坐標(biāo)事件 */ #define EV_ABS 0x03 /* 絕對(duì)坐標(biāo)事件 */ #define EV_MSC 0x04 /* 雜項(xiàng)(其他)事件 */ #define EV_SW 0x05 /* 開(kāi)關(guān)事件 */ #define EV_LED 0x11 /* LED */ #define EV_SND 0x12 /* sound(聲音) */ #define EV_REP 0x14 /* 重復(fù)事件 */ #define EV_FF 0x15 /* 壓力事件 */ #define EV_PWR 0x16 /* 電源事件 */ #define EV_FF_STATUS 0x17 /* 壓力狀態(tài)事件 */

比如本章我們要使用到按鍵,那么就需要注冊(cè) EV_KEY 事件,如果要使用連按功能的話還需要注冊(cè) EV_REP 事件。繼續(xù)回到示例代碼 58.1.2.2 中,第 129 行~137 行的 evbit、keybit、relbit 等等都是存放不同事件對(duì)應(yīng)的值。比如我們本章要使用按鍵事件,因此要用到 keybit,keybit 就是按鍵事件使用的位圖,Linux 內(nèi)核定義了很多按鍵值,這些按鍵值定義在include/uapi/linux/input.h 文件中,按鍵值如下: 示例代碼 58.1.2.4 按鍵值

215 #define KEY_RESERVED 0 216 #define KEY_ESC 1 217 #define KEY_1 2 218 #define KEY_2 3 219 #define KEY_3 4 220 #define KEY_4 5 221 #define KEY_5 6 222 #define KEY_6 7 223 #define KEY_7 8 224 #define KEY_8 9 225 #define KEY_9 10 226 #define KEY_0 11 ...... 794 #define BTN_TRIGGER_HAPPY39 0x2e6 795 #define BTN_TRIGGER_HAPPY40 0x2e7

2、上報(bào)輸入事件 當(dāng)我們向 Linux 內(nèi)核注冊(cè)好 input_dev 以后還不能高枕無(wú)憂的使用 input 設(shè)備,input 設(shè)備都是具有輸入功能的,但是具體是什么樣的輸入值 Linux 內(nèi)核是不知道的,我們需要獲取到具體的輸入值,或者說(shuō)是輸入事件,然后將輸入事件上報(bào)給 Linux 內(nèi)核。比如按鍵,我們需要在按鍵中斷處理函數(shù),或者消抖定時(shí)器中斷函數(shù)中將按鍵值上報(bào)給 Linux 內(nèi)核,這樣 Linux 內(nèi)核才能獲取到正確的輸入值。不同的事件,其上報(bào)事件的 API 函數(shù)不同,我們依次來(lái)看一下一些常用的事件上報(bào) API 函數(shù)。 首先是 input_event 函數(shù),此函數(shù)用于上報(bào)指定的事件以及對(duì)應(yīng)的值,函數(shù)原型如下:

void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)函數(shù)參數(shù)和返回值含義如下: dev:需要上報(bào)的 input_dev。 type: 上報(bào)的事件類型,比如 EV_KEY。 code:事件碼,也就是我們注冊(cè)的按鍵值,比如 KEY_0、KEY_1 等等。 value:事件值,比如 1 表示按鍵按下,0 表示按鍵松開(kāi)

3、代碼示例

和按鍵中斷程序類似設(shè)備樹(shù)下的中斷,唯一不同的是在keyio_init函數(shù)里申請(qǐng)完中斷后要申請(qǐng)輸入事件、注冊(cè)輸入設(shè)備

/* 申請(qǐng) input_dev */keyinputdev.inputdev = input_allocate_device();keyinputdev.inputdev->name = KEYINPUT_NAME;keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) |BIT_MASK(EV_REP);input_set_capability(keyinputdev.inputdev, EV_KEY, KEY_0);/* 注冊(cè)輸入設(shè)備 */ret = input_register_device(keyinputdev.inputdev);if (ret) {printk("register input device failed!rn");return ret;}

timer_function定時(shí)器功能函數(shù)里改為上報(bào)按鍵事件

if(value == 0){ /* 按下按鍵 *//* 上報(bào)按鍵值 *///input_event(dev->inputdev, EV_KEY, keydesc->value, 1);input_report_key(dev->inputdev, keydesc->value, 1);/*1,按下*/input_sync(dev->inputdev);} else { /* 按鍵松開(kāi) *///input_event(dev->inputdev, EV_KEY, keydesc->value, 0);input_report_key(dev->inputdev, keydesc->value, 0);input_sync(dev->inputdev);} 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的input type类型_设备树下的input子系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。