3. USB传输类型:控制、批量、中断、同步
USB的传输类型,说白了就是四种不同的数据搬运方式。每种方式都有自己的脾气和适用场景。我刚开始接触USB时,总觉得这四种类型记起来很绕,后来在项目里挨个踩过坑,才真正理解它们的设计初衷。
咱们一个一个来看。
3.1 控制传输(Control Transfer)
控制传输是USB的“官话”。设备刚插上时,主机和它还不认识,就得靠控制传输来握手、问名字、分配地址。它也是唯一一种所有USB设备都必须支持的传输类型。
控制传输分三个阶段:
- Setup阶段:主机发一个8字节的请求包,告诉设备“我要干什么”。比如获取设备描述符、设置配置值。
- Data阶段(可选):如果请求有数据,就双向传输。比如主机要读设备描述符,设备就在这个阶段把数据发回来。
- Status阶段:收尾确认。设备告诉主机“我搞定了”或者“我出错了”。
关键点:控制传输的可靠性很高,但速度慢。它适合小数据量、不频繁的通信。枚举过程全靠它。
我遇到过一个问题:设备枚举时老是失败,抓包一看,Status阶段设备回了STALL。后来发现是固件里对控制请求的处理逻辑写错了,少处理了一个标准请求。嗯,控制传输的每个阶段都不能马虎。
3.2 批量传输(Bulk Transfer)
批量传输,听名字就知道——它适合“搬砖”。数据量大,但对实时性没要求。比如U盘读写、打印机发数据。
它的特点是:
- 保证数据正确:硬件有CRC校验和重传机制。
- 不保证带宽和延迟:总线空闲时它拼命传,总线忙时它等着。
- 只能用于BULK端点:控制端点不行。
| 特性 | 批量传输 |
|---|---|
| 数据完整性 | 高(CRC + 重传) |
| 实时性 | 低 |
| 典型应用 | U盘、打印机、数据采集 |
| 带宽占用 | 尽力而为 |
个人经验:批量传输在USB 2.0下理论速度可达53.248 MB/s(高速模式),但实际项目中能跑到40 MB/s就算不错了。别被理论值忽悠了。
3.3 中断传输(Interrupt Transfer)
中断传输这个名字容易让人误解。它并不是真的“中断”CPU,而是主机定期轮询设备,看有没有数据要传。
它的特点:
- 保证延迟:主机按约定的间隔(bInterval)来查询。
- 有重传机制:出错会重试,保证数据正确。
- 适合小数据量、周期性通信:比如鼠标、键盘、游戏手柄。
我曾经调试一个USB键盘,发现按键偶尔丢失。抓包一看,中断传输的轮询间隔设得太长了,主机来不及读取按键状态。把bInterval从16ms改成8ms,问题就解决了。你想想看,这种实时性要求高的设备,轮询间隔很关键。
注意:中断传输在USB 2.0高速模式下,最大包大小可达1024字节。但别贪心,包越大,占用的总线时间越多,会影响其他设备。
3.4 同步传输(Isochronous Transfer)
同步传输是四种类型里最“任性”的。它追求实时性,但牺牲了可靠性。数据丢了?不重传。CRC错了?直接扔。
为什么这么设计?因为有些数据过期不候。比如USB摄像头、麦克风、音箱。你想想,视频流里丢了一帧,顶多画面卡一下;但如果为了重传等半天,那声音画面就全乱套了。
同步传输的特点:
- 保证带宽:主机预留固定的总线时间。
- 不保证数据正确:没有重传机制。
- 没有握手阶段:发完就完,不确认。
- 只能用于ISO端点。
避坑指南:同步传输的缓冲区设计要小心。我曾经做一个USB音频设备,同步传输的缓冲区太小,导致数据溢出,声音出现爆音。后来把缓冲区加大到4个微帧,问题才解决。
3.5 四种传输类型对比
为了方便记忆,我习惯用一张表来对比:
| 传输类型 | 可靠性 | 实时性 | 带宽保证 | 典型应用 |
|---|---|---|---|---|
| 控制传输 | 高 | 低 | 无 | 枚举、配置 |
| 批量传输 | 高 | 低 | 无 | U盘、打印机 |
| 中断传输 | 高 | 中 | 有(延迟保证) | 鼠标、键盘 |
| 同步传输 | 低 | 高 | 有(带宽保证) | 音频、视频 |
说白了,选哪种传输类型,就看你的应用场景更在乎什么。数据不能丢?用控制或批量。要求实时响应?用中断或同步。
3.6 知识结构图
下面这张图帮你理清四种传输类型的关系和适用场景:
3.7 实际项目中的选择建议
我做了这么多年USB,总结了几条经验:
- 控制传输:只用来做控制和配置。别用它传大数据,效率太低。
- 批量传输:适合数据量大、不要求实时的场景。注意总线竞争,多个批量端点会互相抢带宽。
- 中断传输:适合人机交互设备。轮询间隔别设太大,也别设太小(浪费总线)。
- 同步传输:音频视频首选。但一定要做好丢包处理,应用层要有容错机制。
小技巧:调试时可以用USB分析仪抓包,看看实际传输中用的是哪种类型。我经常用这个方法验证固件配置是否正确。