Linux/Android——输入子系统input_event传递

一身转战三千里,一剑曾当百万师。这篇文章主要讲述Linux/Android——输入子系统input_event传递 相关的知识,希望能为你提供帮助。
本文转载自:http://blog.csdn.net/jscese/article/details/42099381
  在前文  Linux/Android— — usb触摸屏驱动 - usbtouchscreen (一)  中记录了如何在kernel中添加input device 类型为touchscreen的驱动,
这在整个输入体系中是最下层的设备驱动部分,往上一层就是linux内核的管理驱动input系统,kernel中的源码位置:/kernel/drivers/input/input.c
 
                                                                              撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42099381
 
到目前已经完全调通,可以正常使用了,现在记录一下这段时间接触到的android 输入input 系统,先看一张网上的层次图,蛮不错的:
                             
                 

Linux/Android——输入子系统input_event传递

文章图片

 
上一篇博客里面的 usbtouchscreen 就是对应上图的I2c module的位置,而在kernel中input的核心就是input.c .
input_dev:  这个结构体表述的是一个输入设备的相关信息,在usbtouchscreen 驱动中的  usbtouch_probe  会初始化input_dev,作为usbtouch设备的一部分.
会对 input_dev  做一系列的初始化,设置参数之类的,具体可参考之前博客
input_dev 结构原型如下,/kernel/include/linux/input.h中定义:
 
