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. unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
  89. unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
  90. unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
  91. unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
  92. unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
  93. unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
  94. unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
  95. unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
  96. unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
  97. unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
  98. unsigned int hint_events_per_packet;
  99. unsigned int keycodemax;
  100. unsigned int keycodesize;
  101. voidvoid *keycode;
  102. int (*setkeycode)(struct input_dev *dev,
  103. const struct input_keymap_entry *ke,
  104. unsigned intint *old_keycode);
  105. int (*getkeycode)(struct input_dev *dev,
  106. struct input_keymap_entry *ke);
  107. struct ff_device *ff;
  108. unsigned int repeat_key;
  109. struct timer_list timer;
  110. int rep[REP_CNT];
  111. struct input_mt_slot *mt;
  112. int mtsize;
  113. int slot;
  114. int trkid;
  115. struct input_absinfo *absinfo;
  116. unsigned long key[BITS_TO_LONGS(KEY_CNT)];
  117. unsigned long led[BITS_TO_LONGS(LED_CNT)];
  118. unsigned long snd[BITS_TO_LONGS(SND_CNT)];
  119. unsigned long sw[BITS_TO_LONGS(SW_CNT)];
  120. int (*open)(struct input_dev *dev);
  121. void (*close)(struct input_dev *dev);
  122. int (*flush)(struct input_dev *dev, struct file *file);
  123. int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
  124. struct input_handle __rcu *grab;
  125. spinlock_t event_lock;
  126. struct mutex mutex;
  127. unsigned int users;
  128. bool going_away;
  129. bool sync;
  130. struct device dev;
  131. struct list_head    h_list;
  132. struct list_head    node;
  133. };

我解释可能还会误导,源码上面的注释是最好的解释,都是描述一个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. if (!type->read_data(usbtouch, pkt))
  9. return;
  10. input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch); // 上报触摸类型 。touch为按下
  11. if (swap_xy) {
  12. input_report_abs(usbtouch->input, ABS_X, usbtouch->y);
  13. input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);
  14. } else {
  15. input_report_abs(usbtouch->input, ABS_X, usbtouch->x);
  16. input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); // 上报绝对坐标值
  17. }
  18. if (type->max_press)
  19. input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);
  20. input_sync(usbtouch->input);   // 同步操作
  21. }

可以看到通过 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. static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)
  6. {
  7. input_event(dev, EV_REL, code, value);
  8. }
  9. static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
  10. {
  11. input_event(dev, EV_ABS, code, value);
  12. }

可以看到不同的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. if (is_event_supported(type, dev->evbit, EV_MAX)) {  //判断是否是注册时的event类型,驱动probe时注册input_dev时设置了能响应的event类型
  23. spin_lock_irqsave(&dev->event_lock, flags); //自旋锁枷锁
  24. add_input_randomness(type, code, value);
  25. input_handle_event(dev, type, code, value);  //进一步处理传上来的这个 event
  26. spin_unlock_irqrestore(&dev->event_lock, flags);//解锁
  27. }
  28. }

可以看到在这里首先就是过滤了事件类型,这个也是在usbtouchscreen中的probe中初始化过的!

类型有如下几种:

[objc] view plain copy

  1. /*
  2. * Event types
  3. */
  4. #define EV_SYN          0x00
  5. #define EV_KEY          0x01
  6. #define EV_REL          0x02
  7. #define EV_ABS          0x03
  8. #define EV_MSC          0x04
  9. #define EV_SW           0x05
  10. #define EV_LED          0x11
  11. #define EV_SND          0x12
  12. #define EV_REP          0x14
  13. #define EV_FF           0x15
  14. #define EV_PWR          0x16
  15. #define EV_FF_STATUS        0x17
  16. #define EV_MAX          0x1f
  17. #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. switch (type) {
  6. case EV_SYN:
  7. switch (code) {
  8. case SYN_CONFIG:
  9. disposition = INPUT_PASS_TO_ALL;
  10. break;
  11. case SYN_REPORT:
  12. if (!dev->sync) {
  13. dev->sync = true;
  14. disposition = INPUT_PASS_TO_HANDLERS;
  15. }
  16. break;
  17. ...
  18. case EV_KEY:
  19. if (is_event_supported(code, dev->keybit, KEY_MAX) &&  //按键code是否被keybit支持
  20. !!test_bit(code, dev->key) != value) {  //key是键盘当前所有键状态,测试code对应键状态,value传来事件的按键状态。此句表示按键状态应有变化
  21. if (value != 2) {
  22. __change_bit(code, dev->key);  //改变key的值以改变按键状态。
  23. if (value)
  24. input_start_autorepeat(dev, code);  //如果按键值为按下,则开始重复按键操作。具体会不会重复,input_start_autorepeat还会根据evbit中有没有置位重复事件等判断。
  25. else
  26. input_stop_autorepeat(dev); //如果是松开按键则应停止重复按键相关操作。
  27. }
  28. disposition = INPUT_PASS_TO_HANDLERS;
  29. }
  30. break;
  31. ...
  32. case EV_ABS:
  33. if (is_event_supported(code, dev->absbit, ABS_MAX))  //同上面一样看是否支持
  34. disposition = input_handle_abs_event(dev, code, &value);  //这个函数可以跟进去看,是做为筛选的,第一次是不会返回INPUT_IGNORE_EVENT ,后面如果有跟上次相同的ABS坐标就会被过滤掉,返回IGNORE
  35. //        err("jscese display disposition vlue ==0x%x,code==0x%x, value== 0x%x\n",disposition,code,value);
  36. break;
  37. ...
  38. }
  39. if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
  40. dev->sync = false;
  41. if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
  42. dev->event(dev, type, code, value);
  43. if (disposition & INPUT_PASS_TO_HANDLERS)
  44. input_pass_event(dev, type, code, value);  //更深一步调用 ,最终都是 调用到 event(**)方法
  45. }

