内核版本:3.9.5

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

 struct input_dev {
const char *name;
const char *phys;
const char *uniq;
struct input_id id;//与input_handler匹配用的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)];//支持声音事件
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//支持受力事件
unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//支持开关机时间 unsigned int hint_events_per_packet; unsigned int keycodemax;
unsigned int keycodesize;
void *keycode; int (*setkeycode)(struct input_dev *dev,
const struct input_keymap_entry *ke,
unsigned int *old_keycode);
int (*getkeycode)(struct input_dev *dev,
struct input_keymap_entry *ke); struct ff_device *ff; unsigned int repeat_key;//最近一次的按键值
struct timer_list timer; int rep[REP_CNT]; struct input_mt *mt; struct input_absinfo *absinfo; unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反应设备当前的按键状态
unsigned long led[BITS_TO_LONGS(LED_CNT)];//反应设备当前的led状态
unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反应设备当前的声音输入状态
unsigned long sw[BITS_TO_LONGS(SW_CNT)];//反应设备当前的开关状态 int (*open)(struct input_dev *dev);//第一次打开设备时调用,初始化设备用
void (*close)(struct input_dev *dev);//最后一个应用程序释放设备时用,关闭设备
int (*flush)(struct input_dev *dev, struct file *file);/*用于处理传递给设备的事件,如LED事件和声音事件*/
int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); struct input_handle __rcu *grab;//当前占有该设备的input_handle spinlock_t event_lock;
struct mutex mutex; unsigned int users;//打开该设备的用户数量(input handlers)
bool going_away; struct device dev; struct list_head h_list;//该链表头用于链接此input_dev所关联的input_handle
struct list_head node;//用于将此input_dev链接到input_dev_list unsigned int num_vals;
unsigned int max_vals;
struct input_value *vals; bool devres_managed;
};

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

 struct input_handler {

     void *private;

     void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);/*event用于处理事件*/
void (*events)(struct input_handle *handle,
const struct input_value *vals, unsigned int count);
bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*match)(struct input_handler *handler, struct input_dev *dev);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);/*connect用于建立handler和device的联系*/
void (*disconnect)(struct input_handle *handle);/*disconnect用于解除handler和device的联系*/
void (*start)(struct input_handle *handle); bool legacy_minors;
int minor;//次设备号
const char *name; const struct input_device_id *id_table;//用于和input_dev匹配 struct list_head h_list;//用于链接和此input_handler相关的input_handle
struct list_head node;//用于将该input_handler链入input_handler_list
};

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

 struct input_handle {

     void *private;

     int open;//记录设备的打开次数(有多少个应用程序访问设备)
const char *name; struct input_dev *dev;//指向所属的device
struct input_handler *handler;//指向所属的handler struct list_head d_node;//用于将此input_handle链入所属input_dev的h_list链表
struct list_head h_node;//用于将此input_handle链入所属input_handler的h_list链表
};

可以看到,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. Making Genome in Berland (DFS+思维)

    个人心得:被这周的专题名坑了,一直用字典树,明明题目看得很清楚了,不存在相同的字母,即每个字母最多只有一个直接后驱,那么只要用DFS走开头就好了, 思想很巧妙,用vector,记录后驱,同时用visi ...

  2. scrapy爬取验证码登录网页

    scrapy 验证码登录程序, https://accounts.douban.com/login # -*- coding: utf-8 -*- import scrapy import urlli ...

  3. RabbitMQ介绍及windows下安装使用

    RebbitMQ介绍 RabbitMQ是一个由 Erlang (一种通用的面向并发的编程语言)开发的AMQP(Advanced Message Queue )的开源实现,Rabbit MQ 是建立在E ...

  4. DML操纵语句

    --在新增数据的时候,如果在表名之后没有跟 列名,那么values()必须写全--顺序必须不能改变,这个顺序就是表中列的顺序insert into dept values(70,'20','哈哈') ...

  5. pymongo和mongodbengine之间的区别

    pymongo是一个mongo driver,可以用来连接数据库以及对数据库进行操作,但是是用mongo自己的用来操作数据库的语句进行操作数据库,而mongodbengine就像是sqlalchemy ...

  6. 用oradebug short_stack及strace -p分析oracle进程是否dead或出现故障

    1,可以采用oradebug或者strace -p跟踪后台或前台进程是否dead或hang住2,如果进程出现故障,必会在对应的TRC文件写入最新信息,基于此可以获取非常重要的信息进一步分析与诊断    ...

  7. angular(mvc)指令的嵌套使用

    关于指令嵌套的使用,取值问题. 原理类似于控制器中使用指令,父指令类似于控制器,子指令就类似于控制器中指令.通过传值方式‘=’,我们直接可以在父指令中获取数据 举一个例子: 有个指令parentDir ...

  8. 如何在项目中使用requireJS

    本文主要讲讲如何在一个项目中合理的使用requireJS,来加载js代码,这里是个实际例子,讲解不多, 看详情请连接到:http://www.cnblogs.com/evaling/p/6722760 ...

  9. 黄聪:WordPress默认编辑器可视化切换不见了,非插件导致消失问题

    1.后台---用户---我的个人资料 2.看看 [可视化编辑器]的[撰写文章时不使用可视化编辑器]项目是不是勾上了 3.去掉保存即可

  10. Java-Runoob:Java 异常处理

    ylbtech-Java-Runoob:Java 异常处理 1.返回顶部 1. Java 异常处理 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少 ...