内核版本:3.9.5

1. input_dev,用来标识输入设备

  1. struct input_dev {
  2. const char *name;
  3. const char *phys;
  4. const char *uniq;
  5. struct input_id id;//与input_handler匹配用的id
  6.  
  7. unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
  8.  
  9. unsigned long evbit[BITS_TO_LONGS(EV_CNT)];//支持所有的事件类型
  10. unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//支持按键事件
  11. unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//支持相对位移事件
  12. unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];//支持绝对位移事件
  13. unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//支持其它事件
  14. unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//支持led事件
  15. unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//支持声音事件
  16. unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//支持受力事件
  17. unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//支持开关机时间
  18.  
  19. unsigned int hint_events_per_packet;
  20.  
  21. unsigned int keycodemax;
  22. unsigned int keycodesize;
  23. void *keycode;
  24.  
  25. int (*setkeycode)(struct input_dev *dev,
  26. const struct input_keymap_entry *ke,
  27. unsigned int *old_keycode);
  28. int (*getkeycode)(struct input_dev *dev,
  29. struct input_keymap_entry *ke);
  30.  
  31. struct ff_device *ff;
  32.  
  33. unsigned int repeat_key;//最近一次的按键值
  34. struct timer_list timer;
  35.  
  36. int rep[REP_CNT];
  37.  
  38. struct input_mt *mt;
  39.  
  40. struct input_absinfo *absinfo;
  41.  
  42. unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反应设备当前的按键状态
  43. unsigned long led[BITS_TO_LONGS(LED_CNT)];//反应设备当前的led状态
  44. unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反应设备当前的声音输入状态
  45. unsigned long sw[BITS_TO_LONGS(SW_CNT)];//反应设备当前的开关状态
  46.  
  47. int (*open)(struct input_dev *dev);//第一次打开设备时调用,初始化设备用
  48. void (*close)(struct input_dev *dev);//最后一个应用程序释放设备时用,关闭设备
  49. int (*flush)(struct input_dev *dev, struct file *file);/*用于处理传递给设备的事件,如LED事件和声音事件*/
  50. int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
  51.  
  52. struct input_handle __rcu *grab;//当前占有该设备的input_handle
  53.  
  54. spinlock_t event_lock;
  55. struct mutex mutex;
  56.  
  57. unsigned int users;//打开该设备的用户数量(input handlers)
  58. bool going_away;
  59.  
  60. struct device dev;
  61.  
  62. struct list_head h_list;//该链表头用于链接此input_dev所关联的input_handle
  63. struct list_head node;//用于将此input_dev链接到input_dev_list
  64.  
  65. unsigned int num_vals;
  66. unsigned int max_vals;
  67. struct input_value *vals;
  68.  
  69. bool devres_managed;
  70. };

2.input_handler,用来标识输入事件处理

  1. struct input_handler {
  2.  
  3. void *private;
  4.  
  5. void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);/*event用于处理事件*/
  6. void (*events)(struct input_handle *handle,
  7. const struct input_value *vals, unsigned int count);
  8. bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
  9. bool (*match)(struct input_handler *handler, struct input_dev *dev);
  10. int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);/*connect用于建立handler和device的联系*/
  11. void (*disconnect)(struct input_handle *handle);/*disconnect用于解除handler和device的联系*/
  12. void (*start)(struct input_handle *handle);
  13.  
  14. bool legacy_minors;
  15. int minor;//次设备号
  16. const char *name;
  17.  
  18. const struct input_device_id *id_table;//用于和input_dev匹配
  19.  
  20. struct list_head h_list;//用于链接和此input_handler相关的input_handle
  21. struct list_head node;//用于将该input_handler链入input_handler_list
  22. };

3.input_handle,用来链接input_dev和input_handler的桥梁

  1. struct input_handle {
  2.  
  3. void *private;
  4.  
  5. int open;//记录设备的打开次数(有多少个应用程序访问设备)
  6. const char *name;
  7.  
  8. struct input_dev *dev;//指向所属的device
  9. struct input_handler *handler;//指向所属的handler
  10.  
  11. struct list_head d_node;//用于将此input_handle链入所属input_dev的h_list链表
  12. struct list_head h_node;//用于将此input_handle链入所属input_handler的h_list链表
  13. };

可以看到,input_device和input_handler中都有一个h_list,而input_handle拥有指向input_dev和input_handler的指针,也就是说input_handle是用来关联input_dev和input_handler的,那么为什么一个input_device和input_handler

中拥有的是h_list而不是一个handle呢?因为一个device可能对应多个handler,而一个handler也不能只处理一个device,比如说一个鼠标,它可以对应even handler,也可以对应mouse handler,因此当其注册时与系统中的handler进行匹配,就有可能产生两个实例,一个是evdev,另一个是mousedev,而任何一个实例中都只有一个handle.至于以何种方式来传递事件,就由用户程序打开哪个实例来决定.后面一个情况很容易理解,一个事件驱动不能只为一个甚至一种设备服务,系统中可能有多种设备都能使用这类handler,比如event handler就可以匹配所有的设备.在input子系统中,有8种事件驱动,每种事件驱动最多可以对应32个设备,因此dev实例总数最多可以达到256个.