这里先记录整个输入系统从设备驱动到上层的关系,以及从kernel中的驱动调用到input系统中的传递过程,虽然看到调用了input.c中的一些函数传递,但是对input核心还是没多少概念,

下篇解析记录一下input这个核心模块~

时间: 2024-11-05 09:33:22

Linux/Android——输入子系统input_event传递 (二)【转】的相关文章

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

在前文Linux/Android--usb触摸屏驱动 - usbtouchscreen中记录了如何在kernel中添加input device 类型为touchscreen的驱动, 这在整个输入体系中是最下层的设备驱动部分,往上一层就是linux内核的管理驱动input系统,kernel中的源码位置:/kernel/drivers/input/input.c 撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42099381 到目前

Linux/Android——input子系统核心 (三)【转】

本文转载自:http://blog.csdn.net/jscese/article/details/42123673 之前的博客有涉及到linux的input子系统,这里学习记录一下input模块. input子系统,作为管理输入设备与系统进行交互的中枢,任何的输入设备驱动都要通过input向内核注册其设备, 常用的输入设备也就是鼠标,键盘,触摸屏. 稍微细分一点整个输入体系,就是 硬件驱动层,input核心中转层,事件处理层.层次之间传递都以event事件的形式,这其中input连接上下层,分

Linux/Android——input子系统核心

之前的博客有涉及到linux的input子系统,这里学习记录一下input模块. input子系统,作为管理输入设备与系统进行交互的中枢,任何的输入设备驱动都要通过input向内核注册其设备, 常用的输入设备也就是鼠标,键盘,触摸屏. 稍微细分一点整个输入体系,就是 硬件驱动层,input核心中转层,事件处理层.层次之间传递都以event事件的形式,这其中input连接上下层,分别提供接口. 之前有分析usbtouchscreen的驱动,也就是硬件驱动部分,这里简单记录一下input核心中转处理

linux input输入子系统应用分析

输入设备(如按键.键盘.触摸屏.鼠标等)是典型的字符设备,其一般的工作机理是底层在按键.触摸等动作发送时产生一个中断(或驱动通过timer定时查询),然后CPU通过SPI.I2 C或外部存储器总线读取键值.坐标等数据,放入1个缓冲区,字符设备驱动管理该缓冲区,而驱动的read()接口让用户可以读取键值.坐标等数据. 显然,在这些工作中,只是中断.读值是设备相关的,而输入事件的缓冲区管理以及字符设备驱动的file_operations接口则对输入设备是通用的.基于此,内核设计了输入子系统,由核心层

linux input输入子系统分析《四》:input子系统整体流程全面分析

1      input输入子系统整体流程 本节分析input子系统在内核中的实现,包括输入子系统(Input Core),事件处理层(Event Handler)和设备驱动层.由于上节代码讲解了设备驱动层的写法,因此在开头部分会从设备驱动层做为线索,分析输入子系统和事件处理层是如何配合的,最后从用户角度出发,从"/dev/input/*"接口如何使用输入子系统提供的服务. 既然需要详细分析,有一个这样的流程图能够帮助我们在被绕进代码的过程中,找到出口,你能够知道你现在位于代码框架的什

输入子系统分析 (二)

输入子系统是由输入子系统核心层( Input Core ),驱动层和事件处理层(Event Handler)三部份组成.一个输入事件,如鼠标移动,键盘按键按下,joystick的移动等等通过 input driver -> Input core -> Event handler -> userspace 到达用户空间传给应用程序. input子系统的3个基本的数据结构struct input_dev { struct list_head    h_list;    //h_list是一个

Android 输入子系统

输入子系统模型: 输入子系统由设备驱动层(input device driver),核心层(input core)和事件驱动层(event driver)三部份组成. 任何一次输入事件, 如鼠标移动, 按键按下, 都需要通过InputDeviceDriver- >InputCore- >EventDrive才能到达用 户 空间的应用程序. 设备驱动层:将底层的硬件输入转化为统一事件型式, 向输入核心( InputCore)汇报.v 输入核心层:为设备驱动层提供输入设备注册与操作接口 , 如:为

linux 的 输入子系统 与 平台设备系统个人理解

首先 ,   输入子系统跟平台设备之间没有必然联系 输入子系统,默认主设备号13,自己使用的时候要定义次设备号 ,输入子系统 ,完成一些复杂的输入功能  ,鼠标,键盘,等等输入.是一些输入设备的合集 平台设备驱动 ,是一种程序框架的,一种方式,将设备驱动的硬件配置,和软件处理分开来写. 具体知道套路就可以了,不用深究 原文地址:https://www.cnblogs.com/niuxiaojie521/p/11127257.html

android 音频子系统-Surfaceflinger(二)

音频系统的核心:AudioFlinger AudioFlinger为上层提供访问和管理音频的接口,同时通过hal来管理音频设备. AudioFlinger服务的启动: Framework/av/media/audioserver/main_audioserver.cpp int main(int argc __unused, char **argv){ AudioFlinger::instantiate(); AudioPolicyService::instantiate(); RadioSer