【SUBJECT技术】探索 OpenHarmony libudev 设备热插拔机制

一、多模输入子系统设备热插拔事件来源

当前多模输入子系统处理设备热插拔事件的过程如图所示

现有多模输入子系统框架中,设备原始输入事件要经由 libinput 处理,封装成 libinput 的事件类型。多模输入子系统接收并处理 libinput 封装的事件。特别地,libinput 依赖 udev 获得输入设备热插拔事件的通知。udev 将监听热插拔事件、读取热插拔的设备信息,连同枚举已加载设备等接口实现封装成 libudev 共享库。libinput 通过 libudev 封装的这些功能接口与 udev 通信,因而在编译时多模输入模块需要链接到 libudev。

libinput 依赖的两个关键路径是设备节点“/dev/input/”和设备系统路径“/sys/class/input/”。系统路径可以通过设备节点关联得到。通过设备节点可获得设备支持的事件和属性,以及接收和发送输入事件。通过系统路径可以获得设备的详细信息。

libinput 依赖设备能力标记来分设备类型进行事件处理。这些标记是由 udevd 通过应用配置的规则计算得到的。

总结下来有几个关键点:
(1)libudev 是在 eudev 项目中实现的。
(2)多模输入子系统从 udevd 获知输入设备热插拔,而设备节点由 ueventd 创建。
(3)多模输入子系统依赖 udev 提供的信息包括:输入设备热插拔通知;输入设备节点路径;输入设备的能力标记。udev 支持广泛的设备类型,为此定义了一整套复杂的规则来处理设备热插拔事件。多模输入子系统只支持输入设备,我们可以通过简单的逻辑来获取这些信息。

二、判断设备类型

不同的输入设备支持不同的输入事件和属性的组合。

2.1 如触摸屏支持的事件

  Discriminator::DeviceType::TOUCHSCREEN, {
      .eventTypes {
        EV_KEY,
        EV_ABS,
      },
      .keys {
        BTN_TOUCH,
      },
      .abs {
        ABS_MT_TOUCH_MAJOR,
        ABS_MT_TOUCH_MINOR,
        ABS_MT_POSITION_X,
        ABS_MT_POSITION_Y,
        ABS_MT_TRACKING_ID,
        ABS_MT_PRESSURE,
        ......
      },
      .properties {
        INPUT_PROP_DIRECT,
      },
    }

2.2 鼠标支持的输入事件和属性

Discriminator::DeviceType::MOUSE, {
      .eventTypes {
        EV_KEY,
        EV_REL,
      },
      .keys {
        BTN_LEFT,
        BTN_RIGHT,
        BTN_MIDDLE
      },
      .rels {
        REL_X,
        REL_Y,
        REL_WHEEL
      }
    },

2.3 键盘支持的输入事件和属性

Discriminator::DeviceType::KEYBOARD,
    {
      .eventTypes {
        EV_KEY,
      },
      .keys {
        KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, 
        KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, KEY_Q, 
        KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I,
        KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE,
        KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S, KEY_D, KEY_F,
        KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
        KEY_LEFTSHIFT, KEY_BACKSLASH, KEY_Z, KEY_X,
        KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, KEY_COMMA, KEY_DOT,
        KEY_SLASH, KY_RIGHTSHIFT, KEY_LEFTALT, KEY_SPACE,
        KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6,
        KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_NUMLOCK,
        KEY_SCROLLLOCK, KEY_KP7, KEY_KP8, KEY_KP9, KEY_KPMINUS,
        KEY_KP4, KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1, KEY_KP2,
        KEY_KP3, KEY_KP0, KEY_KPDOT, KEY_F11, KEY_F12, ......
      },
    },

三、主要程序处理逻辑

3.1 libinput 初始化

3.2 热插拔事件处理

3.3 模块结构

3.4 接口列表 struct udev;

四、udevd 进程

4.1 udevd 是一个守护进程

udevd 启动时通过 netlink scoket 监听内核通知的设备热插拔事件:
src/udev/udevd.c:main()

当接收到内核发出的设备热插拔事件时,udevd 将事件加入事件队列,启动工作进程处理事件:
src/udev/udevd.c:main()

工作进程处理热插拔事件,应用配置的规则,执行处理例程,然后将处理后的事件转发给 libudev 事件监听者(libinput):
src/udev/udevd.c:worker_spawn()

libinput 依赖 udevd 处理过的事件进行设备识别。如果去掉规则匹配部分的逻辑,测试时 libinput 不能正常识别设备。参考日志:

4.2 udevd 规则处理逻辑

udevd 启动时会遍历预定的目录,寻找规则配置文件。udevd 逐个解析每个规则配置文件,形成一个规则项的数组。单个配置文件解析得到的规则项是按序连续排列的,其中第一项(如下图的蓝色项)记录了一些从相应规则配置文件解析得到的规则项的信息,包括规则项的个数等。从该配置文件解析得到的规则项紧接着按规则的类型顺序排列。这些规则项可分为两类,一类用来做匹配,另一类指示执行的动作。如下图所示:

应用规则时,单个规则配置文件中的所有规则项是作为一个整体考虑的。设备的属性应匹配所有的匹配项,才能应用后面的动作。

4.3 UDEV 鼠标标记

五、ueventd 进程

5.1 ueventd 是一个守护进程

它通过 netlink scoket 监听内核生成的 uevent 消息。当 ueventd 接收到 uevent 消息时,采取适当的动作来处理。典型的场景是当有设备热插/拔时,内核发送 uevent 事件通知用户端;ueventd 接收到此 uevent 事件,执行如创建/移除设备节点的动作。
系统正常启动后,ueventd 会超时退出。当有设备热插拔事件上报时,如果 udevd 进程未运行,则系统会拉起 ueventd 进程处理事件,创建设备节点。
OpenHarmony 的 ueventd 进程的代码在“/base/startup/init_lite/ueventd/”目录中。系统启动后,ueventd 通过 netlink scoket 监听内核发送的输入设备热插拔事件。

5.2 当前 ueventd 的实现支持“input”子系统事件的处理

参考日志:

5.3 ueventd 可接收并处理设备热插拔事件

测试时加载了两个虚拟触摸屏设备,uevent 响应并创建了设备节点,ueventd 输出日志:

5.4 测试插入键盘,uevent 创建了设备节点

参考日志:

5.5 测试插入鼠标,uevent 创建了设备节点

5.6 ueventd 的日志输出

5.7 一个问题是 ueventd 有监听超时时间设置

设备启动后 uevent 进程因超时而结束运行。如果去除 ueventd 的超时设置,ueventd 则保持运行:

5.8 另一个问题是 ueventd 的功能简单

未提供事件通知的接口和设备信息获取的接口,如果多模依赖 ueventd 实现设备热插拔,则需要增加实现这些接口。

六、各类型输入设备支持的事件和属性

6.1 键盘支持的事件类型和属性

6.2 鼠标支持的事件类型和属性

6.3 触摸屏支持的事件类型和属性

6.4 数位板支持的事件类型和属性

6.5 手写笔支持的事件类型和属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值