LINUX输入子系统

来源:互联网 发布:windows系统安装工具 编辑:程序博客网 时间:2024/05/29 09:18

一、前言

1 初识linux输入子系统

linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler)、输入子系统核心层(InputCore)和输入子系统设备驱动层。

对于输入子系统设备驱动层而言,主要实现对硬件设备的读写访问,中断设置,并把硬件产生的事件转换为核心层定义的规范提交给事件处理层。

对于核心层而言,为设备驱动层提供了规范和接口。设备驱动层只要关心如何驱动硬件并获得硬件数据(例如按下的按键数据),然后调用核心层提供的接口,核心层会自动把数据提交给事件处理层。

对于事件处理层而言,则是用户编程的接口(设备节点),并处理驱动层提交的数据处理。

对于linux输入子系统的框架结构如下图1所示: 
这里写图片描述

由上图所展现的内容就是linux输入子系统的分层结构。

/dev/input目录下显示的是已经注册在内核中的设备编程接口,用户通过open这些设备文件来打开不同的输入设备进行硬件操作。

事件处理层为不同硬件类型提供了用户访问及处理接口。例如当我们打开设备/dev/input/mice时,会调用到事件处理层的Mouse Handler来处理输入事件,这也使得设备驱动层无需关心设备文件的操作,因为Mouse Handler已经有了对应事件处理的方法。

输入子系统由内核代码drivers/input/input.c构成,它的存在屏蔽了用户到设备驱动的交互细节,为设备驱动层和事件处理层提供了相互通信的统一界面。

下图2简单描述了linux输入子系统的事件处理机制:

图2 linux输入子系统事件处理机制 
这里写图片描述 
由上图可知输入子系统核心层提供的支持以及如何上报事件到input event drivers。

二、如何查看输入子系统的信息

root@android:/ # cat /proc/bus/input/devices  cat /proc/bus/input/devices  I: Bus=0019 Vendor=0001 Product=0001 Version=0100  N: Name="rk29-keypad"  P: Phys=gpio-keys/input0  S: Sysfs=/devices/platform/rk29-keypad/input/input0  U: Uniq=  H: Handlers=kbd event0 keychord  B: PROP=0  B: EV=3  B: KEY=8000 100000 0 0 0  I: Bus=0019 Vendor=0001 Product=0001 Version=0100  N: Name="rkxx-remotectl"  P: Phys=gpio-keys/input0  S: Sysfs=/devices/platform/rkxx-remotectl/input/input1  U: Uniq=  H: Handlers=kbd event1 keychord  B: PROP=0  B: EV=3  B: KEY=c 70110 260000 0 0 0 20100 2000000 7800000 4000a800 1e16c0 19 78000000 10006ffc  I: Bus=0003 Vendor=0c45 Product=1109 Version=0100  N: Name="coocaa Device coocaa Wireless Device"  P: Phys=usb-usb20_host-1.3/input2  S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.3/2-1.3:1.2/input/input2  U: Uniq=  H: Handlers=sysrq kbd event2 keychord  B: PROP=0  B: EV=12001b  B: KEY=10000 7 ff800000 7ff febeffdf ffefffff ffffffff fffffffe  B: ABS=700 0  B: MSC=10  B: LED=1f  I: Bus=0003 Vendor=0c45 Product=1109 Version=0100  N: Name="coocaa Device coocaa Wireless Device"  P: Phys=usb-usb20_host-1.3/input3  S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.3/2-1.3:1.3/input/input3  U: Uniq=  H: Handlers=sysrq kbd event3 keychord  B: PROP=0  B: EV=12001f  B: KEY=4837fff 72ff32d bf544446 0 0 1 30f90 8b17c007 ffe77bfa d941dfff febeffdf ffefffff ffffffff fffffffe  B: REL=40  B: ABS=ffffff01 0  B: MSC=10  B: LED=1f  I: Bus=0003 Vendor=0c45 Product=1109 Version=0100  N: Name="coocaa Device coocaa Wireless Device"  P: Phys=usb-usb20_host-1.3/input4  S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.3/2-1.3:1.4/input/input4  U: Uniq=  H: Handlers=event4  B: PROP=0  B: EV=17  B: KEY=1f0000 0 0 0 0 0 0 0 0  B: REL=103  B: MSC=10  I: Bus=0003 Vendor=0c45 Product=1109 Version=0100  N: Name="coocaa Device coocaa Wireless Device"  P: Phys=usb-usb20_host-1.3/input5  S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.3/2-1.3:1.5/input/input5  U: Uniq=  H: Handlers=sysrq kbd event5 keychord  B: PROP=0  B: EV=12001f  B: KEY=4837fff 72ff32d bf544446 0 0 1 30f90 8b17c007 ffff7bfa d941dfff febeffdf ffefffff ffffffff fffffffe  B: REL=40  B: ABS=1 0  B: MSC=10  B: LED=1f  I: Bus=0003 Vendor=093a Product=2510 Version=0111  N: Name="PixArt USB Optical Mouse"  P: Phys=usb-usb20_host-1.2.4/input0  S: Sysfs=/devices/platform/usb20_host/usb2/2-1/2-1.2/2-1.2.4/2-1.2.4:1.0/input/input7  U: Uniq=  H: Handlers=event6  B: PROP=0  B: EV=17  B: KEY=70000 0 0 0 0 0 0 0 0  B: REL=103  B: MSC=10  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

三、输入子系统的eventx文件是如何生成

源码目录在:drivers/input/evdev.c

/* * Create new evdev device. Note that input core serializes calls * to connect and disconnect so we don't need to lock evdev_table here. */static int evdev_connect(struct input_handler *handler, struct input_dev *dev,             const struct input_device_id *id){    struct evdev *evdev;    int minor;    int error;    for (minor = 0; minor < EVDEV_MINORS; minor++)        if (!evdev_table[minor])            break;    if (minor == EVDEV_MINORS) {        pr_err("no more free evdev devices\n");        return -ENFILE;    }    evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);    if (!evdev)        return -ENOMEM;    INIT_LIST_HEAD(&evdev->client_list);    spin_lock_init(&evdev->client_lock);    mutex_init(&evdev->mutex);    init_waitqueue_head(&evdev->wait);    dev_set_name(&evdev->dev, "event%d", minor);    evdev->exist = true;    evdev->minor = minor;    evdev->handle.dev = input_get_device(dev);    evdev->handle.name = dev_name(&evdev->dev);    evdev->handle.handler = handler;    evdev->handle.private = evdev;    evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + 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);    if (error)        goto err_free_evdev;    error = evdev_install_chrdev(evdev);    if (error)        goto err_unregister_handle;    error = device_add(&evdev->dev);    if (error)        goto err_cleanup_evdev;    return 0; err_cleanup_evdev:    evdev_cleanup(evdev); err_unregister_handle:    input_unregister_handle(&evdev->handle); err_free_evdev:    put_device(&evdev->dev);    return error;}
原创粉丝点击