内核版本: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. flask第二十篇——模板【3】

    请关注公众号:自动化测试实战 现在我们通过查询字符串的方式给render_template传参,我们就要用到flask库的flask.request.args.get()函数先获取参数,在index. ...

  2. npm 可执行模块的开发&&私服发布

    备注:    大家日常在使用npm 安装依赖的时候有一些是命令行工具,比如vue-cli,具体的开发比较简单,同时 可以基于此开发一些脚手架,方便开发. 1. 项目初始化 npm init 备注:按照 ...

  3. Let’s Encrypt 将于 2018 年免费提供通配符证书

    旨在让每个网站都启用 HTTPS 加密的 Let's Encrypt CA 宣布将于 2018 年 1 月免费提供通配符证书(Wildcard certificate).通配符证书是一种可被多个子域使 ...

  4. mysql导入外部sql脚本的方法

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011043843/article/details/29689853 导入的方法分为两种:一是採用图 ...

  5. Hyper-V 手动导入虚机配置实例(转载)

    原文转载:http://blog.51cto.com/bobzy/980241 Hyper-V提供了很方便的虚机导入和导出功能.平时假如我们想导出虚机,先选中虚机,然后鼠标右键在出现菜单列表中选中“导 ...

  6. Python 函数 -xrange()

    xrange() xrange() 函数用法与 range 完全相同,所不同的是生成的不是一个数组,而是一个生成器. 语法: xrange(stop) xrange(start, stop[, ste ...

  7. ecmall类关系图(转)

  8. Mac下docker搭建lnmp环境 + redis + elasticsearch

    之前在windows下一直使用vagrant做开发, 团队里面也是各种开发环境,几个人也没有统一环境,各种上线都是人肉,偶尔还会有因为开发.测试.生产环境由于软件版本或者配置不一致产生的问题, 今年准 ...

  9. 一些非常好的VC++/MFC开源项目链接

    Introduction List of some of the best Open Source projects written in VC++/MFC. Background Codeproje ...

  10. 全局获取Context

    1.定制一个Application类,管理全局的状态信息 public class MyApplication extends Application{ private static Context ...