输入设备总类繁杂,包括按键,键盘,触摸屏,鼠标,摇杆等等,它们本身都是字符设备,不过内核为了能将这些设备的共性抽象出来,简化驱动的开发,建立了一个 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 行一样。
![]()
|