linux input subsystem 架构分析

news/2024/7/4 9:38:17

主要数据结构

struct input_dev {

 void *private;

 const char *name;
 const char *phys;
 const char *uniq;
 struct input_id id;

 unsigned long evbit[NBITS(EV_MAX)];
 unsigned long keybit[NBITS(KEY_MAX)];
 unsigned long relbit[NBITS(REL_MAX)];
 unsigned long absbit[NBITS(ABS_MAX)];
 unsigned long mscbit[NBITS(MSC_MAX)];
 unsigned long ledbit[NBITS(LED_MAX)];
 unsigned long sndbit[NBITS(SND_MAX)];
 unsigned long ffbit[NBITS(FF_MAX)];
 unsigned long swbit[NBITS(SW_MAX)];

 unsigned int keycodemax;
 unsigned int keycodesize;
 void *keycode;
 int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
 int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);

 struct ff_device *ff;

 unsigned int repeat_key;
 struct timer_list timer;

 int state;

 int sync;

 int abs[ABS_MAX + 1];
 int rep[REP_MAX + 1];

 unsigned long key[NBITS(KEY_MAX)];
 unsigned long led[NBITS(LED_MAX)];
 unsigned long snd[NBITS(SND_MAX)];
 unsigned long sw[NBITS(SW_MAX)];

 int absmax[ABS_MAX + 1];
 int absmin[ABS_MAX + 1];
 int absfuzz[ABS_MAX + 1];
 int absflat[ABS_MAX + 1];

 int (*open)(struct input_dev *dev);
 void (*close)(struct input_dev *dev);
 int (*flush)(struct input_dev *dev, struct file *file);
 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);

 struct input_handle *grab;

 struct mutex mutex; 
 unsigned int users;

 struct device dev;
 union {   
  struct device *dev;
 } cdev;

 struct list_head h_list;
 struct list_head node;
};

struct input_handle {

 void *private;

 int open;
 const char *name;

 struct input_dev *dev;
 struct input_handler *handler;

 struct list_head d_node;
 struct list_head h_node;
};

struct input_handler {

 void *private;

 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
 void (*disconnect)(struct input_handle *handle);
 void (*start)(struct input_handle *handle);

 const struct file_operations *fops;
 int minor;
 const char *name;

 const struct input_device_id *id_table;
 const struct input_device_id *blacklist;

 struct list_head h_list;
 struct list_head node;
};

 

------------------------------

input subsystem 用来统一处理数据输入设备,例如键盘,鼠标,游戏杆,触摸屏等等。

