内核版本: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. Spring-Java事物回滚失效处理

    spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因. 一切还是要从Java的检查型异常和非检查型异常说起 ...

  2. linux下如何添加一个用户并且让用户获得root权限【转载】

    原文:http://www.cnblogs.com/johnw/p/5499442.html 1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加 ...

  3. Linux 之 hugepage 大页内存理论

    HugePages是通过使用大页内存来取代传统的4kb内存页面,使得管理虚拟地址数变少,加快了从虚拟地址到物理地址的映射以及通过摒弃内存页面的换入换出以提高内存的整体性能.尤其是对于8GB以上的内存以 ...

  4. linq左连接

    Table1和Table2连接,把Table1的全列出来 var tempData = from a in table1 join b in table2 on a.Id equals b.aId i ...

  5. mac下finder子目录直接打开终端

    macstore下载go2shell,放你喜欢的目录,按住command,拖动到finder顶部的工具栏即可 终端直接打开finder,终端输入 open . 注意,后面红色的点,表明当前目录

  6. 关于FPGA复位的认识

    xilinx推荐尽量不复位,利用上电初始化,如果使用过程中需要复位,采用同步高复位. 如果逻辑工程较大,复位扇出会较多,会很影响时序,有以下常用方法: 复位信号按照不同时钟域分为rst0..rstn, ...

  7. java里面的public static void main(String[] args)

    package com.java_1; public class Hello { public static void main(String[] args){ System.out.println( ...

  8. configure: error: jpeglib.h not found.

    编译出现错误: configure: error: jpeglib.h not found. 解决方法:yum install libjpeg libjpeg-devel -y libjpeg-dev ...

  9. Linux命令-chmod、chown和chgrp

    Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而禁 ...

  10. 【BZOJ】2818: Gcd(欧拉函数+质数)

    题目 传送门:QWQ 分析 仪仗队 呃,看到题后感觉很像上面的仪仗队. 仪仗队求的是$ gcd(a,b)=1 $ 本题求的是$ gcd(a,b)=m $ 其中m是质数 把 $ gcd(a,b)=1 $ ...