当你对 Linux 驱动程序或 USB 一无所知时编写一个基本的 Linux 设备驱动程序

几个月前购买了Nanoleaf Pegboard Desk Dock,它是带有 RGB LED 和小工具挂钩的 USB 集线器技术的最新成果,但仅支持 Windows 和 macOS 操作系统,需开发 Linux 驱动。

  • 过去的帖子中设置了带有 USB 透传的 Windows VM,并尝试逆向工程官方驱动,同时给供应商发消息询问协议规格,没想到 Nanoleaf 技术支持 4 小时内就回复,提供了 Desk Dock 及 RGB 灯带使用的协议完整描述,确认了部分发现,还得知一些其他小功能。
  • 今天基于(逆向工程的)协议尝试编写驱动,虽从未写过 Linux 设备驱动,也从未以除用户外的身份与 USB 设备交互。
  • 大多数 Linux 发行版自带lsusb工具可枚举系统连接的 USB 设备,运行后看到设备存在,但其识别是通过内核的通用驱动,因该设备的 RGB LED 无 HID 规范,内核虽识别并供电但不知如何处理,有两种选择:写遵循内核标准的驱动将每个 LED 作为 3 个设备暴露在/sys/class/leds下,或通过libusb写用户空间驱动。
  • 要在 Linux 上以非 root 身份操作 USB 设备需创建/etc/udev/rules.d/70-pegboard.rules文件,在 NixOS 中需自定义包定义规则并扩展services.udev.packages
  • 用 Rust 编写基本驱动,添加rusb crate 以绑定libusb,先获取设备句柄获取基本信息,然后要获取接口需先判断内核驱动是否活跃,若活跃则 detach 后再 claim 接口,发送数据时根据lsusb信息确定使用write_interruptOUT端点写数据,测试时让 pegboard 显示纯色红色,发现只写不读会导致固件崩溃,需在写后读取设备响应,之后为避免设备可能发送更多中断,使用std::thread::scope创建两个线程,一个写数据一个读数据,处理中断,但该设备有一些 quirks,如需要稳定的颜色帧流,颜色格式为 GRB 等,此小概念验证表明写简单设备驱动没那么难,50 行代码能做很多事,未来希望完善并分享。
阅读 11
0 条评论