紧接着上一节的实例我们来分析调用的input子系统的接口:

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

   1:  struct input_dev {
   2:      const char *name;      //设备名
   3:      const char *phys;     // 设备在系统中路径
   4:      const char *uniq;
   5:      struct input_id id;    //与input_handler匹配用的id
   6:   
   7:      unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
   8:   
   9:      unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //设备所支持事件类型,主要有EV_SYNC,EV_KEY,EV_REL,EV_ABS等       
  10:      unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];// 按键所对应的位图
  11:      unsigned long relbit[BITS_TO_LONGS(REL_CNT)];//  相对坐标对应位图
  12:      unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];// 绝对坐标对应位图
  13:      unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//支持其它事件
  14:      unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//支持led事件
  15:      unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//支持声音事件
  16:      unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//支持受力事件
  17:      unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//支持开关机事件
  18:   
  19:      unsigned int hint_events_per_packet;
  20:   
  21:      unsigned int keycodemax;
  22:      unsigned int keycodesize;
  23:      void *keycode;
  24:   
  25:      int (*setkeycode)(struct input_dev *dev,
  26:                const struct input_keymap_entry *ke,
  27:                unsigned int *old_keycode);
  28:      int (*getkeycode)(struct input_dev *dev,
  29:                struct input_keymap_entry *ke);
  30:   
  31:      struct ff_device *ff;
  32:   
  33:      unsigned int repeat_key;//最近一次的按键值
  34:      struct timer_list timer;
  35:   
  36:      int rep[REP_CNT];
  37:   
  38:      struct input_mt_slot *mt;
  39:      int mtsize;
  40:      int slot;
  41:      int trkid;
  42:   
  43:      struct input_absinfo *absinfo;
  44:   
  45:      unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反应设备当前的按键状态
  46:      unsigned long led[BITS_TO_LONGS(LED_CNT)];//反应设备当前的led状态
  47:      unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反应设备当前的声音输入状态
  48:      unsigned long sw[BITS_TO_LONGS(SW_CNT)];//反应设备当前的开关状态
  49:   
  50:      int (*open)(struct input_dev *dev);//第一次打开设备时调用,初始化设备用
  51:      void (*close)(struct input_dev *dev);//最后一个应用程序释放设备时用,关闭设备
  52:      int (*flush)(struct input_dev *dev, struct file *file);/*用于处理传递给设备的事件,如LED事件和声音事件*/
  53:      //  事件处理函数,主要是接收用户下发的命令,如点亮led;
  54:      int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
  55:   
  56:      struct input_handle __rcu *grab;    //当前占有该设备的input_handle
  57:   
  58:      spinlock_t event_lock;
  59:      struct mutex mutex;
  60:   
  61:      unsigned int users;        //打开该设备的用户数量(input handlers)
  62:      bool going_away;
  63:   
  64:      bool sync;
  65:   
  66:      struct device dev;
  67:   
  68:      struct list_head    h_list; // 设备所支持的input handle; 
  69:      struct list_head    node;    //用于将此input_dev链接到input_dev_list
  70:  };

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2.把输入设备注册进核心层  int input_register_device(struct input_dev *dev)

   1:  int input_register_device(struct input_dev *dev)
   2:  {
   3:      static atomic_t input_no = ATOMIC_INIT(0);
   4:      struct input_handler *handler;
   5:      const char *path;
   6:      int error;
   7:   
   8:      /* Every input device generates EV_SYN/SYN_REPORT events. */
   9:      __set_bit(EV_SYN, dev->evbit);//  /*表示设备支持所有的事件*/ 
  10:   
  11:      /* KEY_RESERVED is not supposed to be transmitted to userspace. */
  12:      __clear_bit(KEY_RESERVED, dev->keybit);
  13:   
  14:      /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
  15:      input_cleanse_bitmasks(dev);
  16:   
  17:      if (!dev->hint_events_per_packet)
  18:          dev->hint_events_per_packet =
  19:                  input_estimate_events_per_packet(dev);
  20:   
  21:      /*
  22:       * If delay and period are pre-set by the driver, then autorepeating
  23:       * is handled by the driver itself and we don't do it in input.c.
  24:       */
  25:      init_timer(&dev->timer);//初始化定时器
  26:      /*如果dev->rep[REP_DELAY]和dev->rep[REP_PERIOD]没有设值,
  27:      则将其赋默认值,这主要是为自动处理重复按键定义*/
  28:      if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
  29:          dev->timer.data = (long) dev;
  30:          dev->timer.function = input_repeat_key;//定时器处理函数
  31:          dev->rep[REP_DELAY] = 250;
  32:          dev->rep[REP_PERIOD] = 33;
  33:      }
  34:   
  35:      if (!dev->getkeycode)//获取键值
  36:          dev->getkeycode = input_default_getkeycode;
  37:   
  38:      if (!dev->setkeycode)//设置键值
  39:          dev->setkeycode = input_default_setkeycode;
  40:      //设置input_dev中的device的名字
  41:      dev_set_name(&dev->dev, "input%ld",
  42:               (unsigned long) atomic_inc_return(&input_no) - 1);
  43:   
  44:      error = device_add(&dev->dev);//将input_dev包含的device结构注册到Linux设备模型中,并可以在sysfs文件系统中表现出来。
  45:      if (error)
  46:          return error;
  47:   
  48:      path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
  49:      pr_info("%s as %s\n",
  50:          dev->name ? dev->name : "Unspecified device",
  51:          path ? path : "N/A");
  52:      kfree(path);
  53:   
  54:      error = mutex_lock_interruptible(&input_mutex);
  55:      if (error) {
  56:          device_del(&dev->dev);
  57:          return error;
  58:      }
  59:   
  60:      list_add_tail(&dev->node, &input_dev_list);//添加到input device 链表
  61:   
  62:      list_for_each_entry(handler, &input_handler_list, node)//
  63:          input_attach_handler(dev, handler);
  64:   
  65:      input_wakeup_procfs_readers();
  66:   
  67:      mutex_unlock(&input_mutex);
  68:   
  69:      return 0;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

