Linux input子系统分析

Linux input子系统主要分为3层:

  • input_device(设备驱动层)
  • input_handle(核心层,即input_core)
  • 和input_handler(事件处理层)。

所有的input子系统输入设备的主设备号都是13,input_core通过次设备号对输入设备进行分类管理,输入设备总共分为8类,每一类可包含最多32个次设备。

 

input子系统初始化:

1、input_core初始化

                                                                                                                                                                             ---driver/input/input.c

在设备模型/sys/class目录注册设备类,在/proc/bus/input目录产生设备信息,向字符设备驱动框架注册input子系统的接口操作函数(主设备号13和input_fops)。

2、input_handler初始化         

                                                                                                                                              ---driver/input/evdev.c

 

继续展开input_register_handler()接口

 

3、input_device初始化

                                                                                                                      ---driver/input/touchscreen/imx_i2c_ts.c

 

i2c_add_driver驱动接口会自动匹配i2c设备,匹配成功之后调用migor_ts_probe()接口函数。

继续跟踪migor_ts_probe之前先看看input-device的数据结构:

 继续跟踪migor_ts_probe

 继续展开input_register_device

                                                                                                                                                        ---driver/input/input.c

4、input_core关联input_device和input_handler

input_register_handler和input_register_device最后都会调用input_attach_handler接口来匹配输入设备和对应的事件处理者

 继续跟踪evdev_connect:

                                                                                                                                                        ---driver/input/evdev.c

struct evdev evdev_table代表evdev_handler所管理的底层input_device(通过input-handle管理)和应用层已打开该设备的进程、同步的相关结构和消息队列(evdev_client记录)。

 继续跟踪input_register_handle之前展开input_handle结构体

继续跟踪input_register_handle

handle->dev指向input_dev驱动设备,所以就是将handle->d_node放入到input_dev驱动设备的h_list链表中,即input_dev驱动设备的h_list链表就指向handle->d_node, 同样, input_handler驱动处理结构体的h_list也指向了handle->h_node。两者的.h_list都指向了同一个handle结构体,然后通过.h_list 来找到handle的成员.dev和handler,便能找到对方,便建立了连接。

应用open过程

1、应用层调用open接口

2、vfs_open打开设备文件,读取文件的inode内容,得到主设备号13和次设备号

3、chrdev_open字符设备驱动的open根据主设备号得到输入系统的input_fops操作集

4、input_fops->open,即input_open_file()

 

5、继续跟踪input_handler层的evdev_open,至此evdev不仅关联了底层具体的input-device,而且记录了应用层进程打开该设备的信息。之后input-device产生的消息可以传递到evdev的client中的消息队列。便于上层读取。

6、input_device层的input_open_device

触摸消息传递过程

1、 open获得的fd句柄对应的file_operations是evdev_handler的evdev_fops。因此read接口最终会调用到evdev_fops的read接口,即evdev_read。接下来我们来跟踪这个接口的实现过程。我们先看看struct evdev的成员evdev_client的定义,其即是代表打开该输入设备的进程相关的数据结构。

2、evdev_read接口

 

3、假设消息队列为空时,则上层进程将会睡眠,直到被唤醒再进行消息读取。谁来唤醒它呢?

由底层input-device的硬件中断发起,最终将触屏消息送达该消息队列后即会发出唤醒信号。migor_probe中注册的外部硬件中断服务函数即是发起者。

中断函数实现:

ts_dev->work即event_deal:

 

跟踪input_report_abs接口:

input_report_abs()->input_handle_event()->input_pass_event()->handle->handler->event()

继续跟进evdev_event:

evdev->event()->evdev_pass_event()->client_buffer

即会唤醒执行在evdev_read中等待读取消息的进程,继续下面的执行过程,从client的buffer中取出消息,并通过copy_to_user返回给应用程序。

每次触屏消息产生后,在evdev_event中要input_report_abs报告x坐标,y坐标和压力值,最后再通过input-sync接口发出同步事件,向上层应用发出异步通知进行读取。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值