[objc]  view plain  copy  
  1. /** 
  2.   *  struct  input_dev  -  represents  an  input  device 
  3.   *  @name:  name  of  the  device 
  4.   *  @phys:  physical  path  to  the  device  in  the  system  hierarchy 
  5.   *  @uniq:  unique  identification  code  for  the  device  (if  device  has  it) 
  6.   *  @id:  id  of  the  device  (struct  input_id) 
  7.   *  @propbit:  bitmap  of  device  properties  and  quirks 
  8.   *  @evbit:  bitmap  of  types  of  events  supported  by  the  device  (EV_KEY, 
  9.   *    EV_REL,  etc.) 
  10.   *  @keybit:  bitmap  of  keys/buttons  this  device  has 
  11.   *  @relbit:  bitmap  of  relative  axes  for  the  device 
  12.   *  @absbit:  bitmap  of  absolute  axes  for  the  device 
  13.   *  @mscbit:  bitmap  of  miscellaneous  events  supported  by  the  device 
  14.   *  @ledbit:  bitmap  of  leds  present  on  the  device 
  15.   *  @sndbit:  bitmap  of  sound  effects  supported  by  the  device 
  16.   *  @ffbit:  bitmap  of  force  feedback  effects  supported  by  the  device 
  17.   *  @swbit:  bitmap  of  switches  present  on  the  device 
  18.   *  @hint_events_per_packet:  average  number  of  events  generated  by  the 
  19.   *    device  in  a  packet  (between  EV_SYN/SYN_REPORT  events).  Used  by 
  20.   *    event  handlers  to  estimate  size  of  the  buffer  needed  to  hold 
  21.   *    events. 
  22.   *  @keycodemax:  size  of  keycode  table 
  23.   *  @keycodesize:  size  of  elements  in  keycode  table 
  24.   *  @keycode:  map  of  scancodes  to  keycodes  for  this  device 
  25.   *  @getkeycode:  optional  legacy  method  to  retrieve  current  keymap. 
  26.   *  @setkeycode:  optional  method  to  alter  current  keymap,  used  to  implement 
  27.   *    sparse  keymaps.  If  not  supplied  default  mechanism  will  be  used. 
  28.   *    The  method  is  being  called  while  holding  event_lock  and  thus  must 
  29.   *    not  sleep 
  30.   *  @ff:  force  feedback  structure  associated  with  the  device  if  device 
  31.   *    supports  force  feedback  effects 
  32.   *  @repeat_key:  stores  key  code  of  the  last  key  pressed;   used  to  implement 
  33.   *    software  autorepeat 
  34.   *  @timer:  timer  for  software  autorepeat 
  35.   *  @rep:  current  values  for  autorepeat  parameters  (delay,  rate) 
  36.   *  @mt:  pointer  to  array  of  struct  input_mt_slot  holding  current  values 
  37.   *    of  tracked  contacts 
  38.   *  @mtsize:  number  of  MT  slots  the  device  uses 
  39.   *  @slot:  MT  slot  currently  being  transmitted 
  40.   *  @trkid:  stores  MT  tracking  ID  for  the  current  contact 
  41.   *  @absinfo:  array  of  & struct  input_absinfo  elements  holding  information 
  42.   *    about  absolute  axes  (current  value,  min,  max,  flat,  fuzz, 
  43.   *    resolution) 
  44.   *  @key:  reflects  current  state  of  device‘s  keys/buttons 
  45.   *  @led:  reflects  current  state  of  device‘s  LEDs 
  46.   *  @snd:  reflects  current  state  of  sound  effects 
  47.   *  @sw:  reflects  current  state  of  device‘s  switches 
  48.   *  @open:  this  method  is  called  when  the  very  first  user  calls 
  49.   *    input_open_device().  The  driver  must  prepare  the  device 
  50.   *    to  start  generating  events  (start  polling  thread, 
  51.   *    request  an  IRQ,  submit  URB,  etc.) 
  52.   *  @close:  this  method  is  called  when  the  very  last  user  calls 
  53.   *    input_close_device(). 
  54.   *  @flush:  purges  the  device.  Most  commonly  used  to  get  rid  of  force 
  55.   *    feedback  effects  loaded  into  the  device  when  disconnecting 
  56.   *    from  it 
  57.   *  @event:  event  handler  for  events  sent  _to_  the  device,  like  EV_LED 
  58.   *    or  EV_SND.  The  device  is  expected  to  carry  out  the  requested 
  59.   *    action  (turn  on  a  LED,  play  sound,  etc.)  The  call  is  protected 
  60.   *    by  @event_lock  and  must  not  sleep 
  61.   *  @grab:  input  handle  that  currently  has  the  device  grabbed  (via 
  62.   *    EVIOCGRAB  ioctl).  When  a  handle  grabs  a  device  it  becomes  sole 
  63.   *    recipient  for  all  input  events  coming  from  the  device 
  64.   *  @event_lock:  this  spinlock  is  is  taken  when  input  core  receives 
  65.   *    and  processes  a  new  event  for  the  device  (in  input_event()). 
  66.   *    Code  that  accesses  and/or  modifies  parameters  of  a  device 
  67.   *    (such  as  keymap  or  absmin,  absmax,  absfuzz,  etc.)  after  device 
  68.   *    has  been  registered  with  input  core  must  take  this  lock. 
  69.   *  @mutex:  serializes  calls  to  open(),  close()  and  flush()  methods 
  70.   *  @users:  stores  number  of  users  (input  handlers)  that  opened  this 
  71.   *    device.  It  is  used  by  input_open_device()  and  input_close_device() 
  72.   *    to  make  sure  that  dev-> open()  is  only  called  when  the  first 
  73.   *    user  opens  device  and  dev-> close()  is  called  when  the  very 
  74.   *    last  user  closes  the  device 
  75.   *  @going_away:  marks  devices  that  are  in  a  middle  of  unregistering  and 
  76.   *    causes  input_open_device*()  fail  with  -ENODEV. 
  77.   *  @sync:  set  to  %true  when  there  were  no  new  events  since  last  EV_SYN 
  78.   *  @dev:  driver  model‘s  view  of  this  device 
  79.   *  @h_list:  list  of  input  handles  associated  with  the  device.  When 
  80.   *    accessing  the  list  dev-> mutex  must  be  held 
  81.   *  @node:  used  to  place  the  device  onto  input_dev_list 
  82.   */   
  83. struct  input_dev  {   
  84.         const  charchar  *name;    
  85.         const  charchar  *phys;    
  86.         const  charchar  *uniq;    
  87.         struct  input_id  id;    
  88.    
  89.         unsigned  long  propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];    
  90.    
  91.         unsigned  long  evbit[BITS_TO_LONGS(EV_CNT)];    
  92.         unsigned  long  keybit[BITS_TO_LONGS(KEY_CNT)];    
  93.         unsigned  long  relbit[BITS_TO_LONGS(REL_CNT)];    
  94.         unsigned  long  absbit[BITS_TO_LONGS(ABS_CNT)];    
  95.         unsigned  long  mscbit[BITS_TO_LONGS(MSC_CNT)];    
  96.         unsigned  long  ledbit[BITS_TO_LONGS(LED_CNT)];    
  97.         unsigned  long  sndbit[BITS_TO_LONGS(SND_CNT)];    
  98.         unsigned  long  ffbit[BITS_TO_LONGS(FF_CNT)];    
  99.         unsigned  long  swbit[BITS_TO_LONGS(SW_CNT)];    
  100.    
  101.         unsigned  int  hint_events_per_packet;    
  102.    
  103.         unsigned  int  keycodemax;    
  104.         unsigned  int  keycodesize;    
  105.         voidvoid  *keycode;    
  106.    
  107.         int  (*setkeycode)(struct  input_dev  *dev,   
  108.                             const  struct  input_keymap_entry  *ke,   
  109.                             unsigned  intint  *old_keycode);    
  110.         int  (*getkeycode)(struct  input_dev  *dev,   
  111.                             struct  input_keymap_entry  *ke);    
  112.    
  113.         struct  ff_device  *ff;    
  114.    
  115.         unsigned  int  repeat_key;    
  116.         struct  timer_list  timer;    
  117.    
  118.         int  rep[REP_CNT];    
  119.    
  120.         struct  input_mt_slot  *mt;    
  121.         int  mtsize;    
  122.         int  slot;    
  123.         int  trkid;    
  124.    
  125.         struct  input_absinfo  *absinfo;    
  126.    
  127.         unsigned  long  key[BITS_TO_LONGS(KEY_CNT)];    
  128.         unsigned  long  led[BITS_TO_LONGS(LED_CNT)];    
  129.         unsigned  long  snd[BITS_TO_LONGS(SND_CNT)];    
  130.         unsigned  long  sw[BITS_TO_LONGS(SW_CNT)];    
  131.    
  132.         int  (*open)(struct  input_dev  *dev);    
  133.         void  (*close)(struct  input_dev  *dev);    
  134.         int  (*flush)(struct  input_dev  *dev,  struct  file  *file);    
  135.         int  (*event)(struct  input_dev  *dev,  unsigned  int  type,  unsigned  int  code,  int  value);    
  136.    
  137.         struct  input_handle  __rcu  *grab;    
  138.    
  139.         spinlock_t  event_lock;    
  140.         struct  mutex  mutex;    
  141.    
  142.         unsigned  int  users;    
  143.         bool  going_away;    
  144.    
  145.         bool  sync;    
  146.    
  147.         struct  device  dev;    
  148.    
  149.         struct  list_head        h_list;    
  150.         struct  list_head        node;    
  151. };    

