Linux输入子系统

驱动程序

1. 申请设备,设置input设备支持的事件类型(比如EV_ABS,EV_KEY)

input_allocate_device函数分配了一个 input_dev 结构体

            button_dev = input_allocate_device(); 
            button_dev->evbit[0] = BIT_MASK(EV_KEY);/*设置按键信息*/  
            button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);  
2.注册中断处理函数

例如键盘设备需要编写按键的抬起、放下,触摸屏设备需要编写按下、抬起、绝对移动,鼠标设备需要编写单击、抬起、相对移动,并且需要在必要的时候提交硬件数据(键值/坐标/状态等等)

中断程序中上报输入事件

 input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1); 

"input_dev->name 就是给上层open 的 /dev/input/enventX"
"/sys/class/input/inputX/"; --- name ---eventX

3.将输入设备注册到输入子系统中

input_register_device()函数是输入子系统核心(input core)提供的函数。该函数将input_dev结构体注册到输入子系统核心中,(注册过程是个匹配过程)

        input_register_device
        => input_attach_handler
        =>input_match_device

匹配过程

static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
 {
      const struct input_device_id *id;                //   定义一个input_device_id 的指针
     int error;
 
     id = input_match_device(handler, dev);   //  通过这个函数进行handler与input设备的匹配工作
      if (!id)
          return -ENODEV;
  
     error = handler->connect(handler, dev, id);  //  匹配成功则调用 handler 中的 connect 函数进行连接
     if (error && error != -ENODEV)
         printk(KERN_ERR
             "input: failed to attach handler %s to device %s, "
             "error: %d\n",
             handler->name, kobject_name(&dev->dev.kobj), error);
 
     return error;
过滤

采用EV_ABS方式传送,input机制会过滤掉相同的值,所以会出现丢值的现象。如果采用EV_REL方式就可以解决这个问题了
disposition = input_handle_abs_event(dev, code, &value);//这里调用的input_handle_abs_event会将上次值和这次值相同的事件过滤掉

用户程序

设备的打开和读写

用户程序通过Input Handler层创建的设备节点的Open,read,write等函数打开和读写输入设备。

系统中有哪些输入设备

add device 2: /dev/input/event1 gsensor

name: "lsm303dlhc_mag"

add device 4: /dev/input/event4 keyboard

name: "7x27a_kp"
add device 5: /dev/input/event3 tp

name: "ft5x0x_ts"

add device 6: /dev/input/event2 psensor 和lsensor

name: "tmd2771x"

输入子系统的架构

分为三层
1、核心层 input.c

2、设备层 Gpio_keys.c
设备层涉及底层硬件

3、事件处理层 Evdev.c

事件处理层为纯软件的东西,事件处理层文件主要是用来支持输入设备并与用户空间交互,,这部分代码一般不需要我们自己去编写,因为Linux内核已经自带有一些事件处理器,可以支持大部分输入设备,比如evdev.c、mousedev.c、joydev.c等。

1)当我们按下鼠标左键的时候就会触发中断(中断是早就注册好的),
就会去执行中断所绑定的处理函数,在函数中就会去读取硬件寄存器来判断按下的是哪个按键和状态

2)将按键信息上报给input core层

3) input core层处理好了之后就会上报给input event层

4)在这里会将我们的输入事件封装成一个input_event结构体放入一个缓冲区中

5)应用层read就会将缓冲区中的数据读取出去。


clipboard.png
clipboard1.png
clipboard2.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1:InputChannel提供函数创建底层的Pipe对象 2: 1)客户端需要新建窗口 2)new ViewRo...
    自由人是工程师阅读 10,899评论 0 18
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 7,918评论 0 3
  • 本文开启 linux 内核 V4L2 框架部分的学习之旅,本文仅先对 V4L2 的框架做一个综述性的概括介绍,然后...
    yellowmax阅读 12,297评论 0 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,120评论 19 139
  • Ji Zhi Xu is my favourit person. He likes play EV3. He ca...
    5545任天曦阅读 1,567评论 0 1

友情链接更多精彩内容