zoukankan      html  css  js  c++  java
  • 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 系统,先看一张网上的层次图,蛮不错的:
                   

             

    上一篇博客里面的 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== 0x%x ",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这个核心模块~

  • 相关阅读:
    java并发初探CountDownLatch
    java并发LockSupport
    java并发初探ReentrantWriteReadLock
    mysql视图初探
    mysql索引
    java并发AtomicIntegerFieldUpdater
    php7.* 新特性
    搜索引擎 对比
    2021-03-09 吐槽
    linux 进程&线程
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7808406.html
Copyright © 2011-2022 走看看