这三个数据结构的关系看起来有点乱!那么就用图表示出来,看起来应该会明了很多吧!三者的关系如下所示:

可以看出input_handle是连接input_device和input_handler的桥梁,如图中的箭头所示从input_device可以通过input_handl找到input_handler,同样的input_handler可以通过 input_handle找到input_device

下一节将以even handler为例介绍设备注册以及打开的过程.

input子系统分析之二:数据结构的更多相关文章

  1. SPI子系统分析之二:数据结构【转】

    转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...

  2. SPI子系统分析之二:数据结构

    内核版本:3.9.5 spi_master struct spi_master用来描述一个SPI主控制器,我们一般不需要自己编写spi控制器驱动. /*结构体master代表一个SPI接口,或者叫一个 ...

  3. Linux input子系统分析

    输入输出是用户和产品交互的手段,因此输入驱动开发在Linux驱动开发中很常见.同时,input子系统的分层架构思想在Linux驱动设计中极具代表性和先进性,因此对Linux input子系统进行深入分 ...

  4. input子系统分析(转)

    转自:http://www.linuxidc.com/Linux/2011-09/43187.htm 作者:作者:YAOZHENGUO2006 Input子系统处理输入事务,任何输入设备的驱动程序都可 ...

  5. input子系统分析

    ------------------------------------------ 本文系本站原创,欢迎转载! 转载请注明出处:http://ericxiao.cublog.cn/ -------- ...

  6. Linux Input子系统浅析(二)-- 模拟tp上报键值【转】

    转自:https://blog.csdn.net/xiaopangzi313/article/details/52383226 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  7. input子系统分析之三:驱动模块

    内核版本:3.9.5 本节将以even handler来分析设备的注册和打开的过程,分析之前不妨回顾一下上节介绍的数据结构. 结合前两节分析可知,input子系统分为3层,最上一层是event han ...

  8. linux kernel input 子系统分析

    Linux 内核为了处理各种不同类型的的输入设备 , 比如说鼠标 , 键盘 , 操纵杆 , 触摸屏 , 设计并实现了一个对上层应用统一的试图的抽象层 , 即是Linux 输入子系统 . 输入子系统的层 ...

  9. input子系统分析之一:框架

    内核版本:3.9.5 输入设备总类繁杂,包括按键,键盘,触摸屏,鼠标,摇杆等等,它们本身都是字符设备,不过内核为了能将这些设备的共性抽象出来,简化驱动的开发,建立了一个Input子系统.Input子系 ...

随机推荐

  1. Django(一):从socket到MVC

    一.socket的http套路 web应用本质上是一个socket服务端,用户的浏览器是一个socket客户端.socket处在应用层与传输层之间,是操作系统中I/O系统的延伸部分(接口),负责系统进 ...

  2. waitKey()

    waitKey仅对窗口机制起作用,即namedWindow产生的窗口.若在此之前没有产生窗口,则waitKey相当于未执行. 注:namedWindow产生的窗口: namedWindow()+ims ...

  3. springboot: 集成freemark模板引擎

    1.freemark简介(摘自:http://blog.csdn.net/liaomin416100569/article/details/78349072) 在互联网软件内容网站中 一般首页的访问量 ...

  4. DB time VS. DB CPU

    如何行之有效地展示系统负载在做系统调优的时候是必不可少的技巧.通常我们会使用Oracle提供的Time Model,比如我们需要作出类似于下面这样的趋势图来展示系统负载的高低. 这样的趋势图可以直接使 ...

  5. JavaFX 之自定义窗口标题栏(二)

    一.问题场景 PC客户端登录界面仿QQ,上边显示图片,下边显示输入框和登录按钮.而JavaFX默认的窗口,不满足需求. 二.解决思路 隐藏窗口默认的标题栏,使用创建label对象,使用css将按钮图片 ...

  6. 各大互联网公司2014前端笔试面试题–HTML,CSS篇

    Html篇: 1.你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? IE: trident内核 Firefox:gecko内核 Safari:webkit内核 Opera:以前是presto ...

  7. xml获取属性值的方法

    sSqlstr += string.Format(@" and businessattr.value('(/Arch/Field[@Name=""发文单位$$" ...

  8. bootstrap常用模态框

    <!-- 触发器(button) --> <button class="btn btn-xs btn-success" data-toggle="mod ...

  9. OpenSSL生成公钥私钥***

    证书标准 X.509 - 这是一种证书标准,主要定义了证书中应该包含哪些内容.其详情可以参考RFC5280,SSL使用的就是这种证书标准. 编码格式 同样的X.509证书,可能有不同的编码格式,目前有 ...

  10. cordova 安装使用

    前人总结: Cordova是Apache软件基金会的一个产品.其前身是PhoneGap,由Nitobi开发,2011年10月,Adobe收够了Nitobi,并且PhoneGap项目也被贡献给Apach ...