3. USB 传输类型:特性与适用场景

USB 协议定义了四种传输类型,分别针对不同的带宽、延迟和可靠性需求。理解这四种传输类型是编写 USB 设备驱动的核心基础。每种传输类型在 USB 规范中对应特定的端点描述符,驱动开发者必须根据硬件特性选择合适的传输方式。

3.1 控制传输 (Control Transfer)

控制传输是 USB 设备枚举和配置的基础,也是唯一必须被所有 USB 设备支持的传输类型。它用于主机与设备之间的命令/状态交互,例如读取设备描述符、设置配置、发送类特定命令等。

核心特性: 双向、可靠、有保证的传输,但带宽占用较小。控制传输总是由主机发起的 SETUP 阶段开始,随后是可选的数据阶段,最后是状态阶段。

3.1.1 控制传输的四个阶段

  1. SETUP 阶段: 主机向设备发送 8 字节的 USB 请求块 (USB Request Block, URB),包含请求类型、请求码、参数等信息。
  2. DATA 阶段(可选): 根据 SETUP 阶段的方向位,主机或设备传输数据。数据长度由 SETUP 阶段指定。
  3. STATUS 阶段: 用于确认数据阶段是否成功完成。方向与 DATA 阶段相反。
  4. 完成回调: 当 URB 完成或发生错误时,内核调用注册的回调函数通知驱动。
控制传输事务流程 主机 (Host) 设备 (Device) ① SETUP (8 字节请求) ② DATA (可选,方向可变) ③ STATUS (握手确认) 控制传输是设备枚举的必经之路,所有 USB 设备必须支持端点 0

3.1.2 适用场景

  • 设备枚举: 获取设备描述符、配置描述符、接口描述符等。
  • 标准请求: 设置地址、设置配置、清除端点暂停等。
  • 类特定命令: HID 报告描述符获取、大容量存储设备的 SCSI 命令封装。
  • 厂商自定义命令: 固件升级、设备模式切换、寄存器读写。
注意: 控制传输的 DATA 阶段最大数据长度受端点 0 的 wMaxPacketSize 限制(通常为 8、16、32 或 64 字节)。如果需要传输大量数据,应使用批量传输或等时传输。

3.2 批量传输 (Bulk Transfer)

批量传输用于传输大量数据,但不保证固定的延迟。它利用 USB 总线空闲时的带宽,当总线繁忙时可能被延迟。批量传输具有硬件级别的 CRC 校验和重传机制,确保数据完整性。

核心特性: 非周期性、大容量、可靠传输。批量传输只在总线带宽空闲时进行,优先级低于中断传输和等时传输。

3.2.1 批量传输的 URB 编程要点

/* 批量传输 URB 初始化示例 */
struct urb *bulk_urb;
void *bulk_buffer;
dma_addr_t bulk_dma;

/* 1. 分配 URB */
bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!bulk_urb)
    return -ENOMEM;

/* 2. 分配 DMA 缓冲区 */
bulk_buffer = usb_alloc_coherent(udev, BULK_BUFFER_SIZE,
                                 GFP_KERNEL, &bulk_dma);
if (!bulk_buffer) {
    usb_free_urb(bulk_urb);
    return -ENOMEM;
}

/* 3. 填充 URB */
usb_fill_bulk_urb(bulk_urb, udev,
                  usb_rcvbulkpipe(udev, BULK_IN_EP),
                  bulk_buffer, BULK_BUFFER_SIZE,
                  bulk_completion_callback, NULL);

/* 4. 设置 DMA 句柄 */
bulk_urb->transfer_dma = bulk_dma;
bulk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

/* 5. 提交 URB */
ret = usb_submit_urb(bulk_urb, GFP_KERNEL);

3.2.2 适用场景

设备类型 典型应用 数据特点
大容量存储设备 (U盘、移动硬盘) 读写数据块 数据量大,对延迟不敏感,要求 100% 正确
USB 打印机 发送打印作业 数据量大,可容忍一定延迟
USB 网络适配器 传输网络数据包 数据量大,依赖上层协议保证可靠性
数据采集卡 批量上传采样数据 数据量大,允许缓冲
批量传输带宽抢占模型 时间 等时 中断 批量 (数据块1) 等时 批量 (数据块2) 中断 批量传输只在等时和中断传输的间隙中传输,优先级最低 当总线空闲时,批量传输可以占满整个带宽

3.3 中断传输 (Interrupt Transfer)

中断传输用于传输少量、周期性、对延迟敏感的数据。尽管名称包含“中断”,但 USB 中断传输实际上是主机轮询设备的过程,设备不能主动发起传输。主机根据端点描述符中的 bInterval 字段定期轮询设备。

核心特性: 保证最大延迟、有限数据量、可靠传输。中断传输的轮询间隔由端点描述符定义,范围从 1ms 到 255ms(全速/低速)或 125µs 到 4096ms(高速)。

3.3.1 中断传输的轮询机制

/* 中断传输 URB 初始化示例 */
struct urb *intr_urb;
void *intr_buffer;