我解释可能还会误导,源码上面的注释是最好的解释,都是描述一个input 设备的相关信息.
 
每一个input设备,都需要初始化一个这样的input_dev结构来描述记录此设备的一些特性,然后通过input_register_device 注册到设备总线上以供后续使用
可以到系统运行目录的/proc/bus/input下  cat devices  查看总线上的已经注册上的input device
 
 
input_event:  设备驱动部分往上传递的就是触发的event事件了,还以usbtouchscreen的为例,回调函数为:
[objc]  view plain  copy  
  1. /***************************************************************************** 
  2.   *  Generic  Part 
  3.   */   
  4. static  void  usbtouch_process_pkt(struct  usbtouch_usb  *usbtouch,   
  5.                                                                   unsigned  charchar  *pkt,  int  len)   
  6. {   
  7.         struct  usbtouch_device_info  *type  =  usbtouch-> type;      
  8.    
  9.         if  (!type-> read_data(usbtouch,  pkt))   
  10.                         return;    
  11.    
  12.         input_report_key(usbtouch-> input,  BTN_TOUCH,  usbtouch-> touch);   //  上报触摸类型  。touch为按下   
  13.    
  14.         if  (swap_xy)  {   
  15.                 input_report_abs(usbtouch-> input,  ABS_X,  usbtouch-> y);    
  16.                 input_report_abs(usbtouch-> input,  ABS_Y,  usbtouch-> x);    
  17.         }  else  {   
  18.                 input_report_abs(usbtouch-> input,  ABS_X,  usbtouch-> x);    
  19.                 input_report_abs(usbtouch-> input,  ABS_Y,  usbtouch-> y);   //  上报绝对坐标值   
  20.         }   
  21.         if  (type-> max_press)   
  22.                 input_report_abs(usbtouch-> input,  ABS_PRESSURE,  usbtouch-> press);    
  23.         input_sync(usbtouch-> input);       //  同步操作   
  24. }   



