input子系统整体框架

本文详细介绍了Linux内核中的input子系统,包括模块结构、关键结构体和函数接口、设备注册过程以及数据传输流程。input子系统由驱动层、核心层和事件处理层组成,通过input_dev、input_handler和input_handle三个关键结构体连接设备和处理层。驱动层负责读取原始数据,核心层提供接口,事件处理层负责上报事件。数据传输过程中,驱动通过input_event上报数据,事件经过处理层传递到用户空间。此外,文章还探讨了自定义handler处理层的匹配规则和Android层的实现。
摘要由CSDN通过智能技术生成

2.模块结构

下图是input输入子系统框架,输入子系统linux由输入子系统核心层( Core层 ),驱动层和事件处理层(Event Handler)三部份组成。Android层操作input子系统由Native层、Java框架层、应用程序三部分组成。

1: input输入子系统层次图

    一个输入事件,如手指触摸,键盘按键按下,横竖屏转动等等通过 input driver -> Input core -> Event handler -> userspace 到达用户空间传给应用程序

    驱动层负责读取原始数据,如触摸屏的驱动,g_sensor的驱动等。

    输入子系统核心层(input core),其对下提供了设备驱动的接口,对上提供了事件处理层的编程接口。

    事件处理层(event handler)负责将事件上报,将键值、坐标等数据上报的对应的设备节点。

3.关键的结构体和函数接口介绍

3.1.关键结构体(共三个)

struct input_dev {

const char *name;

const char *phys;

const char *uniq;

struct input_id id;

unsigned long evbit[BITS_TO_LONGS(EV_CNT)];

unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];

unsigned long relbit[BITS_TO_LONGS(REL_CNT)];

unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];

unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];

unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];

unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];

unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];

unsigned long swbit[BITS_TO_LONGS(SW_CNT)];

struct list_head h_list;

struct list_head node;

};

关于input_dev结构体,一个input_dev结构体对象代表着一个输入设备,以上只列出部分的成员,其中的name表示设备的名字,evbit表示设备支持的事件类型,设备驱动程序需要设置这些值。

struct input_handler {

void *private;

void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);

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 file_operations *fops;

int minor;

const char *name;

const struct input_device_id *id_table;

struct list_head h_list;

struct list_head node;

};

input_handler为子系统的处理层。一旦devhandler匹配上了就会调用connect函数。其中这里有一个很关键的地方,就是struct input_device_id *id_table;这里是匹配规则,只要dev注册时满足id_table的条件就会匹配上

struct input_handle {

void *private;

int open;

const char *name;

struct input_dev *dev;

struct input_handler *handler;

struct list_head d_node;

struct list_head h_node;

};

input_handle可以说就是中间层,专门负责联系devhandler

3.2.分析三个结构体之间的关系

1)、在内核中,input_dev 表示一个 input设备;input_handler 表示input设备的 interface。所有的input_dev用双向链表input_dev_list 连起来。在调用 input_register_device(struct input_dev *dev) 的时候,会将新的 input_dev 加入到这个链表中。

2)、所有的input_handler用双向链表 input_handler_list 连起来。在调用 input_register_handler(struct input_handler *handler) 的时候,会将新的 input_handler 加入到这个链表中。

3)、每 个input_dev 和 input_handler 是要关联上才能工作的,在注册 input_dev 或者 input_handler的时候,就遍历上面的列表,找到相匹配的,然后调用 input_handler 的 connect函数来将它们联系到一起。

4)、通常在input_handler 的 connect函数中,就会创建 input_handle, input_handle就是负责将 input_dev input_handler 联系在一起的.

3.3.函数接口

1input_register_handler(struct input_handler *handler)注册一个新的handler处理层。例如linux里面自带的evdev.c就是一个handler处理层代码。

2input_register_handle(struct input_handle *handle)注册一个中间层handle,用于关联devhandler。一般在devhandler匹配后connection函数里面注册。

3input_register_device(struct input_dev *dev)注册一个设备,这个就是设备驱动程序需要调用的接口。用于向input子系统注册一个input设备。

4input_match_device(struct input_handler *handler,struct input_dev *dev)匹配函数,每当注册一个设备或者一个handler处理层,都会调用该接口进行devhandler的匹配。

5input_open_device(struct input_handle *handle)打开设备。

6input_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)事件上报接口,主要是调用handler层的event函数进行上报,将上报的工作交给handler处理层。

4.注册驱动到Input子系统和数据的传递过程

4.1. 驱动层部分

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值