3. USB同步传输协议基础
同步传输(Isochronous Transfer)是USB体系中唯一为实时性与带宽确定性设计的传输类型。在USB Gadget驱动中,音频、视频、数据采集卡等对延迟敏感的设备几乎全部依赖同步传输。本章深入剖析同步传输端点的特性、事务格式以及等时传输的实时性约束。
3.1 同步传输端点特性
同步端点(Isochronous Endpoint)在USB描述符中通过 bEndpointAddress 和 bmAttributes 字段标识。与批量端点相比,同步端点具有以下关键特性:
| 特性 | 同步端点 | 批量端点 |
|---|---|---|
| 传输方向 | 单向(IN 或 OUT) | 单向(IN 或 OUT) |
| 错误重传 | 不支持(无握手阶段重试) | 支持(自动重试直到成功或超时) |
| 带宽保证 | 预留固定带宽(每微帧固定字节数) | 尽力而为(无预留) |
| 最大包大小 | 高速:≤1024字节;全速:≤1023字节 | 高速:≤512字节;全速:≤64字节 |
| 每微帧事务数 | 高速:最多3个事务(1~3个数据包) | 高速:最多1个事务(批量流除外) |
| 数据有效性 | 提供 数据有效性标志(Data PID 校验) | 严格校验,无效则重传 |
struct usb_ep 描述,但 ep->caps.type_iso 必须为真。驱动初始化时需通过 usb_ep_autoconfig() 或手动匹配端点描述符来获取同步端点实例。
3.2 同步传输事务格式
同步传输在USB总线上以事务(Transaction)为单位执行。每个事务由三个阶段组成,但与批量/中断事务不同,同步事务没有握手阶段(高速模式下除外,高速同步事务包含微帧级握手)。
3.2.1 标准同步事务阶段
- 令牌阶段(Token):主机发送IN或OUT令牌包,指定端点地址和方向。
- 数据阶段(Data):数据包携带有效载荷,使用DATA0/DATA1/MDATA(高速多事务)PID。
- 握手阶段(Handshake):全速模式下无握手;高速模式下主机/设备返回
ERR或NYET握手(仅用于流控)。
3.2.2 高速同步事务的多包结构
在高速模式下,每个微帧(125 µs)最多可执行3个同步事务。这3个事务使用不同的数据PID:
| 事务序号 | 数据PID | 说明 |
|---|---|---|
| 第1个事务 | DATA0 | 第一个数据包 |
| 第2个事务 | DATA1 | 第二个数据包 |
| 第3个事务 | DATA2 | 第三个数据包(如果存在) |
这种PID序列允许接收方检测数据包是否丢失或乱序,但由于没有重传机制,丢失的数据包只能通过上层协议(如应用层FEC)恢复。
3.2.3 同步事务时序图
下图展示了一个高速同步OUT事务在单个微帧内的完整时序:
3.3 等时传输与实时性要求
等时传输(Isochronous Transfer)的实时性由USB主机控制器的帧/微帧调度保证。每个同步端点在上电配置时向主机声明其带宽需求,主机控制器在每帧/微帧中预留固定时间槽。
3.3.1 带宽预留机制
USB 2.0高速模式下,每个微帧(125 µs)的总带宽为1024字节(全速帧为1 ms,1023字节)。同步端点通过端点描述符中的 wMaxPacketSize 字段声明每微帧最大数据量:
- 单事务端点:
wMaxPacketSize≤ 1024字节,每微帧1个事务。 - 多事务端点:
wMaxPacketSize的高2位(bits 12~11)编码事务数:00:1个事务(默认)01:2个事务10:3个事务11:保留
wMaxPacketSize = 192(单事务)。若需要每微帧发送600字节,可设置 wMaxPacketSize = 0x0320(低10位=0x0320=800字节,高2位=00表示1个事务),或使用2个事务各300字节。
3.3.2 实时性约束与抖动
等时传输的实时性并非绝对,存在以下抖动来源:
| 抖动来源 | 典型范围 | 影响 |
|---|---|---|
| 主机调度延迟 | ±10~50 µs | 数据包到达时间波动 |
| USB总线竞争 | ±1~5 µs | 高优先级传输抢占时间槽 |
| Gadget控制器DMA延迟 | ±5~20 µs | 数据从内存到USB引擎的传输延迟 |
| 中断处理延迟 | ±10~100 µs | Linux内核中断上下文切换 |
对于音频设备(采样率48 kHz,周期20.83 µs),抖动超过100 µs会导致可闻的爆音或失真。因此Gadget驱动必须采用双缓冲或环形缓冲机制来吸收抖动。
3.3.3 等时传输的实时性保障策略
- 预分配DMA缓冲区:在端点使能时分配连续物理内存,避免运行时动态分配。
- 使用URB完成回调的原子操作:在
usb_complete_t回调中仅做轻量级数据搬运,不调用kmalloc或printk。 - 调整URB队列深度:通过
usb_fill_int_urb或usb_fill_bulk_urb的number_of_packets参数控制每次提交的数据包数量,平衡延迟与吞吐量。 - 使用高精度定时器(hrtimer):在Gadget驱动中替代传统内核定时器,提供微秒级精度。
3.3.4 等时传输数据流架构
下图展示了USB Gadget驱动中等时传输的完整数据流:
3.4 同步传输的典型应用场景
同步传输在以下场景中不可替代:
- USB音频设备(UAC):需要恒定比特率传输PCM数据,采样率44.1 kHz/48 kHz/96 kHz,延迟要求<10 ms。
- USB视频设备(UVC):摄像头实时视频流,帧率30 fps/60 fps,每帧数据量数百KB。
- USB数据采集卡:传感器数据以固定速率上传,如心电图(ECG)250 Hz采样。
- USB MIDI设备:MIDI事件流需要低延迟传输,但数据量小。