这里引用 Linux Journal 上的一个图来说明input subsystem 的架构:
(http://www.linuxjournal.com/article/6396)

 

linux input subsystem 架构分析

 


我们可以看到,input core 用来协调硬件的input事件 和 用户层应用之间的通讯。

 


这里再引用 ELDD 上的一个图片,来详细说明其内部的结构:

linux input subsystem 架构分析

 

 


在内核中,input_dev 表示一个 input设备;input_handler 来表示input设备的 interface。

 

所有的input_dev 用双向链表 input_dev_list 连起来,如图所示:


                          /----------------/
         /--------------->| input_dev_list |<------------------/
         |                /----------------/                   |
         |                                                     |
         |                                                     |
         |                                                     |
         |                                                     |
         |      input_dev                      input_dev       | 
         |    +------------+                 +------------+    | 
         |    |            |                 |            |    | 
         |    +------------+                 +------------+    | 
         |    |            |                 |            |    | 
         |    +------------+                 +------------+    |
         |    |            |                 |            |    |    
         |    +------------+                 +------------+    |    
         /--->|   node     |<---- ...... ----|   node     |<---/    
              +------------+                 +------------+         
              |   h_list   |                 |   h_list   |         
              +------------+                 +------------+

在调用 int input_register_device(struct input_dev *dev) 的时候,会将新的 input_dev 加入到这个链表中。

 


所有的input_handler 用双向链表 input_handler_list 连起来, 如图所示:


                          /--------------------/
   /--------------------->| input_handler_list |<--------------------/
   |                      /--------------------/                     |
   |                                                                 |
   |                                                                 |
   |                                                                 |
   |                                                                 |
   |        input_handler                        input_handler       |
   |    +------------------+                 +------------------+    |
   |    |  private         |                 |  private         |    |
   |    +------------------+                 +------------------+    |
   |    | (*event)()       |                 | (*event)()       |    |
   |    +------------------+                 +------------------+    |
   |    | (*connect)()     |                 | (*connect)()     |    |
   |    +------------------+                 +------------------+    |
   |    | (*disconnect)()  |                 | (*disconnect)()  |    |
   |    +------------------+                 +------------------+    |
   |    | (*start)()       |                 | (*start)()       |    |
   |    +------------------+                 +------------------+    |
   |    |  fops            |                 |  fops            |    |
   |    +------------------+                 +------------------+    |
   |    |  minor           |                 |  minor           |    |
   |    +------------------+                 +------------------+    |
   |    |  name            |                 |  name            |    |
   |    +------------------+                 +------------------+    |
   |    |  id_table        |                 |  id_table        |    |
   |    +------------------+                 +------------------+    |
   |    |  blacklist       |                 |  blacklist       |    |
   |    +------------------+                 +------------------+    |
   |    |  hlist           |                 |  hlist           |    |
   |    +------------------+                 +------------------+    |
   /--->|  node            |<--- ...... ---->|  node            |<---/
        +------------------+                 +------------------+    
                                                                     
在调用 int input_register_handler(struct input_handler *handler) 的时候,会将新的 input_handler 加入到这个链表中。


每个input_dev 和 input_handler 是要关联上才能工作的,在注册 input_dev 或者 input_handler的时候,就遍历上面的列表,找到相匹配的,然后调用 input_handler 的 connect函数来将它们联系到一起。
通常在input_handler 的 connect函数中,就会创建 input_handle, input_handle就是负责将 input_dev 和 input_handler 联系在一起的,如图所示:

                                                            
                                                                             
                                 /----------------/                          
                /--------------->| input_dev_list |<------------------/      
                |                /----------------/                   |      
                |                                                     |      
                |                                                     |      
                |                                                     |      
                |                                                     |      
        /----------->  input_dev                      input_dev       |      
        |       |    +------------+                 +------------+    |      
        |       |    |            |                 |            |    |      
        |       |    +------------+                 +------------+    |      
        |       |    |            |                 |            |    |      
        |       |    +------------+                 +------------+    |      
        |       |    |            |                 |            |    |      
        |       |    +------------+                 +------------+    |      
        |       /--->|   node     |<---- ...... ----|   node     |<---/      
        |            +------------+                 +------------+           
        |     /----->|   h_list   |<-------/        |   h_list   |           
        |     |      +------------+        |        +------------+           
        |     |                            |                                 
        |     |                            |                                 
        |     |                            |                                 
        |     |                            |                                 
        |     |                            |                                 
        |     |                            |                                 
        |     |                            |                                 
        |     |                            |                                 
        |     |        input_handle        |                                 
        |     |      +--------------+      |                                 
        |     |      |  private     |      |                                 
        |     |      +--------------+      |                                 
        |     |      |  open        |      |                                 
        |     |      +--------------+      |                                 
        |     |      |  name        |      |                                 
        |     |      +--------------+      |                                 
        |     /----->|  d_node      |<-----/                                 
        |            +--------------+                                        
        /------<-----| *dev         |                                        
                     +--------------+                                        
      /-----<--------| *handler     |                                        
      |              +--------------+                                        
      |        /-----|  h_node      |<-----/                                 
      |        |     +--------------+      |                                 
      |        |                           |                                 
      |        |                           |                                 
      |        |                           |                                 
      |        |                           |                                 
      |        |                           |                                 
      |        |                           |                                 
      /------------>   input_handler       |                                 
               |   +------------------+    |                                 
               |   |  private         |    |                                 
               |   +------------------+    |                                 
               |   | (*event)()       |    |                                 
               |   +------------------+    |                                 
               |   | (*connect)()     |    |                                 
               |   +------------------+    |                                 
               |   | (*disconnect)()  |    |                                 
               |   +------------------+    |                                 
               |   | (*start)()       |    |                                 
               |   +------------------+    |                                 
               |   |  fops            |    |                                 
               |   +------------------+    |                                 
               |   |  minor           |    |                                 
               |   +------------------+    |                                 
               |   |  name            |    |                                 
               |   +------------------+    |                                 
               |   |  id_table        |    |                                 
               |   +------------------+    |                                 
               |   |  blacklist       |    |                                 
               |   +------------------+    |                                 
               /-->|  hlist           |<---/                                 
                   +------------------+                                      
                   |  node            |                                      
                   +------------------+

这里需要额外说明一下的是: input_dev 中的 h_node 是 input_handle 链表的list节点,也就是说,一个input_dev,可以对应多个 input_handle.


当设备产生 input event 的时候,例如按下了一个键,驱动就会调用 input_handler 中的 event 函数,同时,如果input_dev 支持的话,也会调用 input_dev 的 event 函数。


这样,设备产生的事件就会被驱动记录下来。


当用户层的程序需要获知这些事件的时候,会调用 input_handler中的 struct file_operations *fops 中的相应函数,例如 read 等等。

 

可以看出,整个 input 框架的构思还是比较简洁方便的。

 

 

【参考资料】 

1. The Linux USB Input Subsystem

 Part I : http://www.linuxjournal.com/article/6396

 Part II : http://www.linuxjournal.com/article/6429

 

2. linux kernel 2.6.23.11

 


http://www.niftyadmin.cn/n/3613035.html

相关文章

HDU 2020,2021,2024,2028,2029,2030

//Made by syx //Time 2010年7月29日 09:55:28 // //2020 绝对值排序 //2021 发工资咯&#xff1a;&#xff09; //2024 C语言合法标识符 //2028 Lowest Common Multiple Plus //2029 Palindromes_easy version 回文串 //2030 汉字统计 /*//2030 汉字统计 #include <iostrea…

linux内存寻址

本章节介绍linux寻址技术&#xff0c;详细描述80x86微处理器怎样进行芯片级的内存寻址&#xff0c;linux又是如何寻址硬件的。 1. linux内存地址 80x86微处理器下主要有三种不同的地址&#xff1a;逻辑地址&#xff0c;线性地址&#xff0c;物理地址。 逻辑地址&#xff1a; 主…

Linux Input Device 介紹: APIs

Linux Input Device 介紹: APIs jollen 發表於 April 8, 2009 12:18 PM Linux 的 Input Device 是重要的一個 subsystem&#xff0c;在進行實例介紹前&#xff0c;先大略了解一下相關的 API。 Linux Input Device &#xfeff;input.c是Linux的”input”驅動程式&#xff0c;主…

Android 如何破解兼容性困局

最新的消息表明&#xff0c;Android 手机的销售量超越 iPhone&#xff0c;虽然在整体市场占有率上&#xff0c;仍然不及竞争对手&#xff0c;但是却已经初现王者风范&#xff0c;一些文章也预测 Android 最终会稳坐智能手机第一把交椅。Android 的确是十分有潜力的&#xff0c;…

webpack学习路径(01.webpack的配置及使用)

对于webpack&#xff0c;我的理解是一种工具提供了友好的前端模块化开发的支持&#xff0c;可以解决代码压缩混淆&#xff0c;浏览器兼容性问题&#xff0c;以及提升性能等主要功能&#xff0c; 安装配置过程&#xff1a; 首先创建一个根目录&#xff08;随便创建一个文件夹&…

C#中直接打印Report文件(rdlc)

Visual Studio自带的报表文件&#xff08;rdlc&#xff0c;后面提到的报表&#xff0c;都指rdlc报表文件&#xff09;虽然功能相对不是十分强大&#xff0c;但应付一般的报表要求也是绰绰有余了。关于rdlc报表的使用和设计方法&#xff0c;这里就不做讲解了&#xff0c;本文主要…