[经验分享] 【SUBJECT技术】探索 OpenHarmony libudev 设备热插拔机制 原创 精华

诚迈_雨哥 显示全部楼层 发表于 2024-1-28 16:34:48

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

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

wps1.png

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

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

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初始化

wps3.png

3.2 热插拔事件处理

wps4.png

3.3 模块结构

wps5.png

3.4 接口列表struct udev;

四、udevd进程

4.1 udevd是一个守护进程

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

wps14.png

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

wps15.png

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

wps16.jpg

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

wps17.png

wps18.png

wps19.png

wps20.png

4.2 udevd规则处理逻辑

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

wps21.png

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

4.3 UDEV鼠标标记

wps30.png

五、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”子系统事件的处理

参考日志:

wps31.png

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

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

wps32.png

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

参考日志:

wps33.png

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

wps34.png

5.6 ueventd的日志输出

wps35.png

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

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

wps36.png

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

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

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

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

wps37.jpg

wps38.jpg

wps39.jpg

wps40.jpg

wps41.jpg

wps42.jpg

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

wps43.jpg

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

wps44.jpg

wps45.jpg

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

wps46.jpg

wps47.jpg

wps48.jpg

wps49.jpg

wps50.jpg

wps51.jpg

wps51.jpg

wps52.jpg

wps53.jpg

wps54.jpg

wps55.jpg

wps56.jpg

wps57.jpg

wps58.jpg

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

wps59.jpg

wps60.jpg

wps61.jpg

wps62.jpg

wps63.jpg

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部