Linux输入子系统框架分析及输入设备驱动编程

1. Linux输入子系统框架

linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件驱动程序层(EventHandler)、输入子系统核心层(InputCore)和输入子系统设备驱动程序层。它们各自的功能如下:

  1. 对于输入子系统设备驱动程序层而言,主要实现对硬件设备的读写访问,中断设置,并把硬件产生的事件转换为核心层定义的规范提交给事件处理层。

  2. 对于核心层而言,为设备驱动层提供了规范和接口。设备驱动层只要关心如何驱动硬件并获得硬件数据(例如按下的按键数据),然后调用核心层提供的接口,核心层会自动把数据提交给事件处理层。

  3. 对于输入子系统事件驱动程序层而言,则是用户编程的接口(设备节点),并处理驱动层提交的数据处理。

Linux输入子系统的框架如下:

Linux输入子系统框架分析及输入设备驱动编程_第1张图片

  • /dev/input目录下显示的是已经注册在内核中的设备编程接口,用户通过open这些设备文件来打开不同的输入设备进行硬件操作。

  • 事件处理层为不同硬件类型提供了用户访问及处理接口。例如当我们打开设备/dev/input/mice时,会调用到事件处理层的Mouse Handler来处理输入事件,这也使得设备驱动层无需关心设备文件的操作,因为Mouse Handler已经有了对应事件处理的方法。

  • 输入子系统由内核代码drivers/input/input.c构成,它的存在屏蔽了用户到设备驱动的交互细节,为设备驱动层和事件处理层提供了相互通信的统一界面。

2. Linux输入设备驱动编程

编写符合输入子系统框架的设备驱动程序主要有以下四个步骤:

1.分配一个input_dev结构体,调用input_allocate_device()或者devm_input_allocate_device(struct input_dev*)实现;

2.设置input设备支持的事件类型,其支持的事件类型如下表;

                        Linux输入子系统支持的事件类型
EV_SYN     0x00    同步事件
EV_KEY     0x01    按键事件
EV_REL     0x02    相对坐标(如:鼠标移动,报告相对最后一次位置的偏移)
EV_ABS     0x03    绝对坐标(如:触摸屏或操作杆,报告绝对的坐标位置)
EV_MSC     0x04    其它
EV_SW      0x05    开关
EV_LED     0x11    按键/设备灯
EV_SND     0x12    声音/警报
EV_REP     0x14    重复
EV_FF      0x15    力反馈
EV_PWR    0x16    电源
EV_FF_STATUS    0x17   力反馈状态
EV_MAX    0x1f    事件类型最大个数和提供位掩码支持

3.将输入设备注册到输入子系统中,调用input_register_device(struct input_dev*)函数实现;

4.硬件相关的代码:注册中断处理函数,比如键盘设备需要编写按键的抬起、放下,触摸屏设备需要编写按下、抬起、绝对移动,鼠标设备需要编写单击、抬起、相对移动,并且需要在必要的时候提交硬件数据(键值/坐标/状态等等),即上报输入事件。

Linux输入子系统提供了设备驱动层上报输入事件的函数,在include/linux/input.h中:

void input_event(struct input_dev* dev, unsigned int type, unsigned int code, int value); //上报指定的type、code的输入事件

void input_report_key(struct input_dev *dev, unsigned int code, int value);      //上报按键事件

void input_report_rel(struct input_dev *dev, unsigned int code, int value);       //上报相对坐标事件

void input_report_abs(struct input_dev *dev, unsigned int code, int value);              //上报绝对坐标事件

当提交输入设备产生的输入事件之后,需要调用下面的函数来通知输入子系统,以处理设备产生的完整事件:

void input_sync(struct input_dev *dev);

你可能感兴趣的:(linux驱动)