linux设备驱动(14)input子系统(三)数据上报事件流程详解

分析一下input事件上报流程。

1.可以看系统提供了很多来上报各种信息的函数(适用,键盘,鼠标,触摸屏等各种上报信息)它们都是掉用同一的接口input_enent来实现的。

定义位于:include\linux\input.h

 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);//注意这里value是两次取反,输入给input_event的只可能是0或1
 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 }
15 
16 static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
17 {
18     input_event(dev, EV_FF_STATUS, code, value);
19 }
20 
21 static inline void input_report_switch(struct input_dev *dev, unsigned int code, int value)
22 {
23     input_event(dev, EV_SW, code, !!value);
24 }
25 
26 static inline void input_sync(struct input_dev *dev)
27 {
28     input_event(dev, EV_SYN, SYN_REPORT, 0);
29 }
30 
31 static inline void input_mt_sync(struct input_dev *dev)
32 {
33     input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
34 }

2input_event的实现

 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     /*调用 is_event_supported()函数检查输入设备是否支持该事件*/
23     if (is_event_supported(type, dev->evbit, EV_MAX)) {
24 
25         spin_lock_irqsave(&dev->event_lock, flags);
26         input_handle_event(dev, type, code, value);
27         spin_unlock_irqrestore(&dev->event_lock, flags);
28     }
29 }

 

1 static inline int is_event_supported(unsigned int code,
2                      unsigned long *bm, unsigned int max)
3 {
4     return code <= max && test_bit(code, bm);
5 }

3 input_handle_event

 1 static void input_handle_event(struct input_dev *dev,
 2                    unsigned int type, unsigned int code, int value)
 3 {
 4     int disposition;
 5  /*定义了一个 disposition 变量,该变量表示使用什么样的方式处理事件。此处初始化为 INPUT_IGNORE_EVENT,表示如果后面没有对该变量重新赋值,则忽略这个事件*/
 6     disposition = input_get_disposition(dev, type, code, &value);
 7 
 8     if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
 9         dev->event(dev, type, code, value);
10 
11     if (!dev->vals)
12         return;
13 
14     if (disposition & INPUT_PASS_TO_HANDLERS) {
15         struct input_value *v;
16 
17         if (disposition & INPUT_SLOT) {
18             v = &dev->vals[dev->num_vals++];
19             v->type = EV_ABS;
20             v->code = ABS_MT_SLOT;
21             v->value = dev->mt->slot;
22         }
23 
24         v = &dev->vals[dev->num_vals++];
25         v->type = type;
26         v->code = code;
27         v->value = value;
28     }
29 
30     if (disposition & INPUT_FLUSH) {
31         if (dev->num_vals >= 2)
32             input_pass_values(dev, dev->vals, dev->num_vals);
33         dev->num_vals = 0;
34     } else if (dev->num_vals >= dev->max_vals - 2) {
35         dev->vals[dev->num_vals++] = input_value_sync;
36         input_pass_values(dev, dev->vals, dev->num_vals);
37         dev->num_vals = 0;
38     }
39 
40 }

4 input_pass_values

 1 /*
 2  * Pass values first through all filters and then, if event has not been
 3  * filtered out, through all open handles. This function is called with
 4  * dev->event_lock held and interrupts disabled.
 5  */
 6 static void input_pass_values(struct input_dev *dev,
 7                   struct input_value *vals, unsigned int count)
 8 {
 9     struct input_handle *handle;
10     struct input_value *v;
11 
12     if (!count)
13         return;
14 
15     rcu_read_lock();
16 
17     handle = rcu_dereference(dev->grab);
18     if (handle) {
19         count = input_to_handler(handle, vals, count);
20     } else {
21         list_for_each_entry_rcu(handle, &dev->h_list, d_node)
22             if (handle->open)
23                 count = input_to_handler(handle, vals, count);
24     }
25 
26     rcu_read_unlock();
27 
28     add_input_randomness(vals->type, vals->code, vals->value);
29 
30     /* trigger auto repeat for key events */
31     for (v = vals; v != vals + count; v++) {
32         if (v->type == EV_KEY && v->value != 2) {
33             if (v->value)
34                 input_start_autorepeat(dev, v->code);
35             else
36                 input_stop_autorepeat(dev);
37         }
38     }
39 }

5 input_to_handler

 1 /*
 2  * Pass event first through all filters and then, if event has not been
 3  * filtered out, through all open handles. This function is called with
 4  * dev->event_lock held and interrupts disabled.
 5  */
 6 static unsigned int input_to_handler(struct input_handle *handle,
 7             struct input_value *vals, unsigned int count)
 8 {
 9     struct input_handler *handler = handle->handler;
10     struct input_value *end = vals;
11     struct input_value *v;
12 
13     for (v = vals; v != vals + count; v++) {
14         if (handler->filter &&  /*看handler要不要进行再次筛选,通常evdev和mousedev等都是不需要进行筛选了*/
15             handler->filter(handle, v->type, v->code, v->value))
16             continue;
17         if (end != v)
18             *end = *v;
19         end++;
20     }
21 
22     count = end - vals;
23     if (!count)
24         return 0;
25     /*真正的调用handler里面的event或者events向应用程序上报数据*/
26     if (handler->events)
27         handler->events(handle, vals, count);
28     else if (handler->event)
29         for (v = vals; v != end; v++)
30             handler->event(handle, v->type, v->code, v->value);
31 
32     return count;
33 }

具体的handler,以evdev为例分析的。见上节。

 

参考博文:
https://blog.csdn.net/qq_16777851/java/article/details/81272843

posted @ 2020-05-23 13:40  Action_er  阅读(1099)  评论(0编辑  收藏  举报