input子系統(tǒng)由驅(qū)動(dòng)層drivers,輸入子系統(tǒng)核心層input core,事件處理層event handler組成。
1個(gè)輸入事件,通過輸入裝備發(fā)給系統(tǒng)如鼠標(biāo)移動(dòng),鍵盤按鍵按下等通過device driver->input core(handler->event函數(shù))->event handler->user space的順序到達(dá)用戶空間傳給利用程序。
1個(gè)輸失事件,通過系統(tǒng)發(fā)給輸入裝備,通過user space->event handler->input core(dev->event函數(shù))->device driver
1、驅(qū)動(dòng)功能層:負(fù)責(zé)和底層的硬件裝備打交道,將底層硬件裝備對(duì)用戶輸入的響應(yīng)轉(zhuǎn)換為標(biāo)準(zhǔn)的輸入事件以后再向上發(fā)送給輸入系統(tǒng)核心層
2、Input系統(tǒng)核心層:由driver/input/input.c及相干頭文件實(shí)現(xiàn),他對(duì)下提供了裝備驅(qū)動(dòng)層的接口,對(duì)上提供了事件處理層的變成接口。
3、事件處理層將硬件裝備上報(bào)的事件分發(fā)到用戶空間和內(nèi)核。
結(jié)構(gòu)圖以下:
1)包括頭文件<linux/input.h>,他是input子系統(tǒng)的接口,提供了必要的定義消息
2)Input_allocate_device()
分配了1個(gè)Input device的結(jié)構(gòu),設(shè)置他的bit field來告知input子系統(tǒng)他能產(chǎn)生或接收甚么事件。
3)input_register_device(struct input_dev *dev)
將dev結(jié)構(gòu)體添加到input_dev_list全局鏈表中去
通過input_attach_handler(struct input_dev *dev, struct input_handler *handler)來查找對(duì)應(yīng)的handler,
input_attach_handler里面實(shí)際調(diào)用了input_match_device(const struct input_device_id *id,struct input_dev *dev)
1旦input_attach_handler找到了對(duì)應(yīng)的handler,就履行handler->connect
4)input_report_key(struct input_dev *dev, unsigned int code, int value)
5)input_sync(struct input_dev *dev)
告知事件的接收者,到此為止為1次完全的消息。比如我們?cè)?span style="font-family:Arial">touch screen上取得了x、y的值,要使作為1次事件,那末將input_sync加在report x、y值得后面。
6)其他的事件type,輸失事件處理
其他的事件有:
EV_LED:用作鍵盤的LED燈
EV_SND:用作鍵盤的蜂鳴器
他和鍵盤事件很相似,只不過鍵盤事件是INPUT_PASS_TO_DEVICE,而輸失事件是INPUT_PASS_TO_HANDLERS,從系統(tǒng)到輸入裝備的驅(qū)動(dòng)程序,如果你的驅(qū)動(dòng)程序要處理這些事件,必須設(shè)置evbit中相應(yīng)位,而且要實(shí)現(xiàn)1個(gè)回調(diào)函數(shù)。
struct input_dev *button_dev;
button_dev->event = button_event;這個(gè)便是處理輸失事件的回調(diào)函數(shù)
Makefile以下:
Include/linux/bitops.h中定義了
#define BIT(nr) (1UL << (nr))
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BTN_0 0x100
button_dev->evbit[0] = BIT_MASK(EV_KEY);
button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
說明:
1)上面的0x100表示BTN_0這個(gè)bit在所有的bit中是0x100(bit 256)位,那末
BIT_WORD(BTN_0)代表bit 256在keybit這個(gè)數(shù)組的第幾個(gè)數(shù)組(第8個(gè))
BIT_MASK(BTN_0)代表bit 256在keybit這個(gè)數(shù)組的第幾個(gè)數(shù)組里面的值(第8個(gè)數(shù)組的bit0)
2)事件類型type――編碼code――值value
evbit是事件數(shù)組,evbit這個(gè)事件數(shù)組里面可以放很多事件類型,比如key、abs等
事件key里面又有很多具體編碼BTN_0、BTN_TOUCH等
事件abs里面也有很多具體編碼ABS_X、ABS_Y等
不同編碼有不同的值
另外http://blog.csdn.net/ylyuanlu/article/details/6704744 這篇博客對(duì)以下說的挺詳細(xì)的
1)input子系統(tǒng)的struct input_dev、struct handler的注冊(cè)
2)struct input_dev與struct input_handler怎樣相互匹配(類似于device和driver匹配)
3)事件處理進(jìn)程
以上只是1個(gè)簡(jiǎn)單的利用程序測(cè)試。當(dāng)你按下K1的時(shí)候,串口終端會(huì)有顯示的input dev上報(bào)的按鍵的消息。
編寫利用程序的時(shí)候如何肯定是哪一個(gè)eventX呢,cat /proc/bus/input/devices,輸出打印消息以下:
這里插入了鼠標(biāo),通過比較VID、PID來找到對(duì)應(yīng)的usb mouse裝備,然后找到對(duì)應(yīng)的mouse0、event1
另外還有很多里面ioctl調(diào)用的內(nèi)容沒有實(shí)驗(yàn),具體可以參考這篇博客http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html,對(duì)ioctl的每一個(gè)case和read調(diào)用都試1遍,找到自己的體會(huì)。