内核版本: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. ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存

    分享 最近在公司成功落地了一个用ASP.NET Core 开发前台的CMS项目,虽然对于表层的开发是兼容MVC5的,但是作为爱好者当然要用尽量多的ASP.NET Core新功能了. 背景 在项目开发的 ...

  2. sailsjs 不用写代码就能生成rest api 代码

    1. 脚手架安装 npm install sails -g     2. 生成基本项目 a. 项目 sails new appdemo b. 创建api sails new api demoapi a ...

  3. L2TP/IPSec一键安装脚本

    本脚本适用环境:系统支持:CentOS6+,Debian7+,Ubuntu12+内存要求:≥128M更新日期:2017 年 05 月 28 日 关于本脚本:名词解释如下L2TP(Layer 2 Tun ...

  4. arm_linux QT+v4l 显示视频

    1.参考(原创)基于ZedBoard的Webcam设计(三):视频的采集和动态显示 下载代码实测可用. 2.重新下载了csdn的代码,缺widget.h文件,后重新生成widget工程(自动产生wid ...

  5. UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 7: ordinal not in range(128) [duplicate]

    Python在往文件里写东西的时候,如果ascii码报错 参考 http://stackoverflow.com/questions/19833440/unicodeencodeerror-ascii ...

  6. cocos2d-x的popScene的动画效果

    找到CCDirector.h,找到void popScene(); 在下面加上一段类模板 template <class T> void popSceneWithTransition(fl ...

  7. C#操作MySql数据库帮助类(Dapper,T-Sql)

    using System.Text; using MySql.Data.MySqlClient; using System.Data; using Dapper; using System.Refle ...

  8. 双口RAM,值得研究

    在FPGA设计过程中,使用好双口RAM,也是提高效率的一种方法. 官方将双口RAM分为简单双口RAM和真双口RAM. 简单双口RAM只有一个写端口,一个读端口. 真双口RAM分别有两个写端口和两个读端 ...

  9. webpack快速入门(一):安装

    webpack入门系列,从安装到使用再到放弃....全套的哟,呵呵 首先说明,我是一个后端开发,好几年没碰过前端了,想当年写前端的时候jq还是主流,那时的前端还单纯的像个处女一样,哪有什么构建工具.依 ...

  10. 手游[追忆之青]动画导演:2D动画制作技巧

    转自:http://www.gamelook.com.cn/2016/09/264591 GameLook报道/由一般法人计算机娱乐协会(CESA)主办的CEDEC2016日前在日本横滨举行,诸多开发 ...