3.调用input_report_key函数报告此事件

   1:  static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
   2:  {
   3:      input_event(dev, EV_KEY, code, !!value);
   4:  }

input_report_key函数参数,1.input_dev设备,2。按键值 3.按键的状态(1按下,0松开)

在input.h中定义了按键类code的值,BTN_0,BTN_1,KEY_A KEY_B等等这样的键值

此函数只是调用了input_event函数,这个函数是总的事件报告函数,

   1:  void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
   2:  {
   3:      unsigned long flags;
   4:   
   5:      if (is_event_supported(type, dev->evbit, EV_MAX)) {    //(1)
   6:   
   7:          spin_lock_irqsave(&dev->event_lock, flags);    //(2)
   8:          add_input_randomness(type, code, value);    //(3)
   9:          input_handle_event(dev, type, code, value);    //(4)
  10:          spin_unlock_irqrestore(&dev->event_lock, flags);//(5)    
  11:      }
  12:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

参数1.input_dev 2.事件类型(如EV_KEY键盘事件) 3.此类型具体事件code(如KEY_A,键A) 4.此事件的值(如1,按键按下)

(1)设备是否支持该事件类型。下面分析

(2)自旋锁上锁

(3)因为按键是随机事件,所以对随机熵有贡献,对于驱动无关。具体不懂

(4)进一步处理报告的事件

(5)自旋锁解锁

 
 
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Linux input子系统实例分析(二)的更多相关文章

  1. Linux input子系统实例分析(一)

    这是一个简单的输入设备驱动实例.这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理.该实例的代码如下:     1: #inclu ...

  2. Linux Input子系统浅析(二)-- 模拟tp上报键值【转】

    转自:https://blog.csdn.net/xiaopangzi313/article/details/52383226 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  3. Linux input子系统分析

    输入输出是用户和产品交互的手段,因此输入驱动开发在Linux驱动开发中很常见.同时,input子系统的分层架构思想在Linux驱动设计中极具代表性和先进性,因此对Linux input子系统进行深入分 ...

  4. Linux Input子系统

    先贴代码: //input.c int input_register_handler(struct input_handler *handler) { //此处省略很多代码 list_for_each ...

  5. 一些有用的javascript实例分析(二)

    原文:一些有用的javascript实例分析(二) 5 求出数组中所有数字的和 window.onload = function () { var oBtn = document.getElement ...

  6. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  7. Linux input子系统 io控制字段【转】

    转自:http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html http://blog.csdn.net/guoshaobei/arc ...

  8. Linux时间子系统之(二):软件架构

    专题文档汇总目录 Notes:从框架上讲解了时间子系统,从底向上包括CPU Local TImer.Global Counter.Clock Souce/Clock Events模块管理.Tick D ...

  9. Linux input子系统编程、分析与模板

    输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系 ...

随机推荐

  1. Python升级版本2.6到2.7

    CentOS 6 系统默认 Python 版本是:2.6.6 平时在使用中遇到很多的库要求是 2.7.x 版本的库,比如使用 ConfigParser 库,在 2.6 版本库就不支持没有 value ...

  2. 如何快速下载maven依赖jar包

    找到settings.xml文件.在mirrors里面添加下面的代码: <mirror> <id>alimaven</id> <mirrorOf>cen ...

  3. [无趣]bit reverse

    真不想承认啊,因为年轻而犯下的错误! inline void _BR(int* a,int r){ for(int i=0,j=1;i<r;++i,j<<=1){ for(int k ...

  4. DelegatingActionProxy

    使用 DelegatingActionProxy 使用 DelegatingRequestProcesso 非常简单方便,但有一个缺点:RequestProcessor 是Struts 的一个扩展点, ...

  5. uva 550 有趣的乘法(dfs)

    题目大意:给三个数A(进制).B(如*****7的最后一个数字7).C(*****7*4的后面的因数4)求符合条件下的第一个因数的位数最少 例子: 179487 * 4 = 717948 (10进制) ...

  6. Codeforces963D. Frequency of String

    $n \leq 100000$的一文本串,给$m \leq 100000$个询问,每次问一小串在文本串的哪一个最短的子串里出现指定次数.注意,询问串互不相同,且总长度$\leq 100000$. 比赛 ...

  7. 跳蚤 BZOJ 4310

    跳蚤 [问题描述] 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最 ...

  8. linux 管道符号 | ,以及&& ||等等特殊符号笔记

    管道和重导向:“|”.“>”.“>>”.“<” 重导向就是使命令改变它所认定的标准输出.“>”可将结果输出到文件中,该文件原有内容会被删除,“>>”则将结果附 ...

  9. 集合-Vector

    Vector中的操作是线程安全的. public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCa ...

  10. iOS开发中16进制颜色(html颜色值)字符串转为UIColor

    //16进制颜色(html颜色值)字符串转为UIColor +(UIColor *) hexStringToColor: (NSString *) stringToConvert { NSString ...