3. USB同步传输协议基础

同步传输(Isochronous Transfer)是USB体系中唯一为实时性与带宽确定性设计的传输类型。在USB Gadget驱动中,音频、视频、数据采集卡等对延迟敏感的设备几乎全部依赖同步传输。本章深入剖析同步传输端点的特性、事务格式以及等时传输的实时性约束。

核心认知:同步传输不保证数据重传,但保证以恒定速率在固定时间槽内完成传输。这是它与批量传输(Bulk)最本质的区别。

3.1 同步传输端点特性

同步端点(Isochronous Endpoint)在USB描述符中通过 bEndpointAddress 和 bmAttributes 字段标识。与批量端点相比,同步端点具有以下关键特性:

特性 同步端点 批量端点
传输方向 单向(IN 或 OUT) 单向(IN 或 OUT)
错误重传 不支持(无握手阶段重试) 支持(自动重试直到成功或超时)
带宽保证 预留固定带宽(每微帧固定字节数) 尽力而为(无预留)
最大包大小 高速:≤1024字节;全速:≤1023字节 高速:≤512字节;全速:≤64字节
每微帧事务数 高速:最多3个事务(1~3个数据包) 高速:最多1个事务(批量流除外)
数据有效性 提供 数据有效性标志(Data PID 校验) 严格校验,无效则重传
Gadget驱动注意:在Linux内核中,同步端点使用 struct usb_ep 描述,但 ep->caps.type_iso 必须为真。驱动初始化时需通过 usb_ep_autoconfig() 或手动匹配端点描述符来获取同步端点实例。

3.2 同步传输事务格式

同步传输在USB总线上以事务(Transaction)为单位执行。每个事务由三个阶段组成,但与批量/中断事务不同,同步事务没有握手阶段(高速模式下除外,高速同步事务包含微帧级握手)。

3.2.1 标准同步事务阶段

  1. 令牌阶段(Token):主机发送IN或OUT令牌包,指定端点地址和方向。
  2. 数据阶段(Data):数据包携带有效载荷,使用DATA0/DATA1/MDATA(高速多事务)PID。
  3. 握手阶段(Handshake):全速模式下无握手;高速模式下主机/设备返回 ERR 或 NYET 握手(仅用于流控)。
关键差异:全速同步事务没有握手阶段,这意味着发送方无法知道数据是否被成功接收。高速同步事务虽然引入了握手,但握手仅用于流控(NYET)或错误报告(ERR),不会触发数据重传。

3.2.2 高速同步事务的多包结构

在高速模式下,每个微帧(125 µs)最多可执行3个同步事务。这3个事务使用不同的数据PID:

事务序号 数据PID 说明
第1个事务 DATA0 第一个数据包
第2个事务 DATA1 第二个数据包
第3个事务 DATA2 第三个数据包(如果存在)

这种PID序列允许接收方检测数据包是否丢失或乱序,但由于没有重传机制,丢失的数据包只能通过上层协议(如应用层FEC)恢复。

3.2.3 同步事务时序图

下图展示了一个高速同步OUT事务在单个微帧内的完整时序:

高速同步OUT事务时序图 高速同步OUT事务时序(微帧内) SOF EOF 125 µs OUT令牌 DATA0 NYET OUT令牌 DATA1 NYET OUT令牌 DATA2 令牌阶段 数据阶段 握手阶段 说明:高速同步事务最多3个/微帧,每个事务包含令牌+数据+握手。握手仅用于流控,不触发重传。 全速模式下无握手阶段,数据发送后直接结束事务。

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:保留
Gadget驱动配置示例:若音频设备需要每微帧发送192字节的PCM数据,可设置 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 等时传输的实时性保障策略

  1. 预分配DMA缓冲区:在端点使能时分配连续物理内存,避免运行时动态分配。
  2. 使用URB完成回调的原子操作:在 usb_complete_t 回调中仅做轻量级数据搬运,不调用 kmalloc 或 printk。
  3. 调整URB队列深度:通过 usb_fill_int_urb 或 usb_fill_bulk_urb 的 number_of_packets 参数控制每次提交的数据包数量,平衡延迟与吞吐量。
  4. 使用高精度定时器(hrtimer):在Gadget驱动中替代传统内核定时器,提供微秒级精度。

3.3.4 等时传输数据流架构

下图展示了USB Gadget驱动中等时传输的完整数据流:

USB Gadget等时传输数据流架构 USB Gadget等时传输数据流架构 应用层 音频/视频数据源 Gadget驱动 URB队列管理 DMA引擎 双缓冲/环形缓冲 USB控制器 同步端点引擎 USB总线 实时性保障措施 • 预分配DMA缓冲区 • 原子URB回调 • 调整队列深度 • hrtimer定时器 • 双缓冲吸收抖动

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事件流需要低延迟传输,但数据量小。