4. 端点类型与传输类型:控制传输、批量传输、中断传输、等时传输特性对比
USB 协议定义了四种传输类型,分别对应不同的端点类型。理解这四种传输类型的特性,是配置端点、编写 URB 提交逻辑的基础。每种传输类型在带宽保证、错误重试、数据大小和延迟方面都有不同的设计目标。
核心概念:端点的类型决定了其支持的传输类型。在 USB 描述符中,
bEndpointAddress 的低 4 位与 bmAttributes 字段共同标识端点的方向与传输类型。驱动开发者必须在初始化端点时正确匹配这两者。
4.1 四种传输类型总览
下表从带宽、可靠性、延迟、数据大小和典型应用五个维度,对比四种传输类型。
| 传输类型 | 带宽保证 | 错误重试 | 延迟 | 最大数据包大小 (FS/HS/SS) | 典型应用 |
|---|---|---|---|---|---|
| 控制传输 | 固定 10% 保留带宽 | 硬件自动重试 (3 次) | 中等 | 8 / 64 / 512 字节 | 设备枚举、配置、命令 |
| 批量传输 | 无保证(利用剩余带宽) | 硬件自动重试 (直到成功) | 高(非实时) | 8 / 64 / 1024 字节 | U 盘、打印机、数据采集 |
| 中断传输 | 有保证(轮询间隔) | 硬件自动重试 (直到成功) | 低(可预测) | 8 / 64 / 1024 字节 | 鼠标、键盘、HID 设备 |
| 等时传输 | 有保证(预留带宽) | 无重试(允许丢包) | 最低(固定间隔) | 1023 / 1023 / 1024 字节 | 音频、视频、实时流 |
驱动开发要点:批量传输是 USB 驱动开发中最常用的类型,因为它提供可靠的数据传输且不占用固定带宽。但要注意,批量传输在总线繁忙时可能被延迟,不适合实时性要求高的场景。
4.2 控制传输详解
控制传输是 USB 协议的基础,每个 USB 设备必须至少有一个控制端点(端点 0)。它采用“请求-数据-状态”三阶段模型,用于设备枚举、标准请求和厂商自定义命令。
4.3 批量传输详解
批量传输是 USB 驱动开发中最常用的传输类型。它提供可靠的数据传输,但带宽优先级最低。当总线空闲时,批量传输可以占用全部带宽;当总线繁忙时,它会被其他传输类型抢占。
常见陷阱:批量传输没有固定的带宽保证。在高速 USB 系统中,批量传输的最大数据包大小为 512 字节(HS)或 1024 字节(SS)。如果驱动未正确处理短包(short packet)或 ZLP(零长度包),可能导致数据传输不完整或死锁。
批量传输的 URB 提交流程如下:
- 分配 URB:使用
usb_alloc_urb(0, GFP_KERNEL)分配 URB 结构体。 - 填充 URB:设置
urb->dev、urb->pipe(使用usb_sndbulkpipe()或usb_rcvbulkpipe())、urb->transfer_buffer、urb->transfer_buffer_length。 - 设置回调:注册
urb->complete回调函数,处理传输完成或错误。 - 提交 URB:调用
usb_submit_urb(urb, GFP_KERNEL)将 URB 提交到 USB 核心层。 - 释放 URB:在回调中或超时后调用
usb_free_urb(urb)释放资源。
/* 批量传输 URB 提交示例 */
struct urb *bulk_urb;
void *buf;
/* 1. 分配缓冲区 */
buf = kmalloc(512, GFP_KERNEL);
if (!buf)
return -ENOMEM;
/* 2. 分配 URB */
bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!bulk_urb) {
kfree(buf);
return -ENOMEM;
}
/* 3. 填充 URB:批量 OUT 端点 */
usb_fill_bulk_urb(bulk_urb, udev,
usb_sndbulkpipe(udev, 0x02), /* 端点 2 OUT */
buf, 512,
bulk_write_complete, /* 回调函数 */
NULL);
/* 4. 提交 URB */
ret = usb_submit_urb(bulk_urb, GFP_KERNEL);
if (ret) {
dev_err(&udev->dev, "批量 URB 提交失败: %d\n", ret);
usb_free_urb(bulk_urb);
kfree(buf);
return ret;
}
4.4 中断传输详解
中断传输并非真正的中断,而是主机以固定间隔轮询设备,检查是否有数据需要传输。它提供低延迟和带宽保证,适用于鼠标、键盘等 HID 设备。
驱动提示:中断传输的轮询间隔在端点描述符的
bInterval 字段中定义。对于全速设备,单位为毫秒;对于高速设备,单位为 125µs 的倍数。驱动中通过 usb_fill_int_urb() 或手动设置 urb->interval 来配置。
4.5 等时传输详解
等时传输是唯一不保证数据可靠性的传输类型。它没有握手阶段,不进行错误重试,但提供固定的带宽和最低的延迟。等时传输适用于音频、视频等实时流数据,允许偶尔的数据丢失。
| 特性 | 等时传输 | 批量传输 | 中断传输 |
|---|---|---|---|
| 错误重试 | 无 | 有(直到成功) | 有(直到成功) |
| 带宽预留 | 是(固定) | 否 | 是(按间隔) |
| 数据包大小 | 最大 1024 字节 | 最大 1024 字节 | 最大 1024 字节 |
| URB 类型 | URB_ISOCHRONOUS |
URB_BULK |
URB_INTERRUPT |
| 典型应用 | USB 摄像头、音频设备 | 存储设备、打印机 | HID 设备、游戏手柄 |
4.6 传输类型选择指南
在实际驱动开发中,选择正确的传输类型至关重要。以下决策流程可以帮助你快速确定合适的传输类型:
- 是否需要可靠传输?
- 是 → 继续判断是否需要实时性。
- 否 → 选择 等时传输(音频/视频流)。
- 是否需要低延迟和带宽保证?
- 是 → 选择 中断传输(HID 设备)。
- 否 → 选择 批量传输(存储设备)。
- 是否用于设备枚举或标准请求?
- 是 → 选择 控制传输(端点 0)。
实战建议:在编写 USB 驱动时,优先使用批量传输进行大数据量传输。如果设备是 HID 类,使用中断传输。控制传输仅用于配置和命令。等时传输需要精确的带宽计算,建议在硬件验证阶段再启用。