我是靠谱客的博主 会撒娇铃铛,这篇文章主要介绍输入子系统,现在分享给大家,希望可以做个参考。

文章目录

          • input子系统简介
          • input_dev 结构体:
          • 输入设备的注册与注销:
          • 输入设备的事件报告
          • 键盘驱动示例:

input子系统简介

就我们生活中的输入设备无非就是键盘、鼠标、触摸屏等。
输入子系统将输入设备分为三种类型,分别是键盘设备、鼠标设备和操作杆设备。
他们之间最主要的区别在于他们输入的数据类型不同。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于注册上述不同设备类型,只要符合要求的类型即可

input_dev 结构体:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
Struct input_dev{ const char* name;//设备名称 const char* phys;//设备文件路径 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 int repeat_key;//存储最后一次设备输入的键值 int rep[REP_CNT];//自动重复参数的当前值 }
输入设备的注册与注销:
复制代码
1
2
3
4
5
6
7
8
9
*1分配input_dev结构体 struct input_dev *input_allocate_device(void) *2将结构体input_dev结构体注册到内核,之前应该初始化好结构体里的变量和内容 Int input_register_device(struct input_dev *dev) *3将设备结构体input_dev结构体注销 void input_unregister_device(struct input_dev *dev) *4 与分配结构体相对应,释放input_dev结构体 void input_free_device(struct input_dev *dev)
输入设备的事件报告

例如按下按键,会触发中断,此时cpu执行中断服务函数。但是内核不知道此时按键的值,所以在中断服务函数里面需要添加事件报告,目的很纯粹就是想将键位码转换为linux内核可以认识的键盘编码。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*向内核上报一个键盘事件 void input_report_key(struct input_dev *dev,//当前输入设备 unsigned int code,//键值编码 Int value)//用0或者1表示按下或者释放的状态 *向内核上报一个REL事件 void input_report_rel(struct input_dev *dev,//当前输入设备 unsigned int code,//事件码 Int value)//事件的值 *向内核上报一个ABS事件 void input_report_abs(struct input_dev *dev,//当前输入设备 unsigned int code,//事件码 Int value)//事件值 *完成了事件的上报,还需要调用一个函数来实现内核的同步 void input_sync(struct input_dev *dev)//将事件同步到内核中
键盘驱动示例:
  • *0修改设备树,新增设备树节点
    在这里插入图片描述
  • *1注册输入设备(使用platform驱动模型)
    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    static int mykeypad_probe(struct platform_device *pdev) { mykeypad_dev=input_allocate_device(); //向内核申请 input_dev 结构体 对input_dev结构体一系列初始化(内部的变量设置等) ret = input_register_device(mykeypad_dev); //注册input_dev 利用platform_get_resource()+ioremap()函数得到寄存器地址从而进行寄存器配置 ret = devm_request_irq(&pdev->dev, //中断号申请 platform_get_irq(pdev, 0),//绑定的设备 mykeypad_irq,//中断服务函数 0,//触发方式 "mykey",//中断名 (void*)&key_value);//设备ID }
  • *2实现中断服务函数
    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    static irqreturn_t mykeypad_irq (int irq, void *dev_id)//实现事件的报告 { ssize_t key_value; if(((*keyadc_ints)&(1<<1)) != 0) {/*上报事件*/ key_value = ((*keyadc_data)&(0x3f)); if(key_value == 24) { input_event(mykeypad_dev,EV_KEY,KEY_A,1); //上报EV_KEY类型,button按键,1(下) } else if(key_value == 17) { input_event(mykeypad_dev,EV_KEY,KEY_B,1);//上报EV_KEY类型,button按键,1(按下) } 。。。。。 } input_sync(mykeypad_dev); // 上传同步事件,告诉系统有事件出现 return IRQ_HANDLED; }
  • *3输入设备注销((使用platform驱动模型))
    复制代码
    1
    2
    3
    4
    5
    6
    7
    static int mykeypad_remove(struct platform_device *pdev){ iounmap(keyadc_xxx);//取消LRADC_xxx一些列映射 。。。。 input_unregister_device(mykeypad_dev); //卸载类下的驱动设备 input_free_device(mykeypad_dev); //释放驱动结构体 }
  • *4 注册paltform_driver驱动
    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    static struct of_device_id mykeypad_match_table[]={//匹配compatible属性 {.compatible = "mykeypad",}, }; static struct platform_device_id mykeypad_device_ids[] = {//一个驱动匹配多少设备 {.name = "mykeypad",}, }; static struct platform_driver mykeypad_driver= { .probe = mykeypad_probe, .remove = mykeypad_remove, .driver={ .name = "mykeypad", .of_match_table = mykeypad_match_table, }, .id_table = mykeypad_device_ids, }module_platform_driver(mykeypad_driver);取代odule_init()module_exit()出入口
  • *5编译成.ko调试
    直接insmod挂载 在/sys/device/virtual/input下产生一个input0设备

最后

以上就是会撒娇铃铛最近收集整理的关于输入子系统的全部内容,更多相关输入子系统内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部