6.9 Linux 驱动开发 input子系统

一、注册 input_dev

// input_dev 结构体
struct input_dev {
    const char *name;
    const char *phys;
    const char *uniq;
    struct input_id id;

    unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];

    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)]; /*LED 相关的位图 */
    unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];/* sound 有关的位图 */
    unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; /* 压力反馈的位图 */
    unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; /*开关状态的位图 */
    ......
    bool devres_managed;
};

//evbit 表示输入事件类型,可选的事件类型如下:
#define EV_SYN 0x00 /* 同步事件 */
#define EV_KEY 0x01 /* 按键事件 */
#define EV_REL 0x02 /* 相对坐标事件 */
#define EV_ABS 0x03 /* 绝对坐标事件 */
#define EV_MSC 0x04 /* 杂项(其他)事件 */
#define EV_SW 0x05 /* 开关事件 */
#define EV_LED 0x11 /* LED */
#define EV_SND 0x12 /* sound(声音) */
#define EV_REP 0x14 /* 重复事件 */
#define EV_FF 0x15 /* 压力事件 */
#define EV_PWR 0x16 /* 电源事件 */
#define EV_FF_STATUS 0x17 /* 压力状态事件 */

//keybit 就是按键事件使用的位图
#define KEY_RESERVED 0
#define KEY_ESC 1
#define KEY_1 2
#define KEY_2 3
#define KEY_3 4
#define KEY_4 5
#define KEY_5 6
#define KEY_6 7
#define KEY_7 8
#define KEY_8 9
#define KEY_9 10
#define KEY_0 11

申请 input_dev:在编写 input 设备驱动的时候我们需要先申请一个 input_dev 结构体变量,使用 input_allocate_device 函数来申请一个 input_dev,此函数原型如下所示:

struct input_dev *input_allocate_device(void)
函数参数和返回值含义如下:
	参数:无。
	返回值:申请到的 input_dev。

释放 input_dev:如果要注销的 input 设备的话需要使用 input_free_device 函数来释放掉前面申请到的 input_dev,input_free_device 函数原型如下:

void input_free_device(struct input_dev *dev)
函数参数和返回值含义如下:
	dev:需要释放的 input_dev。
	返回值:无。

注册 input_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_dev:注销使用 input_unregister_device 函数来注销掉前面注册的 input_dev,input_unregister_device 函数原型如下:

void input_unregister_device(struct input_dev *dev)
函数参数和返回值含义如下:
	dev:要注销的 input_dev 。
	返回值:无。

input_dev 注册过程如下:

①、使用 input_allocate_device 函数申请一个 input_dev。

②、初始化 input_dev 的事件类型以及事件值。使用 input_register_device 函数向 Linux 系统注册前面初始化好的 input_dev。

③、卸载input驱动的时候需要先使用input_unregister_device 函数注销掉注册的input_dev,然后使用 input_free_device 函数释放掉前面申请的 input_dev。

//input_dev 注册流程
struct input_dev *inputdev; /* input 结构体变量 */

/* 驱动入口函数 */
static int __init dev_init(void)
{
    ......
    inputdev = input_allocate_device(); /* 申请 input_dev */
    inputdev->name = "test_inputdev"; /* 设置 input_dev 名字 */

    /*********第一种设置事件和事件值的方法***********/
    __set_bit(EV_KEY, inputdev->evbit); /* 设置产生按键事件 */
    __set_bit(EV_REP, inputdev->evbit); /* 重复事件 */
    __set_bit(KEY_0, inputdev->keybit); /*设置产生哪些按键值 */
    /************************************************/

    /*********第二种设置事件和事件值的方法***********/
    keyinputdev.inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
    keyinputdev.inputdev->keybit[BIT_WORD(KEY_0)] |= BIT_MASK(

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++/嵌入式开发 秋招面经 文章被收录于专栏

一名985硕,在25年秋招中斩获多个C++/嵌入式开发Offer。本专栏将分享我的面经,涵盖C/C++、操作系统、计算机网络、ARM体系与架构、Linux应用/驱动开发、Qt、通信协议及开发工具链等核心内容。

全部评论

相关推荐

不愿透露姓名的神秘牛友
03-30 21:35
爱蜜莉雅碳劝退测开:裁员裁大动脉了
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务