以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
转载博客:input输入子系统 - 涛少& - 博客园
前言
Linux系统支持的输入设备繁多,例如键盘、鼠标、触摸屏、手柄等等,Linux系统是如何管理如此之多的不同类型、不同原理、不同的输入信息的输入设备的呢?其实就是通过input输入子系统这套软件体系来完成的。
1、input子系统的层次结构
如上图所示,input子系统分为3层:具体硬件驱动层,框架核心层,输入事件驱动层。图中Drivers对应的是具体硬件驱动层,表示各种各样不同的输入设备;Input Core对应的就是框架核心层;Handlers对应的就是输入事件驱动层;最右边的代表的是应用层。
(1)从图中可知,系统可以注册多个输入设备,例如一台电脑上可以带有鼠标,键盘等。
(2)输入事件驱动层的各个handler(Keyboard/Mouse/Joystick/Event)属于平行关系,不同handler所对应的输入设备在应用层中的接口命名方式不一样。例如,Mouse下的输入设备在应用层的接口是 /dev/input/mouse*,Joystick的是 /dev/input/js*,Event的是 /dev/input/event*。
(3)框架核心层负责协调输入事件驱动层和硬件驱动层,使得它们之间能够完成数据传递。当硬件驱动层发生输入事件的时候,整个系统就被激活了,事件就会通过框架核心层传递到输入事件驱动层中对应的一个或者多个handler中,最终会传递到应用空间。
2、input子系统的实质
对比之前学过的驱动框架,input子系统其实就是输入设备的驱动框架。
与之前的学过的驱动框架不同的是,input输入子系统分为上中下3层,所以其复杂度高于之前讲的led、misc、fb等设备的驱动框架。
3、input子系统解决的问题
在GUI界面中,用户的自由度很大,比如可以响应不同类别的输入设备,而且还能够针对不同的输入做出不同的动作。例如window中的一个软件既可以响应鼠标输入事件,也可以响应键盘输入事件,而且这些事件都是预先不知道的。
input子系统解决了(不同类别的输入设备的)输入事件与应用层之间的数据传输问题,使得应用层能够获取到各种(不同类别的输入设备的)输入事件。换言之,input子系统能够囊括所有的不同类别的输入设备,让应用层感知到所有发生的输入事件。简言之,input子系统屏蔽了输入类设备的差异性,解决了应用层和驱动层的信息交流问题。
4、input子系统如何管理输入事件
input子系统使用struct input_event结构体来统一管理输入事件。
该结构体定义在x210_kernel\include\linux\input.h文件中,内容如下:
struct input_event {struct timeval time;//事件发生的时间点__u16 type;//事件发生的由来类型(键盘?触摸屏?)__u16 code;//事件的编码(按键a对应的编码)__s32 value;//操作值(比如是按下了还是弹起了;触摸点坐标等) };
5、举例说明input子系统工作过程
以点击鼠标为例,说明input子系统的工作过程。
当我们按下鼠标左键的时候会触发中断(中断是早就注册好的),就会去执行中断所绑定的处理函数,在函数中就会去读取硬件寄存器来判断按下的是哪个按键和状态 。然后按键信息上报给input core层,input core层处理好了之后就会上报给input event层,在input event层把输入事件封装成一个input_event结构体放入一个缓冲区中,应用层的read就会将缓冲区中的数据读取出去。