linux input 子系统详解

这次研究linux输入子系统

内核参考文档:linux_src_path/Documentation/input/input.txt

通过中断或者Timer定时查询将CPU通过SPI、I2C或外部储存器总线读取的键值,坐标等数据放入一个缓冲区,字符设备管理这个缓冲区, 驱动的read()接口让用户可以读取键值、坐标等数据。显然,中断、读取键值是与设备相关的,而输入事件 的缓冲区管理以及字符设备驱动的file_operations接口则对输入设备是通用的。所以设计了输入子系统。

 

层次分析    
    APP:    /dev/input/xxxx
            ----------------------------------
    kernel:   事件处理层  struct input_handler 
                          负责创建设备文件以及将上报的事件传递到用户空间。
                          evdev.c
            ----------------------------------
            input核心层
                        struct input_handle
                        提供相关结构体 + api 
                        input.c
            ----------------------------------
            input驱动层:
                      struct input_dev
                      input输入设备的驱动
            ----------------------------------
            hardware:   鼠标 键盘  key....

 通过 input driver -> Input core ->event handler -> userspace 到达用户空间传给应用程序。

驱动层:将底层的硬件输入转化为统一事件形式,向输入核心(Input Core)汇报。

驱动层主要操作
          1.struct input_dev my_dev = input_alloc_device();   分配
          2.input_register_device(my_dev);                             注册
              (1)list_add_tail(&dev->node, &input_dev_list);     将my_dev 添加到input_dev_list链表中
              (2)list_for_each_entry(dev, &input_dev_list, node)
                   input_attach_handler(dev, handler);               匹配input_dev 和 handler结构体 成功调用handler->connect函数

核心层  input.c    major=13 

作用:承上启下, 为驱动层 提供输入设备注册与操作接口,如:input_register_device;通知事件处理层对事件进行处理;在/Proc下产生相应的设备信息。

核心层主要功能:                                                                                                                                                                                1.提供核心API
          2.err = class_register(&input_class);     注册输入设备类
          3.err = register_chrdev(INPUT_MAJOR, "input", &input_fops);    申请设备号

 

 事件处理层   evdev.c

作用:主要是和用户空间交互。(Linux中在用户空间将所有的设备都当初文件来处理,由于在一般的驱动程序中都有提供fops接口,以及在/dev下会生成相应的设备文件node,这些操作在输入子系统中由事件处理层完成)。

事件处理层:处理事件
        1.input_register_handler(&evdev_handler);
            (1)list_add_tail(&handler->node, &input_handler_list);   将handler参加到 input_handler_list 链表中
            (2)list_for_each_entry(dev, &input_dev_list, node)      遍历input_dev_list链表中的struct input_dev结构体
          input_attach_handler(dev, handler);         匹配input_dev 和 handler结构体   成功调用evdev_handler->connect函数。

         handler->connect:
                    evdev->dev.devt = MKDEV(INPUT_MAJOR, minor);
                    evdev->dev.class = &input_class;
                    evdev->dev.parent = &dev->dev;
                    evdev->dev.release = evdev_free;
                    device_initialize(&evdev->dev);
                    error = input_register_handle(&evdev->handle);    //字符设备注册
                    cdev_init(&evdev->cdev, &evdev_fops);
                    evdev->cdev.kobj.parent = &evdev->dev.kobj;
                    error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
                    error = device_add(&evdev->dev);
                    
                    evdev_fops中  read函数  会有等待队列阻塞 ,直到驱动层调用input_event()函数,唤醒等待队列.

 应用层程序编写:
        (1)open:input的设备节点
        (2)read: 将input上报的事件存储起来,再解析
        (3)分析事件

Linux中输入设备的事件类型有
            EV_SYN 0x00 同步事件
            EV_KEY 0x01 按键事件,如KEY_VOLUMEDOWN
            EV_REL 0x02 相对坐标,   如shubiao上报的坐标
            EV_ABS 0x03 绝对坐标,如触摸屏上报的坐标
            EV_MSC 0x04 其它
            EV_LED 0x11 LED
            EV_SND 0x12 声音
            EV_REP 0x14 Repeat
            EV_FF 0x15 力反馈 
            ~~~~~~~~~~~~~~~~~~~~~~~~
            EV_PWR       电源
            EV_FF_STATUS   状态 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值