第九周周报(9.7-9.12)
本周工作集中在 USB 设备自动匹配和 UVC 摄像头发现链路。USB host 在完成设备枚举、读取设备和配置描述符后,现在可以生成统一的 device/interface 描述对象,使用注册的 USB ID 表匹配驱动,并在 probe 成功后记录 interface 的逻辑认领状态。基于这条链路,为板上的 Suyin HD Camera 增加了一个名为 uvcvideo 的薄驱动,用于验证 UVC 设备的自动发现和匹配。
本周工作概览
- 在
crab-usb中增加统一的 USB interface driver binding 机制。 - 将 VID/PID、interface class、subclass 和 protocol 封装为
UsbId匹配规则,None表示通配符。 - 增加
UsbDevice、UsbInterface、UsbDriver、UsbIdEntry和UsbDriverRegistry,串起枚举、匹配、probe、claim 和 disconnect 生命周期。 - 在
ax-driver中增加uvcvideo薄驱动,精确匹配1e45:8022的 Video Control 和 Video Streaming interface。 - 调整 QEMU RISC-V 配置,保留 QEMU monitor socket,便于 USB 测试和调试。
- 在 K3 板上验证 Suyin HD Camera 的端口连接、USB enumeration、两个 Video interface 匹配和逻辑认领。
USB 自动 probe 设计
USB host 端已经存在 xHCI 端口变化检测和设备枚举流程。本周没有改动 xHCI 的底层端口检测,而是把 driver binding 接到通用 USBHost::probe_changes() 入口,使 xHCI、DWC2、EHCI 和其他 host backend 可以复用同一套匹配逻辑。
当前调用链如下:
xHCI 检测 port connect
↓
USB enumeration
↓
AddressDevice / GET_DESCRIPTOR / SET_CONFIGURATION
↓
生成 UsbDevice 和 UsbInterface
↓
遍历 USB driver registry
↓
UsbId::matches()
↓
UsbDriver::probe(interface)
↓
probe 成功后 interface 记录 driver
UsbId 只保留当前最需要的字段:VID、PID、interface class、subclass 和 protocol。设备级字段从父级 UsbDevice 读取,class 相关字段从 UsbInterface 读取。这样既可以表达 UVC 的 class 匹配,也可以表达 CH340 一类的 VID/PID 匹配。
UsbDriverRegistry 使用扁平的 UsbIdEntry 列表保存 ID 到 driver 的关系。匹配成功并不立即认领,必须先执行 probe();如果 probe 返回错误,USB core 会继续尝试下一个匹配项。只有 probe 返回成功后,interface 才会记录绑定的 driver。设备断开时,host 根据设备逻辑 ID 找到已绑定的 interface,并调用 driver 的 disconnect 生命周期。
uvcvideo 薄驱动
本周在 ax-driver/src/usb/uvcvideo.rs 中加入了用于验证发现链路的薄驱动,driver 名称为 uvcvideo,ID 表覆盖该设备的两个 Video interface:
VID = 0x1e45
PID = 0x8022
Interface = 0x0e Video
Subclass = 0x01 Video Control
Protocol = wildcard
它在 USB host 创建时注册到 USBHost,因此首次拓扑扫描前就已经具备匹配规则。probe() 目前只输出设备 ID、interface 编号、alternate setting 和 endpoint 数量,然后完成逻辑 claim;它不会打开 live Device、不会直接 claim 底层 endpoint,也不会启动视频流。
现有 drivers/usb/usb-device/uvc 中的 crab-uvc 可以继续作为通用 UVC host-side 协议和视频流实现使用。它的 UvcDevice::new() 需要异步打开设备并取得独占 Device,同时要管理 Video Control 和 Video Streaming 两个 interface,因此不能直接塞入当前同步的 UsbDriver::probe(&UsbInterface) callback。后续需要单独设计 async probe、live device ownership、VC/VS 多 interface 管理、格式协商和 isochronous streaming 生命周期。
板端测试结果
在 K3 板上插入 Suyin HD Camera 后,USB host 检测到端口 4 的连接变化,完成 debounce、reset 和 high-speed device setup。随后两个 Video interface 都被 uvcvideo 匹配并逻辑认领:
root@starry:/root # [137.356351 0:40 crab_usb::backend::kmod::hub::device:173] Port 4 connection changed: true
[137.363140 0:40 crab_usb::backend::kmod::hub::device:188] Port 4 connection changed: connected=true, enabled=false
[137.374792 0:40 crab_usb::backend::kmod::hub::device:706] Handling connection on port 4, speed: Full
[137.385371 0:40 crab_usb::backend::kmod::hub::device:605] Starting debounce on port 4 (expected_connected: true)
[137.497377 0:40 crab_usb::backend::kmod::hub::device:627] Port 4 debounce stable (connected: true)
[137.504790 0:40 crab_usb::backend::kmod::hub::device:661] Resetting port 4
[137.613629 0:40 crab_usb::backend::kmod::hub::device:684] Port 4 reset complete
[137.619458 0:40 crab_usb::backend::kmod::hub::device:767] Port 4 enabled after 1 checks
[137.628813 0:40 crab_usb::backend::kmod::hub::device:726] Port 4 device ready: speed=High, enabled=true
[137.696570 0:40 crab_usb::driver:210] usb: interface 0 alt 0 matched driver uvcvideo
[137.702763 0:40 ax_driver::usb::uvcvideo:44] uvcvideo: logically claimed 1e45:8022 interface 0 alt 0 endpoints=1
[137.714402 0:40 crab_usb::driver:227] usb: interface 0 alt 0 claimed by uvcvideo
[137.723218 0:40 crab_usb::driver:210] usb: interface 1 alt 0 matched driver uvcvideo
[137.732385 0:40 ax_driver::usb::uvcvideo:44] uvcvideo: logically claimed 1e45:8022 interface 1 alt 0 endpoints=0
[137.744042 0:40 crab_usb::driver:227] usb: interface 1 alt 0 claimed by uvcvideo
[137.752851 0:40 starry_kernel::pseudofs::usbfs::manager:747] [usb-hotplug] bus=1 device=5 logical_id=4 state=connected kind=device vid=1e45 pid=8022 class=0xef
这组日志证明了端口连接、枚举、描述符获取、interface 生成、ID 匹配、probe 和逻辑 claim 的链路已经贯通。class=0xef 是设备级 composite class,真正用于本次匹配的是两个 interface 的 Video class/subclass。
当前结果还不代表摄像头视频采集已经完成,下一阶段需要继续完成:
- 将异步 live
Deviceownership 接入 UVC driver 生命周期。 - 同时管理 Video Control 和 Video Streaming interface 的底层 claim。
- 解析 UVC format/frame descriptor,完成视频格式协商。
- 配置 isochronous endpoint,接收 USB payload 并组装视频帧。
验证情况
cargo test -p crab-usb --lib:42 个测试通过。cargo test -p ax-driver --lib --features usb:2 个测试通过。cargo xtask clippy --package ax-driver:59 个 feature 组合全部通过。cargo fmt --all --check和git diff --check通过。
下周计划
- 继续设计 UVC class driver 与 live USB
Device之间的 ownership 边界。 - 解析 Suyin 摄像头的完整 UVC descriptors,确认 VC/VS interface 和 isochronous endpoint 参数。
- 在不破坏 usbfs interface ownership 的前提下,完成最小视频格式协商和单帧接收测试。
- 继续完善 USB 多设备断开、重新连接和 driver disconnect 路径。