數據結構 |
用途 |
定義位置 |
具體數據結構的分配和初始化 |
Struct input_dev |
驅動層物理Input設備的基本數據結構 |
Input.h |
通常在具體的設備驅動中分配和填充具體的設備結構 |
Struct Evdev Struct Mousedev Struct Keybdev… |
Event Handler層邏輯Input設備的數據結構 |
Evdev.c Mousedev.c Keybdev.c |
Evdev.c/Mouedev.c …中分配
|
Struct Input_handler |
Event Handler的結構 |
Input.h |
Event Handler層,定義一個具體的Event Handler。 |
Struct Input_handle |
用來創建驅動層Dev和Handler鏈表的鏈表項結構 |
Input.h |
Event Handler層中分配,包含在Evdev/Mousedev…中。 |
------------------------------
input subsystem 用來統一處理數據輸入設備,例如鍵盤,鼠標,遊戲杆,觸摸屏等等。
這裏引用 Linux Journal 上的一個圖來說明input subsystem 的架構:
(http://www.linuxjournal.com/article/6396)
我們可以看到,input core 用來協調硬件的input事件 和 用戶層應用之間的通訊。
這裏再引用 ELDD 上的一個圖片,來詳細說明其內部的結構:
在內核中,input_dev 表示一個 input設備;input_handler 來表示input設備的 interface。
所有的input_dev 用雙向鏈表 input_dev_list 連起來,如圖所示:
在調用 int input_register_device(struct input_dev *dev) 的時候,會將新的 input_dev 加入到這個鏈表中。
所有的input_handler 用雙向鏈表 input_handler_list 連起來, 如圖所示:
在調用 int input_register_handler(struct input_handler *handler) 的時候,會將新的 input_handler 加入到這個鏈表中。
每個input_dev 和 input_handler 是要關聯上才能工作的,在註冊 input_dev 或者 input_handler的時候,就遍歷上面的列表,找到相匹配的,然後調用 input_handler 的 connect函數來將它們聯繫到一起。
通常在input_handler 的 connect函數中,就會創建 input_handle, input_handle就是負責將 input_dev 和 input_handler 聯繫在一起的,如圖所示:
這裏需要額外說明一下的是:
input_dev 中的 h_node 是 input_handle 鏈表的list節點,也就是說,一個input_dev,可以對應多個 input_handle.
當設備產生 input event 的時候,例如按下了一個鍵,驅動就會調用 input_handler 中的 event 函數,同時,如果input_dev 支持的話,也會調用 input_dev 的 event 函數。
這樣,設備產生的事件就會被驅動記錄下來。
當用戶層的程序需要獲知這些事件的時候,會調用 input_handler中的 struct file_operations *fops 中的相應函數,例如 read 等等。
可以看出,整個 input 框架的構思還是比較簡潔方便的。