前言
上一节有展示Android Input子系统的架构图,这里我们关心Linux kernel层
可以看到kernel层分为三层:
输入子系统设备驱动:处理与硬件相关的信息,调用input API注册输入设备,并把数据往上报
输入子系统核心层:为事件处理层和设备驱动层提供API接口调用
输入子系统事件处理:通过核心层的API获取输入事件上报的数据,定义input API与应用层交互
数据结构
数据结构 | 代码位置 | 描述 |
---|---|---|
struct input_dev |
input.h | input设备驱动中的实例 |
struct evdev struct mousedev struct keybdev |
evdev.c mousedev.c keybdev.c |
Event Handler层逻辑input设备的数据结构 |
struct input_handler |
input.h | Event Handler的结构,handler层实例化对象 |
struct input_handle |
input.h | 用于创建驱动层input_dev和handler链表 |
1 | //kernel/include/linux/input.h |
对于handler和device,分别用链表input_handler_list
和input_device_list
进行维护,这两条是全局链表
input_handle
结构体代表一个成功配对的input_dev
和input_handler
。input_handle
没有一个全局的链表,它注册的时候将自己分别挂在input_device_list
和input_handler_list
的h_list
上;同时,input_handle
的成员.dev,关联到input_dev
结构,.handler关联到input_handler
结构。
输入子系统流程
子系统入口函数:
subsys_initcall(input_init);
-
class_register(&input_class)
:在/sys/class下创建input类 -
input_proc_init()
:在/proc下建立相关文件 -
register_chrdev_region(MKDEV(INPUT_MAJOR, 0), INPUT_MAX_CHAR_DEVICES, "input")
:申请字符设备主设备号为13
-
注册input设备
- 添加设备
- 把输入设备挂到输入设备链表
input_dev_list
中 - 遍历
input_handler_list
链表,查找并匹配输入设备对应的时间处理层,如果匹配上,就调用handler
的connect
函数进行连接。
事件处理入口函数:
module_init(evdev_init);
->input_register_handler
- 把设备处理器挂到全局的input子系统设备链表
input_handler_list
上 - 遍历input_dev_list,与每一个input_dev进行匹配:
input_attach_handler
input_attach_handler
-
input_match_device
-
handler->connect
- 申请此设备号:
input_get_new_monor
- 设置设备节点名称/dev/eventX
- 设置应用层使用的设备号
input_dev
设备驱动和handler事件处理层的关联:input_register_handler
- 将设备加入到Linux设备模型:
device_add
-
- 把设备处理器挂到全局的input子系统设备链表
上报事件
input_report_xx()
input_event()
input_sync
input_event()
举例一个简单的input设备驱动:
https://landlock.io/linux-doc/landlock-v7/input/input-programming.html