前言
最近在学习input子系统驱动的编写的时候,用imx6ull开发板上的按键作为输入设备进行注册。实现过程中没什么问题,但是在面试的时候被问到了input_event函数实现的底层原理,所以总结了一下,作为笔记,供大家参考吧。一、如何使用input子系统?
在使用 input 子系统的时候我们只需要注册一个 input 设备即可, input_dev 结构体表示 input设备,此结构体定义在 include/linux/input.h 文件中
步骤大致分为以下几步:
在编写 input 设备驱动的时候我们需要先申请一个 input_dev 结构体变量,使用input_allocate_device 函数来申请一个 input_dev,此函数原型如下所示:
struct input_dev *input_allocate_device(void)
如果要注销的 input 设备的话需要使用 input_free_device 函数来释放掉前面申请到的
input_dev,input_free_device 函数原型如下:
void input_free_device(struct input_dev *dev)
申请好一个 input_dev 以后就需要初始化这个 input_dev,需要初始化的内容主要为事件类型(evbit)和事件值(keybit)这两种。input_dev 初始化完成以后就需要向 Linux 内核注册 input_dev了,需要用到 input_register_device 函数,此函数原型如下:
int input_register_device(struct input_dev *dev)
函数参数和返回值含义如下:
dev:要注册的 input_dev 。
返回值:0,input_dev 注册成功;负值,input_dev 注册失败。
同样的,注销 input 驱动的时候也需要使用 input_unregister_device 函数来注销掉前面注册的 input_dev,input_unregister_device 函数原型如下:
void input_unregister_device(struct input_dev *dev)
函数参数和返回值含义如下:
dev:要注销的 input_dev 。
返回值:无。
综上所述,input_dev 注册过程如下:
1. 使用 input_allocate_device 函数申请一个 input_dev。
2. 初始化 input_dev 的事件类型以及事件值。
3. 使用 input_register_device 函数向 Linux 系统注册前面初始化好的 input_dev。
4. 卸载input驱动的时候需要先使用input_unregister_device函数注销掉注册的input_dev,然后使用 input_free_device 函数释放掉前面申请的 input_dev。
回归正题:input_event函数
当我们向 Linux 内核注册好 input_dev 以后还不能高枕无忧的使用 input 设备, input 设备都是具有输入功能的,但是具体是什么样的输入值 Linux 内核是不知道的,我们需要获取到具体的输入值,或者说是输入事件,然后将输入事件上报给 Linux 内核。比如按键,我们需要在按键中断处理函数,或者消抖定时器中断函数中将按键值上报给 Linux 内核,这样 Linux 内核才能获取到正确的输入值。不同的事件,其上报事件的 API 函数不同,我们依次来看一下一些常用的事件上报 API 函数。
同样的还有一些其他的事件上报函数,拿按键的上报函数举例:
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{
input_eve