輸入設備總類繁雜,包括按鍵,鍵盤,觸摸屏,鼠標,搖桿等等,它們本身都是字符設備,不過內核為了能將這些設備的共性抽象出來,簡化驅動的開發,建立了一個 Input 子系統。用戶只需要根據內核提供的 input 子系統下提供的 API 函數接口,完成設備的注冊即可。在本章節中我們來學習一下如何使用 Linux內核中的 input 子系統。 1.運行測試 1.1 編譯驅動程序 和前面章節中驅動測試程序一樣需要一個 Makefile 文件,只是將 obj-m 的值改為 key_input.o,Makefile 文 件內容如下: KERNELDIR := /home/topeet/kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga CURRENT_PATH := $(shell pwd) obj-m := key_input.o build: kernel_modules kernel_modules: $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules clean: $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean 首先我們在終端輸入兩個命令(設置兩個環境變量): export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- 然后執行“make”命令編譯模塊,編譯完成生成 key_input.ko 模塊文件。 2.編譯應用測試程序 輸入如下命令編譯應用測試程序: arm-linux-gnueabihf-gcc -o key_input_test key_input_test.c 編譯完成后,會生成 key_input_test 可執行文件。 3.運行測試 啟動開發板,將編譯好的 key_input.ko 模塊文件和 key_input_test 應用程序拷貝到/lib/modules/4.1.15 目錄下(檢查開發板根文件系統中有沒有“/lib/modules/4.1.15”這個目錄,如果沒有的話需要自行創建一下。開發板中使用的是光盤資料里面提供的 busybox 文件系統,光盤資料的“i.MX6UL 終結者光盤資料\08_開發板系統鏡像\03_文件系統鏡像\01_Busybox 文件系統”目錄下)。在加載驅動模塊文件之前,先看一下在/dev/input 目錄下都有哪些文件,結果如下圖所示: ![]() 在/dev/input 目錄下已經存在了不少的 event 事件,然后輸入下面命令加載模塊: depmod modprobe key_input 驅動加載成功后在來看一下在/dev/input 目錄下有哪些文件,結果如下圖所示: ![]() 可以看出,多了一個 event3 文件,因此/dev/input/event3 就是我們注冊的驅動所對應的設備文件。然后key_input_test 應用程序通過讀取/dev/input/event3 設備文件來獲取輸入事件信息,測試命令如下: ./key_input_test /dev/input/event3 按下開發板上的按鍵 KEY0,有如下現象: ![]() 可以看出,當我們按下或者釋放開發板上的按鍵以后都會在終端上輸出相應的內容,提示我們哪個按鍵按下或釋放了,在 Linux 內核中 KEY_0 為 11。 另外,我們也可以不用 key_input_test 應用程序 來測試驅動,可以直接使用 hexdump 命令來查看 /dev/input/event3 文件內容,輸入如下命令: hexdump /dev/input/event3 按下開發板上的按鍵 KEY0,有如下現象: ![]() 上圖就是 input_event 類型的原始事件數據值,采用十六進制表示,這些原始數據的含義如下: ![]() type 為事件類型,EV_KEY 事件值為 1,EV_SYN 事件值為 0。因此第 1 行表示 EV_KEY 事件,第 2 行表示 EV_SYN 事件。code 為事件編碼,也就是按鍵號,KEY_0 這個按鍵編號為 11,對應的十六進制為0xb,因此第 1 行表示 KEY_0 這個按鍵事件,最后的 value 就是按鍵值,為 1 表示按下,為 0 的話表示松開。 綜上所述,上圖中的原始事件值含義如下: 第 1 行,按鍵(KEY_0)按下事件。 第 2 行,EV_SYN 同步事件,因為每次上報按鍵事件以后都要同步的上報一個 EV_SYN 事件。 第 3 行,按鍵(KEY_0)松開事件。 第 4 行,EV_SYN 同步事件,和第 2 行一樣。 ![]() |