可以看到通过  input_report_*  上报事件到input.c中,这也就是上面层次图中的箭头 9  ,初始在/kernel/include/linux/input.h:
 
[objc]  view plain  copy  
  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. }   
  5.    
  6. static  inline  void  input_report_rel(struct  input_dev  *dev,  unsigned  int  code,  int  value)   
  7. {   
  8.         input_event(dev,  EV_REL,  code,  value);    
  9. }   
  10.    
  11. static  inline  void  input_report_abs(struct  input_dev  *dev,  unsigned  int  code,  int  value)   
  12. {   
  13.         input_event(dev,  EV_ABS,  code,  value);    
  14. }   
 
 
可以看到不同的report 都调用进了input_event,只是传参不同,接下来的事就全交由input.c 来做了!
 
[objc]  view plain  copy  
  1. /** 
  2.   *  input_event()  -  report  new  input  event 
  3.   *  @dev:  device  that  generated  the  event 
  4.   *  @type:  type  of  the  event 
  5.   *  @code:  event  code 
  6.   *  @value:  value  of  the  event 
  7.   * 
  8.   *  This  function  should  be  used  by  drivers  implementing  various  input 
  9.   *  devices  to  report  input  events.  See  also  input_inject_event(). 
  10.   * 
  11.   *  NOTE:  input_event()  may  be  safely  used  right  after  input  device  was 
  12.   *  allocated  with  input_allocate_device(),  even  before  it  is  registered 
  13.   *  with  input_register_device(),  but  the  event  will  not  reach  any  of  the 
  14.   *  input  handlers.  Such  early  invocation  of  input_event()  may  be  used 
  15.   *  to  ‘seed‘  initial  state  of  a  switch  or  initial  position  of  absolute 
  16.   *  axis,  etc. 
  17.   */   
  18. void  input_event(struct  input_dev  *dev,   
  19.                   unsigned  int  type,  unsigned  int  code,  int  value)   
  20. {   
  21.         unsigned  long  flags;    
  22.    
  23.         if  (is_event_supported(type,  dev-> evbit,  EV_MAX))  {    //判断是否是注册时的event类型,驱动probe时注册input_dev时设置了能响应的event类型   
  24.    
  25.                 spin_lock_irqsave(& dev-> event_lock,  flags);   //自旋锁枷锁   
  26.    
  27.               add_input_randomness(type,  code,  value);    
  28.                 input_handle_event(dev,  type,  code,  value);     //进一步处理传上来的这个  event   
  29.                 spin_unlock_irqrestore(& dev-> event_lock,  flags); //解锁   
  30.         }   
  31. }   

可以看到在这里首先就是过滤了事件类型,这个也是在usbtouchscreen中的probe中初始化过的!
 
类型有如下几种:
 
[objc]  view plain  copy  
  1. /* 
  2.   *  Event  types 
  3.   */   
  4.    
  5. #define  EV_SYN                    0x00   
  6. #define  EV_KEY                    0x01   
  7. #define  EV_REL                    0x02   
  8. #define  EV_ABS                    0x03   
  9. #define  EV_MSC                    0x04   
  10. #define  EV_SW                      0x05   
  11. #define  EV_LED                    0x11   
  12. #define  EV_SND                    0x12   
  13. #define  EV_REP                    0x14   
  14. #define  EV_FF                      0x15   
  15. #define  EV_PWR                    0x16   
  16. #define  EV_FF_STATUS                0x17   
  17. #define  EV_MAX                    0x1f   
  18. #define  EV_CNT                    (EV_MAX+1)   



 
 
