1. 簡介
這時一組驅動的集合,它們可以用于所有的基于linux的輸入設備,雖然目前它只是用于USB輸入設備,將來(2.5、2.6版本)它們將會被擴展并替換掉現存的多數輸入系統,這就是為什么它們被放在drivers/input/目錄下,而不是drivers/usb/。
輸入設備驅動的核心是input模塊,它需要在其他輸入模塊之前被加載--它是輸入系統其它兩個模塊之間通訊的橋梁:
1.1 設備驅動(Device drivers)
這些模塊負責和實際的硬件打交道(例如通過USB),給input模塊提供相應的事件(按鍵,鼠標移動)
1.2 事件處理模塊(Event handlers)
這些模塊從input模塊獲得事件信息,并根據需要通過不同的接口傳遞這些事件--往kernel傳遞按鍵事件,或者通過模擬的PS/2接口給GPM和X傳遞鼠標移動事件,等等。
2. 一個簡單的例子
通常,對于大多數配置來說,系統有一個USB鼠標和一個USB鍵盤,你需要加載以下幾個模塊(或者把它們編譯到內核中):
input
mousedev
keybdev
usbcore
uhci_hcdor ohci_hcd or ehci_hcd
usbhid
在這之后,USB鍵盤直接就可以工作了,USB鼠標會作為一個字符設備,主次設備號分別為13和63:
crw-r--r--?? 1 root????root????? 13,? 63 Mar 28 22:45 mice
你需要主動創建該鼠標設備節點,創建的命令如下:
cd/dev
mkdirinput
mknodinput/mice c 13 63
之后,你必須告訴GPM和XFree你要使用這個鼠標設備 - 對于GPM,應該象以下的指令:
gpm-t ps2 -m /dev/input/mice
對于X:
Section"Pointer"
Protocol???"ImPS/2"
Device?????"/dev/input/mice"
ZAxisMapping 4 5
EndSection
做完以上步驟以后,你就可以正常地使用USB鼠標和鍵盤了。
3. 詳細描述
~~~~~~~~~~~~~~~~~~~~~~~
3.1 設備驅動(Device drivers)
~~~~~~~~~~~~~~~~~~
設備驅動模塊產生輸入事件,這些事件在沒有經過處理之前是沒有什么用處的,所以你需要用到3.2節的某些模塊。
3.1.1 usbhid
~~~~~~~~~~~~
usbhid可以說是最龐大和復雜的驅動了。它處理所有的HID設備,他之所以這么復雜和龐大,原因是設備類型種類繁多,USB HID的規格也相當不簡單。
目前,它處理USB鼠標,游戲控制桿,方向盤,鍵盤,軌跡球和數字化儀。
而且,USB也使用HID來實現監視器控制,揚聲器控制,UPSs,LCDs等等很多外設。
監視器和揚聲器控制比較容易添加到hid/input接口中,但是UPSs和LCDs就不是這么簡單,為此,設計了hiddev接口,詳細的信息請參考Documentation/hid/hiddev.txt。
usbhid模塊非常易于使用,它沒有任何參數,自動檢測插入的HID設備,是的,它能用合適的方式進行檢測。
不過,因為設備實在是太過于多樣性了,你可能遇到某些設備工作的不好。這時你可以在hid-core.c的開始加上#defineDEBUG,把syslog traces發給我。
3.1.2 usbmouse
~~~~~~~~~~~~~~
對于嵌入式系統,只為了使用鼠標功能而加入整個龐大的usbhid顯然不是一個好的選擇,這時可以只使用usbmouse驅動,它只處理usb鼠標。它使用了簡易的HIDBP協議。當然這要求你的鼠標必須也要支持這一簡易協議。最好,如果你沒有很強烈地理由,請使用usbhid。
3.1.3 usbkbd
~~~~~~~~~~~~
就像usbmouse一樣,這個模塊用簡易的HIDBP協議與鍵盤通信。它很小,但不支持任何額外的按鍵。沒有特別的原因時,也請使用usbhid。
3.1.4 wacom
~~~~~~~~~~~
這是Wacom Graphire和Intuos tablets的驅動。它不是用于Wacom PenPartner,一個由HID驅動處理的設備。盡管Intuos 和Graphiretablets聲稱他們是HID tablets,但實際上不是,所以需要這個特別的驅動。
3.1.5 iforce
~~~~~~~~~~~~
用于I-Force游戲桿和滾輪的驅動,通過USB和RS232連接。現在它包含了ForceFeedback的支持,盡管Immersion公司認為該協議是商業機密而且沒有公開它的任何信息。
3.2 Event handlers
~~~~~~~~~~~~~~~~~~
Eventhandlers根據實際需要,把設備的事件分發到用戶空間或者內核中。
3.2.1 keybdev
~~~~~~~~~~~~~
keybdev目前是一個不太好的駭客工具,它把輸入事件轉換為體系相關的鍵盤raw模式(x86中的Xlated AT Set2),然后傳遞給keyboard.c模塊中的handle_scancode函數。當體系的keybdev能產生rawmode時,它會工作得很好,其他體系也能添加進來。
正確地方法是直接把輸入事件傳遞到keyboard.c中,最好的是keyboard.c本身就是一個event handler。這一工作由下面提到的網頁提供了一個input patch來完成。
3.2.2 mousedev
~~~~~~~~~~~~~~
mousedev也是一個駭客工具,它使得那些需要使用鼠標的程序可以工作。它從鼠標或者數字化儀獲取事件,然后生成了一個PS/2類型(例如/dev/psaux)的鼠標設備來讓用戶空間的程序使用。理想的情況下,程序應該使用一個更加合理的接口,例如evdev。
上面提到的Mousedev設備在/dev/input中的呈現如下:
crw-r--r--?? 1 root????root????? 13,? 32 Mar 28 22:45 mouse0
crw-r--r--?? 1 root????root????? 13,? 33 Mar 29 00:41 mouse1
crw-r--r--?? 1 root????root????? 13,? 34 Mar 29 00:41 mouse2
crw-r--r--?? 1 root????root????? 13,? 35 Apr?1 10:50 mouse3
...
...
crw-r--r--?? 1 root????root????? 13,? 62 Apr?1 10:50 mouse30
crw-r--r--?? 1 root????root????? 13,? 63 Apr?1 10:50 mice
除了最后的'mice',每個'mouse'設備被分配給單一的鼠標或者是數字化儀。最后的'mice',這個單一的字符設備由所有的鼠標和數字化儀共享,就算沒有任何真正的鼠標連接進來,這個設備也依然存在。這一特性對USB鼠標的熱插拔功能很有用。這樣盡管沒有鼠標連接,程序依然可以打開該設備。
在XFree86中,內核的配置項:CONFIG_INPUT_MOUSEDEV_SCREEN_[XY],指定了屏幕的像素。如果你想在X中使用數字化儀,這點是必要的,因為她的移動會被通過虛擬的PS/2鼠標發送到X中,這時需要計算正確地比例。如果你只是使用鼠標,這個配置值是沒有用處的。
依賴于程序希望讀取什么數據,Mousedev會生成PS/2, ImPS/2(Microsoft IntelliMouse) 或者
ExplorerPS/2 (IntelliMouse Explorer)協議格式的數據。你可以把GPM和X設置成這里的任一種。如果你想使用USB鼠標上的滾輪,你可以配置為ImPS/2,而當你希望使用額外的按鍵時,就使用ExplorerPS/2。
3.2.3 joydev
~~~~~~~~~~~~
Joydev實現了Linux joystick 的v0.x和v1.x版的api,有點類似之前內核使用的驅動:drivers/char/joystick/joystick.c。細節請進一步參考內核文檔:joystick-api.txt。一旦有joystick連接到系統中,我們可以通過/dev/input中的以下節點訪問它:
crw-r--r--?? 1 root????root????? 13,?? 0 Apr?1 10:50 js0
crw-r--r--?? 1 root????root????? 13,?? 1 Apr?1 10:50 js1
crw-r--r--?? 1 root????root????? 13,?? 2 Apr?1 10:50 js2
crw-r--r--?? 1 root????root????? 13,?? 3 Apr?1 10:50 js3
...
一直可以到:js31.
3.2.4 evdev
~~~~~~~~~~~
evdev是一個通用的輸入事件接口,它把內核產生的事件,連同時間戳一起,直接傳遞到用戶空間的應用程序中。該接口的API還在不斷完善中,但現在已經可以使用它們。該接口我們會在下面的第5節說明。
GPM和X可以通過該方式來獲取鍵盤和鼠標的事件。無需內核特別支持,它就可以允許X對它進行多線程的訪問。事件編碼對所有平臺都是統一的并且是硬件無關的。
設備節點位于 /dev/input:
crw-r--r--?? 1 root????root????? 13,? 64 Apr?1 10:49 event0
crw-r--r--?? 1 root????root????? 13,? 65 Apr?1 10:50 event1
crw-r--r--?? 1 root????root????? 13,? 66 Apr?1 10:50 event2
crw-r--r--?? 1 root????root????? 13,? 67 Apr?1 10:50 event3
...
一直可以到:event31.
4. 驗證是否可以正常工作
~~~~~~~~~~~~~~~~~~~~~~~~
在鍵盤上敲幾個鍵就足以檢查USB鍵盤是否工作正常,也能檢查是否內核的驅動是否工作正常。
敲入命令:"cat /dev/input/mouse0" (c, 13, 32)可以驗證鼠標是否被正確地枚舉,當你移動鼠標時,屏幕會顯示一些字符。
你可以用jstest工具來測試joystick是否正常工作,該工具在joystick包中(參見文檔:Documentation/input/joystick.txt)
可以使用evtest工具對event設備進行測試,該工具可以從LinuxConsole項目的CVS中獲取(見下面的URL)
5. Event interface
~~~~~~~~~~~~~~~~~~
如果你希望在你的任何應用中(X,gpm,svgalib ...)添加event設備的支持,我(vojtech@ucw.cz)非常樂意盡我所能提供幫助。這里我說明一下當前的進展狀況,雖然還在不斷地擴展中,但是基本的接口是不會改變而導致不兼容的問題:
你可以在/dev/input/eventX設備上使用阻塞,非阻塞的讀操作,也可以用select()操作。你會在一次讀取中返回一個完整的輸入事件,它的結構如下:
struct input_event {
structtimeval time;
unsignedshort type;
unsignedshort code;
unsignedint value;
};
'time'字段是時間戳,它返回時間發生時的時間。關于type字段,EV_REL代表返回的是相對移動值,EV_KEY代表的是按鍵按下或釋放,更多的類型定義可以參見:include/linux/input.h。
'code'字段是事件的編碼,例如可以是REL_X或KEY_BACKSPACE,你也可以從include/linux/input.h中得到完整的列表。
'value'字段是該事件攜帶的參數值。可以是EV_REL事件的相對變化量,EV_ABS事件的一個新的絕對值(joysticks...),對于EV_KEY事件,該值是0代表按鍵釋放,為1代表按鍵按下,為2代表自動重復。
?
評論
查看更多