intr_urb = usb_alloc_urb(0, GFP_KERNEL);
intr_buffer = kmalloc(INT_BUFFER_SIZE, GFP_KERNEL);

/* 填充中断 URB */
usb_fill_int_urb(intr_urb, udev,
                 usb_rcvintpipe(udev, INT_IN_EP),
                 intr_buffer, INT_BUFFER_SIZE,
                 intr_completion_callback, NULL,
                 interval);  /* 轮询间隔,单位:ms (全速) 或 125µs 帧 (高速) */

/* 提交 URB,开始轮询 */
usb_submit_urb(intr_urb, GFP_KERNEL);

3.3.2 适用场景

  • HID 设备: 键盘、鼠标、游戏手柄的输入报告。
  • 人机交互设备: 触摸屏、手写板、条码扫描器。
  • 物理量传感器: 温度传感器、加速度计、陀螺仪的数据读取。
  • 设备状态通知: USB 集线器的端口状态变化、打印机状态反馈。
中断传输轮询时序图 主机 设备 轮询 (t=0ms) 数据 (无数据则 NAK) 轮询 (t=interval) 数据 (有数据则返回) 中断传输的延迟上限 = 轮询间隔 × 2 (最坏情况)

3.4 等时传输 (Isochronous Transfer)

等时传输用于传输实时性要求极高、允许少量数据丢失的流数据。它提供预分配的固定带宽,保证传输速率恒定,但不提供重传机制。等时传输没有握手阶段,数据一旦出错即被丢弃。

关键限制: 等时传输只在高速 USB 设备上广泛支持。低速设备不支持等时传输,全速设备支持但带宽有限。等时端点没有 STALL 和 NAK 机制。

3.4.1 等时传输的 URB 结构

/* 等时传输 URB 初始化示例 */
struct urb *iso_urb;
int packets_per_urb = 8;  /* 每个 URB 包含多个等时包 */

iso_urb = usb_alloc_urb(packets_per_urb, GFP_KERNEL);
iso_urb->dev = udev;
iso_urb->pipe = usb_rcvisocpipe(udev, ISO_IN_EP);
iso_urb->transfer_buffer = iso_buffer;
iso_urb->transfer_buffer_length = ISO_BUFFER_SIZE;
iso_urb->complete = iso_completion_callback;
iso_urb->number_of_packets = packets_per_urb;
iso_urb->interval = 1;  /* 每个微帧传输一次 */

/* 设置每个等时包的偏移和长度 */
for (i = 0; i < packets_per_urb; i++) {
    iso_urb->iso_frame_desc[i].offset = i * ISO_PACKET_SIZE;
    iso_urb->iso_frame_desc[i].length = ISO_PACKET_SIZE;
}

usb_submit_urb(iso_urb, GFP_KERNEL);

3.4.2 适用场景

设备类型 典型应用 数据特点
USB 音频设备 (声卡、耳机、麦克风) 音频流播放/录制 恒定速率,允许偶尔丢帧,延迟敏感
USB 视频设备 (摄像头、采集卡) 视频流传输 高带宽,恒定帧率,允许丢帧
USB 麦克风阵列 多通道音频同步采集 多通道同步,严格时序要求
USB 软件无线电 (SDR) IQ 采样数据传输 连续流,高带宽,实时处理
等时传输带宽预分配模型 USB 帧 (1ms) / 微帧 (125µs) 等时槽 1 等时槽 2 等时槽 3 剩余带宽 (批量/中断/控制) 等时传输在帧/微帧开始时获得固定带宽槽,保证实时性 带宽预分配在 USB 枚举阶段完成,驱动无法动态调整

3.5 四种传输类型对比总结

特性 控制传输 批量传输 中断传输 等时传输
传输方向 双向 (SETUP + DATA + STATUS) 单向 (IN 或 OUT) 单向 (IN 或 OUT) 单向 (IN 或 OUT)
数据可靠性 高 (CRC + 重传) 高 (CRC + 重传) 高 (CRC + 重传) 低 (CRC 但不重传)
延迟保证 无 无 有 (轮询间隔保证) 有 (带宽预分配)
带宽占用 低 (最多 64 字节/事务) 高 (最多 512/1024 字节/事务) 中 (最多 64/1024 字节/事务) 高 (最多 1024 字节/事务)
端点数量 至少 1 个 (端点 0) 至少 1 个 至少 1 个 至少 1 个
硬件握手 ACK/NAK/STALL ACK/NAK/STALL ACK/NAK/STALL 无握手
典型用途 枚举、配置、命令 大容量数据存储 HID、传感器、状态 音频、视频、流媒体
驱动开发建议: 在编写 USB 驱动时,首先阅读设备的数据手册,确定每个端点对应的传输类型。错误的传输类型选择会导致 URB 提交失败(错误码 -EINVAL 或 -EPIPE)。对于复合设备(如带音频和 HID 功能的摄像头),不同接口可能使用不同的传输类型,需要分别处理。