概述
内核的输入子系统是对分散的,多种不同类别的输入设备(如键盘,鼠标,跟踪球,操纵杆,触摸屏,加速计和手写板)等字符设备进行统一处理的抽象模型
框架模型
LINUX 的 input子系统分为三层结构,如下:
分别为:event handler ,input core ,input drvier.
设备驱动层(input drvier)
和硬件相关,直接捕捉和获取硬件设备的数据信息等(包括触摸屏被按下、按下位置、鼠标移动、键盘按下等等),然后将数据信息报告到核心层,提供对硬件各寄存器的读写访问和将底层硬件对用户输入访问的响应转换为标准的输入事件。
核心层
对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口。
事件处理层
为我们用户空间的应用程序提供了统一访问设备的接口和驱动层提交来的事件处理
关键数据对象
Input_dev: 代表着具体的输入设备,它直接从硬件中读取数据,并以事件的形式转发
Input_Handler: 代表接收某一类事件的上层接口,对应于一类事件设备文件
Input_Handle : 用于将input_device 和 handler 连接起来的胶水,对应于某1个具体的设备文件。
Client: 对应于用户程序对文件的访问接口,每open一次事件驱动,就创建一个client.
两条重要的链表
static LIST_HEAD(input_dev_list);
记录着系统中所有的输入设备
static LIST_HEAD(input_handler_list);
记录着所有的事件驱动
关键数据结构
struct input_handle {
...
struct input_dev *dev;
struct input_handler *handler;
struct list_head d_node;//链入input_dev的h_list代表的链表
struct list_head h_node;//链入input_handler的h_list代表的链表
};
struct input_dev {
...//detailed info of this device
struct list_head h_list;//这是与input_dev相关联的input_handle的链表的表头
struct list_head node;//链入全局链表 input_dev_list
};
struct input_handler {
...
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);//important
bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*match)(struct input_handler *handler, struct input_dev *dev);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
...
const struct input_device_id *id_table;
struct list_head h_list;//这是与input_handler相关联的input_handle的链表的表头
struct list_head node;//链入全局链表 input_handler_list
};