1. USB通信的基本单元:帧与微帧
当你把手机插上电脑充电时,USB系统正在以每秒数千次的频率进行着精密的时间分割。这种时间管理的基本单位就是帧(全速/低速设备)和微帧(高速设备)。想象一下交响乐团的指挥家,每1毫秒(全速)或125微秒(高速)挥动一次指挥棒,所有设备都必须在这个时间窗口内完成自己的"演奏"。
实测USB 2.0全速设备的示波器波形显示,每个帧都以SOF包(Start of Frame)开始。这个包含11位帧编号的令牌包就像节拍器,主机通过它宣告:"新的时间片开始了!"有趣的是,帧编号达到0x7FF时会自动归零,这意味着大约每8.192秒就会发生一次"千年虫"式的循环。
在高速模式下,事情变得更精细。1毫秒被划分为8个125微秒的微帧,此时SOF包包含的不仅是帧号,还有3位微帧编号。这就好比把原来的节拍细分成了八分音符,让数据传输的粒度更精细。我在调试一个高速摄像头时发现,如果微帧同步出现偏差,视频流就会出现卡顿。
2. 事务:USB交互的原子操作
如果把帧比作时间格子,那么事务就是填充这些格子的基本操作单元。USB定义了三种核心事务类型,每种都像精心设计的对话流程:
2.1 IN事务:设备到主机的数据请求
主机:"你有数据要给我吗?"(IN令牌包) 设备可能回应:
- "有的,这是数据"(DATA0/DATA1包)
- "忙,等会再说"(NAK握手包)
- "别问了,我出问题了"(STALL握手包)
2.2 OUT事务:主机到设备的数据传输
主机:"我要给你发数据了"(OUT令牌包) + "这是数据"(DATA包) 设备可能回应:
- "收到啦"(ACK)
- "忙不过来"(NAK)
- "拒收"(STALL)
2.3 SETUP事务:控制传输的特殊信使
这是控制传输独有的事务,固定使用8字节的DATA0包来传递标准请求命令。我曾在开发USB设备时踩过坑:试图用OUT事务发送控制请求,结果设备直接返回STALL。后来才明白SETUP事务的DATA0包有特殊格式,包含bmRequestType、bRequest等关键字段。
3. 数据传输的四大门派
3.1 控制传输:USB系统的管理员
每个USB设备的第一次"对话"都是通过控制传输完成的。它分为三个阶段:
- 建立阶段:SETUP事务发送8字节请求(如获取描述符)
- 数据阶段:可选IN/OUT事务(如描述符内容)
- 状态阶段:反向传输确认结果
开发USB HID设备时,控制传输的GET_DESCRIPTOR请求返回的数据必须严格符合描述符结构。有次我少填了一个字段,导致Windows无法识别设备,折腾了半天才发现是这个原因。
3.2 中断传输:及时响应的轻骑兵
虽然叫"中断",但实际上是通过轮询实现的。键盘和鼠标使用这种传输,全速下轮询间隔可以是1-255毫秒。实测一个游戏鼠标设置为1毫秒间隔时,其响应速度几乎感觉不到延迟。
3.3 批量传输:可靠的大件搬运工
U盘和打印机依赖这种传输,特点是不占用固定带宽。当总线忙时,批量传输会自动让路。我曾测试过在同时传输视频(同步传输)时拷贝文件,视频流畅但文件传输速度会明显下降。
3.4 同步传输:实时性优先的表演者
摄像头和麦克风使用这种没有握手包的传输。虽然可能丢包,但保证了实时性。一个视频会议设备的数据显示,在USB 2.0下同步传输最多能占用80%的微帧带宽。
4. 物理信号到数据包的转换之旅
4.1 NRZI编码与位填充
USB采用NRZI(反向不归零)编码:数据0时电平翻转,数据1时保持。但连续多个1会导致长时间无电平变化,因此USB规定每6个连续1后强制插入0。解码时再移除这些填充位。
用逻辑分析仪抓取USB数据时,能看到明显的位填充特征。有次调试发现数据错误,最终查明是硬件没有正确处理填充位。
4.2 数据包组装过程
一个完整的USB数据包就像洋葱,层层包裹:
- 同步域(SYNC):0x01,帮助时钟同步
- 包标识域(PID):4位类型+4位反码(如OUT令牌的PID是0xE1)
- 具体内容:地址、端点、数据等
- CRC校验:防止传输错误
5. 实战中的时序管理技巧
USB主机通过精细的调度算法管理多个设备。在开发USB集线器时,我发现:
- 全速设备的事务必须在一个帧内完成
- 高速设备的事务可以跨微帧
- 主机通过事务翻译器处理不同速度设备间的通信
一个典型的调度策略是:
- 先安排周期性传输(中断/同步)
- 再处理控制传输
- 最后调度批量传输
当设备响应超时(通常18个帧周期)时,主机会重置设备端口。这个机制让我想起有次设备固件卡死,Windows自动重置了USB连接,问题神奇地解决了。
理解USB的帧、事务与传输机制,就像掌握了USB世界的交通规则。无论是设计设备还是排查问题,这套知识体系都能帮你快速定位到通信链路中的具体环节。记住,好的USB设计不仅要实现功能,还要考虑如何优雅地与其他设备共享总线带宽。