VUDC 虚拟设备控制器与 Gadget
1. 用途
usbip-vudc不是把物理USB device反向导出,而是实现软件UDC,使Linux Gadget通过网络出现在远端VHCI上:
1 | ConfigFS Function |
2. 实例化
vudc_main.c以模块参数num决定实例数,默认1。模块创建usbip-vudc.N平台设备并由同名platform driver probe。
vudc_probe()初始化虚拟硬件后调用usb_add_gadget_udc(),因此实例出现在:
1 | /sys/class/udc/usbip-vudc.0 |
它不依赖RK3588 DWC3 UDC或USB PHY,也不会从物理Type-C端口输出信号。
3. Gadget对象
vudc内嵌usb_gadget,最大速度为High Speed;它提供EP0、15个IN和15个OUT endpoint,共31个虚拟endpoint。对象还维护:
- 当前
usb_gadget_driver; - EP0及多个
vep; - address、device status和设备descriptor缓存;
- pullup/connected状态;
- 收到的Host URB队列;
- completion TX队列;
- 传输timer。
vep实现usb_ep,保存endpoint descriptor、type、halt/wedge及vrequest队列。
4. UDC Ops
VUDC实现标准Gadget操作:
- endpoint enable/disable;
- request alloc/free;
- queue/dequeue;
- set_halt/set_wedge;
- pullup;
- udc_start/udc_stop;
- get_frame及设备状态相关操作。
因此configfs/composite function无需感知后端是网络而非硬件UDC。
5. ConfigFS绑定
典型流程:
1 | modprobe usbip-vudc num=1 |
本树tools/usb/usbip/vudc/vudc_server_example.sh给出ACM Gadget示例。
6. Host请求接收
v_rx_loop()接收远端VHCI的CMD_SUBMIT/CMD_UNLINK。SUBMIT被转换为urbp:
- 根据ep地址找到
vep; - 分配URB及buffer;
- 验证transfer length和ISO packet数;
- 接收OUT数据;
- 放入
urb_queue。
EP0 standard request部分由VUDC处理,其余交给gadget driver的setup()。
7. 请求撮合
Gadget function调用usb_ep_queue()提交vrequest;远端Host提交的是urbp。vudc_transfer.c在相同endpoint上撮合二者:
1 | Host URB buffer <-> Gadget request buffer |
按照方向复制数据,更新两侧actual/status,并处理short packet、zero packet、halt、setup/data/status stage。
传输timer模拟frame推进。源码对周期带宽主要采用软件limit,并不等价于真实UDC的微帧调度。
8. 返回路径
完成的urbp包装为tx_item(TX_SUBMIT);取消结果为TX_UNLINK。v_tx_loop()发送RET_SUBMIT/RET_UNLINK及IN payload、ISO descriptor。
Gadget request completion仍通过Gadget API回调function driver。
9. 描述符和用户态发现
VUDC sysfs提供:
usbip_sockfd;usbip_status;- 二进制
dev_desc。
usbipd --device读取虚拟设备descriptor并响应远端DEVLIST/IMPORT。导入时busid是usbip-vudc.N,不是物理USB busid。
10. 限制
- 仅模拟UDC语义,不模拟真实PHY/link power state;
- VUDC的timer传输路径当前对isochronous URB直接返回
-EXDEV,不能用作ISO Gadget后端; - 远端Host完全控制USB请求,Gadget function必须按不可信输入设计;
- 不能同时把一个VUDC绑定给多个Gadget或多个网络连接;
- 删除模块前必须解除ConfigFS Gadget和socket连接。
正在加载留言…