0、Input 子系统介绍
Linux内核为了更好的统一的管理输入型设备:键盘、鼠标、触摸屏、摇杆等,建立起来的一套内核框架,分为四个部分:应用层、input event 、input core、硬件驱动。
代码结构:
input event: /kernel/drivers/input/evdev.c (通用模型)
/kernel/drivers/input/mousedev.c
/kernel/drivers/input/joydev.c
input core: /kernel/drivers/input/input*.c
硬件驱动: /kernel/drivers/input/目录下的文件夹(各种类型的input设备)
硬件驱动: 将底层的硬件输入转化为统一事件形式,向输入核心(input core)汇报
Input core:承上启下,为驱动层提供 输入设备注册:input_register_device;为input event层 提供 handler注册接口:input_register_handler;通知事件处理层对事件进行处理,在/proc目录下产生相应的设备信息
Input event: 主要是和用户空间交互。(linux中在用户空间将所有的设备都当作文件来处理,所以在一般的驱动程序中都有提供fops接口,以及在/dev下会生成相应的设备文件node,这些操作在输入子系统中由处理层完成)
Input 子系统解决了什么问题?
1、在GUI界面中,用户的自由度十分大,可以做的事情非常多,Input子系统可以响应不同的输入类设备,而且还能够对不同的输入类设备的输入做出不同的动作。
2、Input子系统还解决了不同的输入类设备的输入事件与应用层之间的数据传输,使得应用层能够获取到不同的输入设备的输入事件,input输入子系统能够包括所有不同种类的输入设备,在应用层能够感知到所有发生的输入事件。
Input子系统的工作流程:
以一次触摸屏触摸事件作为例子来说明input子系统的工作过程:
当我们在触摸屏上按下的时候,就会触发中断(中断是早就注册好的),之后就会去执行这个中断所绑定的中断处理函数,在函数中就会去读取硬件寄存器来判断触摸的区域和状态--------> 将触摸区域信息上报给input core层 ---------->Input core层处理好了之后就会上报给input event层,在这里就会将我们的输入事件封装成一个input event结构体放入一个缓冲区 ------> 应用层read将会将缓冲区中的数据读取出来,获取输入事件的信息。
综上,我们可以发现,input子系统被划分成三个层次是很有必要的,其中input core层的存在主要是将驱动层上报的输入事件整合成标准模型上报给 input event层,而input event层和驱动层都属于并行层以实现对不同种类的输入设备的支持。
1、Input core层代码分析
static int __init input_init(void) //subsys_initcall(input_init); 模块入口
err = class_register(&input_class); //创建设备类 /sys/class/input
err = input_proc_init(); //proc文件系统相关的初始化
proc_bus_input_dir = proc_mkdir("bus/input", NULL); //在/proc/bus目录下创建input目录
entry = proc_create("devices", 0, proc_bus_input_dir,//在proc/bus/input目录下创建devices文件(有对应的fileops操作)
entry = proc_create("handlers", 0, proc_bus_input_dir//在proc/bus/input目录下创建handlers文件(有对应的fileops操作)
err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0) //注册input字符设备,主设备号为13,次设备号未分配 fileops需要手动调用cdev_init添加
总结:input_init首先完成了input设备类的创建,而后完成了对proc文件系统的支持,最后调用register_chrdev_region向内核注册了主设备号为13的input字符设备类型驱动。(疑问:这里并没有调用cdev init添加fileops)
input core层提供给设备驱动层的接口函数主要有以下三个:
input_allocate_device //分配一块input_dev结构体类型大小的内存
input_set_capability //设置输入设备可以上报哪些输入事件
input_register_device //向input