2. USB批量传输协议基础
批量传输(Bulk Transfer)是USB体系中唯一提供数据完整性保证且不占用固定带宽的传输类型。在Gadget驱动中,批量传输是吞吐量优化的主战场。本节从端点特性、事务格式、数据包大小与NAK机制三个维度拆解批量传输的底层协议规则。
2.1 批量传输端点特性
批量端点与其他端点类型(控制、中断、同步)的关键区别在于:没有预留带宽,且硬件自动重试。下表列出批量端点的核心属性:
| 属性 | 批量端点 | 对比:中断端点 | 对比:同步端点 |
|---|---|---|---|
| 带宽保证 | 无(空闲时抢带宽) | 有(轮询间隔保证) | 有(固定带宽预留) |
| 错误重试 | 硬件自动重试(直到成功) | 硬件自动重试 | 无重试(允许丢包) |
| 最大包大小(HS) | 512字节 | 1024字节 | 1024字节 |
| 最大包大小(SS) | 1024字节 | 1024字节 | 1024字节 |
| 事务方向 | 单向(IN/OUT独立端点) | 单向 | 单向 |
| 流控机制 | NAK握手 | NAK握手 | 无流控 |
Gadget优化提示: 批量端点的“无带宽保证”特性意味着:当总线上同时存在同步或中断传输时,批量传输的延迟会显著增加。性能优化时,应优先确保批量端点在USB调度中的权重不被其他传输类型过度挤压。
批量端点必须成对使用(一个IN端点 + 一个OUT端点),且端点号通常从1开始(端点0为控制端点保留)。在Linux Gadget驱动中,批量端点通过 usb_ep 结构体描述,其 maxpacket 字段决定了单次传输的数据载荷上限。
2.2 批量传输事务格式
USB批量传输采用令牌-数据-握手三段式事务结构。每个批量事务由主机发起,包含三个连续的包阶段:
- 令牌包(Token Packet):主机发送OUT令牌(写设备)或IN令牌(读设备),包含设备地址和端点号。
- 数据包(Data Packet):数据源(主机OUT或设备IN)发送0~1024字节的数据载荷,附带CRC16校验。
- 握手包(Handshake Packet):接收方返回ACK(成功)、NAK(忙)或STALL(错误)。
关键规则: 批量传输不支持PING协议(仅同步和中断端点使用),流控完全依赖NAK握手。这意味着设备端必须通过硬件或软件及时响应事务,否则主机将反复重试同一事务。
下图展示一个完整的批量OUT事务(主机→设备)的包序列:
批量IN事务(设备→主机)的包序列与OUT对称,区别在于:
- 令牌包为IN令牌(主机请求数据)。
- 数据包由设备发送,主机接收。
- 握手包由主机返回ACK(成功接收)或NAK(缓冲区满)。
2.3 数据包大小与最大包限制
批量传输的数据包大小受端点描述符中的wMaxPacketSize约束。不同USB速度下的批量最大包大小如下:
| USB速度 | 批量最大包大小 | 每微帧事务数 | 理论峰值(单向) |
|---|---|---|---|
| 全速(FS, 12 Mbps) | 64字节 | 1 | 1.216 MB/s |
| 高速(HS, 480 Mbps) | 512字节 | 3(微帧内突发) | 53.248 MB/s |
| 超高速(SS, 5 Gbps) | 1024字节 | 突发(Burst) | >400 MB/s |
常见陷阱: 批量传输的短包(Short Packet)规则:当数据长度小于wMaxPacketSize时,该包被视为传输结束(Transfer Complete)。Gadget驱动必须正确处理短包中断,否则可能导致数据粘包或丢失。
数据包大小对性能的影响体现在两个方面:
- 协议开销占比:每个批量事务有20字节的协议开销(令牌+握手+帧间隔)。包越大,有效载荷占比越高。
- DMA对齐:许多USB控制器要求DMA缓冲区地址和大小对齐到wMaxPacketSize边界,否则触发PIO模式,性能骤降。
下图展示不同包大小下的有效带宽利用率(假设HS 480 Mbps,忽略帧调度延迟):
2.4 NAK机制与流控
NAK(Negative Acknowledge)是批量传输的核心流控手段。当设备端无法立即处理数据时(如缓冲区满或DMA未就绪),硬件自动返回NAK握手包,通知主机重试当前事务。
NAK机制的工作流程如下:
- 主机发起批量事务(OUT或IN令牌)。
- 设备硬件检查端点状态:
- 如果端点就绪(缓冲区可用):接收数据(OUT)或发送数据(IN),返回ACK。
- 如果端点忙(缓冲区满/空):返回NAK,事务不完成。
- 主机收到NAK后,在当前微帧内立即重试同一事务(HS下最多3次/微帧)。
- 若连续NAK超过主机重试限制,主机将暂停该端点调度,等待下一微帧再试。
性能影响: 每次NAK意味着一个完整的事务时间片被浪费(约1μs @ HS)。如果Gadget驱动频繁NAK(例如中断处理延迟过高),有效带宽将急剧下降。优化目标是:将NAK率控制在1%以下。
下图展示NAK重试的时序细节:
在Gadget驱动层面,NAK的产生原因通常包括:
- 中断延迟过高:CPU未能及时处理端点中断,导致硬件缓冲区未及时清空/填充。
- DMA未完成:DMA传输正在进行,硬件FIFO被锁定。
- 协议层背压:上层应用未及时消费数据,导致驱动层缓冲区满。
优化切入点: 使用
perf top 或 usbmon 监控NAK频率。如果NAK率超过5%,优先检查中断处理函数(IRQ handler)的执行时间,确保在10μs内完成端点服务。
2.5 批量传输的协议约束总结
下表汇总了批量传输协议中直接影响Gadget驱动性能的关键约束:
| 约束项 | 具体规则 | 性能影响 |
|---|---|---|
| 最大包大小 | HS: 512B, SS: 1024B | 包越小,协议开销占比越大 |
| 短包结束 | 小于wMaxPacketSize的包标记传输结束 | 需正确处理,避免数据截断 |
| NAK重试 | HS下每微帧最多3次重试 | 高NAK率导致带宽浪费 |
| 无PING协议 | 批量端点不支持PING流控 | 设备必须主动NAK,无法预查询 |
| 事务原子性 | 令牌-数据-握手不可分割 | 任何阶段失败都需整个事务重试 |