博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
input 子系统(五) 事件上报及监听
阅读量:4285 次
发布时间:2019-05-27

本文共 4132 字,大约阅读时间需要 13 分钟。

上报流程

事件的生产者 是 input 设备驱动 // 还可能是 用户空间通过write接口 上报的事件,这个可以忽略不计.途径 input.c(input core),到达 handler,然后由handler 提供给消费者.事件的生产者可以看做都是 设备驱动 ,但是消费者 不一定是 应用程序,可能是 kernel 其他模块,例如 key input 的消费者可以是 console subsystem

input subsystem1

input subsystem2

  • 驱动中的上报
input_report_key(button_dev, KEY_POWER,1);    input_report_key(button_dev, KEY_POWER,0);    input_sync(button_dev);
  • 上报流程
evdev 监听之前 和 监听之后 ,上报流程不一样, 区别 在 if (handle->open)监听之前, (handle->open) 为 假,不会传送到 handler监听之后, (handle->open) 为 真,  会传送到 handler input_report_key // 这一句 调用 在 驱动文件里面,但是 实现在 include/linux/input.h --------------------- // 往下 为 input core 的实现(input.c)    input_event(dev, EV_KEY, code, !!value); // 检查dev 是否支持该事件        input_handle_event(dev, type, code, value);            if (disposition & INPUT_PASS_TO_HANDLERS){
// 一般 report 都会进 // 存储每一次上报事件 } if (disposition & INPUT_FLUSH) {
// 如果 sync 到来 // input_pass_values input_to_handler list_for_each_entry_rcu(handle, &dev->h_list, d_node) if (handle->open) {
// 一定要注意,这个是handle ,还有一个 handler ,下两行会提到 ,在 open /dev/input/eventX 事,才会将 evdev对应的handle->open ++ ,该值初始化为0 input_to_handler(handle, vals, count); // 执行一次 , 这一次 是 kbd 的 event---------------------------------------//往下为 handler 的实现 evdev.c 或者 其他 handler } } 上文代码重点讲解: list_for_each_entry_rcu(handle, &dev->h_list, d_node) 这个会遍历 该 device 的 handle , 每匹配一次(该 device 和 handler) ,就会产生一个handle 一般至少会有一个handle ,就是 device 和 evdev handler 匹配产生的handler demo 中产生了两次匹配 1. device 和 evdev handler ,产生了handle 1 2. device 和 kbd handler , 产生了 handle 2 然后会分别检查 handle->open 1. handle 1 在 设备被监听之前, (handle->open)为假,在监听之后,(handle->open)被加1,为真 2. handle 2 (handle->open) 为 真 然后 调用 input_to_handler 1. handle1 对应的 不会调用 input_to_handler 2. handle2 对应的 会调用 input_to_handlerinput_to_handler(handle, vals, count); // 执行两次 handler->events //如果handler实现了handler->events,则优先调用 handler->events ,否则,调用 handler->event---------------------------------------//往下为 handler 的实现 evdev.c evdev_events // 这里分析 evdev handler evdev_pass_values static void __pass_event(struct evdev_client *client,const struct input_event *event) client->tail = (client->head - 2) & (client->bufsize - 1); client->buffer[client->tail].time = event->time; client->buffer[client->tail].type = EV_SYN; client->buffer[client->tail].code = SYN_DROPPED; client->buffer[client->tail].value = 0; client->packet_head = client->tail; if (wakeup) wake_up_interruptible(&evdev->wait);

监听流程

  • open
// 缓冲区 由 struct evdev_client *client; 管理 , struct evdev_client *client; 中有 buffer 成员// struct evdev_client *client; 由 rcu 链表管理.evdev_open    unsigned int size = sizeof(struct evdev_client) + bufsize * sizeof(struct input_event); // 计算环形队列缓冲区大小    client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); // 申请缓冲区 // client 中 有 buffer 成员    evdev_attach_client(evdev, client); // 将 client 串入链表        list_add_tail_rcu(&client->node, &evdev->client_list);    file->private_data = client;        evdev_open_device        handle->open ++;        open 了之后,建立了缓冲区.建立缓冲区 ,64 字节    这个buffer的作用是,上层OPEN了此节点,但是没有读取此节点的数据的时候,会保存到该缓冲区        在open 之前,evdev handler 就没有接收到 事件,事件消亡在 input.c
  • poll
- 阻塞流程evdev_poll    poll_wait(file, &evdev->wait, wait);- 唤醒流程evdev_pass_values    if (v->type == EV_SYN && v->code == SYN_REPORT)        wakeup = true;    if (wakeup)         wake_up_interruptible(&evdev->wait);
  • read
static ssize_t evdev_read(struct file *file, char __user *buffer,size_t count, loff_t *ppos)     struct evdev *evdev = client->evdev;    evdev_fetch_next_event(client, &event)        *event = client->buffer[client->tail++];    input_event_to_user(buffer + read, &event)

转载地址:http://rxigi.baihongyu.com/

你可能感兴趣的文章
DOM笔记(三):Element接口和HTMLElement接口
查看>>
DOM笔记(四):HTML 5 DOM复杂数据类型
查看>>
DOM笔记(五):JavaScript的常见事件和Ajax小结
查看>>
DOM笔记(六):怎么进行JQuery扩展?
查看>>
搜索和网页排名的数学原理
查看>>
DOM笔记(八):JavaScript执行环境和垃圾收集
查看>>
响应式下的下拉菜单
查看>>
DOM笔记(九):引用类型、基本包装类型和单体内置对象
查看>>
也谈学习
查看>>
DOM笔记(十):JavaScript正则表达式
查看>>
如何高效编写可维护代码?
查看>>
DOM笔记(十一):JavaScript对象的基本认识和创建
查看>>
DOM笔记(十二):又谈原型对象
查看>>
DOM笔记(十三):JavaScript的继承方式
查看>>
CSS:响应式下的折叠菜单(条纹式)
查看>>
响应式设计三部曲
查看>>
45种Javascript技巧大全
查看>>
PDO学习笔记
查看>>
MarkDown语法
查看>>
Linux的文件权限
查看>>