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