Linux Input drivers v1.0
(c) 1999-2001 Vojtech Pavlik<vojtech@ucw.cz>
Sponsored by SuSE
----------------------------------------------------------------------------
0.著作權說明
~~~~~~~~~~~~~
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General PublicLicense as published by the Free
Software Foundation; either version 2 ofthe License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
Youshould have received a copy of the GNU General Public License along
with this program; if not, write to theFree Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA02111-1307 USA
Should you need to contact me, the author, you can do so either bye-mail
- mail your message to<vojtech@ucw.cz>, or by paper mail: Vojtech Pavlik,
Simunkova 1594, Prague 8, 182 00 CzechRepublic
Foryour convenience, the GNU General Public License version 2 is included
in the package: See the file COPYING.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
本文由DroidPhone 翻譯:http://blog.csdn.net/droidphone
Kernel版本:V3.4.10
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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代表自動重複。