input_handle_event:  由上面的input_event 调入进这个handle处理。这里会根据type进行分类处理:
[objc]  view plain  copy  
  1. static  void  input_handle_event(struct  input_dev  *dev,   
  2.                                       unsigned  int  type,  unsigned  int  code,  int  value)   
  3. {   
  4.         int  disposition  =  INPUT_IGNORE_EVENT;   //初始为不做处理   
  5.    
  6.         switch  (type)  {   
  7.    
  8.         case  EV_SYN:   
  9.                 switch  (code)  {   
  10.                 case  SYN_CONFIG:   
  11.                         disposition  =  INPUT_PASS_TO_ALL;    
  12.                         break;    
  13.    
  14.                 case  SYN_REPORT:   
  15.                         if  (!dev-> sync)  {   
  16.                                 dev-> sync  =  true;    
  17.                                 disposition  =  INPUT_PASS_TO_HANDLERS;    
  18.                         }   
  19.                         break;    
  20.    
  21. ...   
  22.    
  23.         case  EV_KEY:   
  24.    
  25.                 if  (is_event_supported(code,  dev-> keybit,  KEY_MAX)  & &     //按键code是否被keybit支持   
  26.                         !!test_bit(code,  dev-> key)  !=  value)  {    //key是键盘当前所有键状态,测试code对应键状态,value传来事件的按键状态。此句表示按键状态应有变化   
  27.    
  28.                         if  (value  !=  2)  {   
  29.                                 __change_bit(code,  dev-> key);     //改变key的值以改变按键状态。   
  30.                                 if  (value)   
  31.                                         input_start_autorepeat(dev,  code);     //如果按键值为按下,则开始重复按键操作。具体会不会重复,input_start_autorepeat还会根据evbit中有没有置位重复事件等判断。   
  32.                                 else   
  33.                                         input_stop_autorepeat(dev);   //如果是松开按键则应停止重复按键相关操作。   
  34.                         }   
  35.    
  36.                         disposition  =  INPUT_PASS_TO_HANDLERS;    
  37.                 }   
  38.                 break;    
  39.    
  40. ...   
  41.    
  42.         case  EV_ABS:   
  43.                 if  (is_event_supported(code,  dev-> absbit,  ABS_MAX))    //同上面一样看是否支持   
  44.                         disposition  =  input_handle_abs_event(dev,  code,  & value);     //这个函数可以跟进去看,是做为筛选的,第一次是不会返回INPUT_IGNORE_EVENT  ,后面如果有跟上次相同的ABS坐标就会被过滤掉,返回IGNORE   
  45. //                err("jscese  display  disposition  vlue  ==0x%x,code==0x%x,  value=https://www.songbingjia.com/android/= 0x%x/n",disposition,code,value);    
  46.                 break;    
  47.    
  48. ...   
  49.    
  50.       }   
  51.    
  52.         if  (disposition  !=  INPUT_IGNORE_EVENT  & &   type  !=  EV_SYN)   
  53.                 dev-> sync  =  false;    
  54.    
  55.         if  ((disposition  &   INPUT_PASS_TO_DEVICE)  & &   dev-> event)   
  56.                 dev-> event(dev,  type,  code,  value);      
  57.    
  58.         if  (disposition  &   INPUT_PASS_TO_HANDLERS)   
  59.                 input_pass_event(dev,  type,  code,  value);     //更深一步调用  ,最终都是  调用到  event(**)方法   
  60.    
  61. }   



这里先记录整个输入系统从设备驱动到上层的关系,以及从kernel中的驱动调用到input系统中的传递过程,虽然看到调用了input.c中的一些函数传递,但是对input核心还是没多少概念,
下篇解析记录一下input这个核心模块~
【Linux/Android——输入子系统input_event传递】 

    推荐阅读