Input subsystem I
来源:互联网 发布:汽车租赁源码 编辑:程序博客网 时间:2024/06/07 02:19
Input subsystem概述
1.1.input子系统概述
The kernel’s input subsystem was created to unify scattered drivers that handle diverse classes of data-input devices such as keyboards, mouse, touch screens, hummer.
Advantages of Input Subsystem.
1. Uniform handling of functionally similar input devices even when they are physically different.Example : Mouse, keyboard,Power keys.
2. An easy event interface for dispatching input reports to user applications. Your driver does not have to create and manage /dev nodes and related access methods Instead we can simply invoke the APIs.
1.2. input子系统结构
输入子系统(Input Subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler)、输入子系统核心层(InputCore)和输入子系统设备驱动层, 如图1-1。
设备驱动层 提供对硬件寄存器的读写访问,将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层提交给事件处理层;
输入设备的驱动部分不在用关心对设备文件的操作,只需关心各硬件寄存器的操作和提交的输入事件。
核心层 对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口;
事件处理层 为用户空间的程序提供统一访问设备的接口(设备节点),以及处理驱动层提交来的事件。
/dev/input目录下显示的是已经注册在内核中的设备编程接口,用户通过open这些设备文件来打开不同的输入设备进行硬件操作。
输入子系统由内核代码drivers/input/input.c构成,它的存在屏蔽了用户到设备驱动的交互细节,为设备驱动层和事件处理层提供了相互通信的统一界面。
参考:EssentialLinuxDeviceDrivers书中Chapter7:Input Drivers
Figure 7.1 illustrates the operation of the input subsystem.
The subsystem contains two classes of drivers that work in tandem: event drivers and device drivers.
Event drivers are responsible for interfacing with applications, whereas device drivers are responsible for low-level communication with input devices.
Because event drivers are standardized and available for all input classes, you are more likely to implement a device driver than an event driver. Your device driver can use a suitable existing event driver via the input core to interface with user applications.
EssentialLinuxDeviceDrivers
2 Input subsystem core 架构分析
2.1 input subsystem 数据结构
input_dev 是硬件驱动层,代表一个input输入设备。
input_handler 是事件处理层,代表一个事件处理器。
input_handle 属于核心层,代表一个配对的input设备与input事件处理器。
struct input_dev { .......... struct input_id id; //标识设备驱动特征 unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//设备所支持的事件 unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//KEY事件支持的编码 unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//REL事件支持的编码 ..... int (*open)(struct input_dev *dev); void (*close)(struct input_dev *dev); int (*flush)(struct input_dev *dev, struct file *file); int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); struct device dev; ....... struct list_head h_list;//handle的链表 struct list_head node;};
struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);//input core事件处理函数 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);//分离出常规事件 bool (*match)(struct input_handler *handler, struct input_dev *dev);//当匹配handler和设备的时候调用 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);//当handler和设备匹配的后调用 void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle);//在connect之后调用start const struct file_operations *fops; int minor; const char *name; const struct input_device_id *id_table; struct list_head h_list;//handle的链表 struct list_head node;};
struct input_handle { void *private; int open;//打开标志 const char *name; struct input_dev *dev; struct input_handler *handler; struct list_head d_node;//input_dev的链表 struct list_head h_node;//handler的链表};
所有的input_dev 用双向链表 input_dev_list 连起来,如图所示1-3:
在调用int input_register_device(struct input_dev *dev) 的时候,会将新的 input_dev 加入到这个链表中。
所有的input_handler 用双向链表 input_handler_list 连起来, 如图所示1-4:
在调用 int input_register_handler(struct input_handler *handler) 的时候,会将新的 input_handler 加入到这个链表中。
每个input_dev 和 input_handler 是要关联上才能工作的,在注册 input_dev 或者 input_handler的时候,就遍历上面的列表,找到相匹配的,然后调用 input_handler 的 connect函数来将它们联系到一起。
通常在input_handler 的 connect函数中,就会创建 input_handle, input_handle就是负责将 input_dev 和 input_handler 联系在一起的,如图1-5所示:
其中: input_dev 中的 h_node 是 input_handle 链表的list节点,也就是说,一个input_dev,可以对应多个 input_handle.
当设备产生 input event 的时候,例如按下了一个键,驱动就会调用 input_handler 中的 event 函数,同时,如果input_dev 支持的话,也会调用 input_dev 的 event 函数。
这样,设备产生的事件就会被驱动记录下来。当用户层的程序需要获知这些事件的时候,会调用 input_handler中的 struct file_operations *fops 中的相应函数,例如 read 等等。
参考:
The Linux USB Input Subsystem: Part I
Part II
input子系统全面分析
input子系统分析
- Input subsystem I
- The Linux USB Input Subsystem, Part I
- The Linux USB Input Subsystem, Part I
- The Linux USB Input Subsystem, Part I
- input subsystem
- input subsystem
- Using the Input Subsystem
- input subsystem 笔记1
- input subsystem 笔记2
- input subsystem 函数解释
- Linux Input Subsystem
- Android Input Subsystem
- linux input subsystem 架构分析
- The Linux USB Input Subsystem
- linux input subsystem 架构分析
- Linux输入子系统(Input Subsystem)
- Linux输入子系统(Input Subsystem)
- Linux输入子系统(Input Subsystem)
- 在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务(老罗学习笔记5)
- form表单的两种提交方式,submit和button的用法
- json解析的四种方法
- UVA - 1471 Defense Lines 贪心+二分
- 字节流与字符流区别
- Input subsystem I
- android调节屏幕亮度
- 练习一
- ELCImagePicker 学习总结(八)
- Gradle error: expecting anything but ”\n”; got it anyway
- libevent--事件管理、缓存管理
- 如果根据窗口句柄 或者CWnd指针获取窗口类名
- UI 数字输入控件UIStepper
- java.text.ParseException: Unparseable date: "Mon Mar 30 00:00:00 CST 2015"