3、USB协议分层:物理层、协议层、传输层、设备层、功能层的关系与作用
USB协议栈并非单一 monolithic 协议,而是由五个逻辑层次构成的协同体系。理解这五层——物理层、协议层、传输层、设备层、功能层——是掌握USB设备开发(尤其是HID和CDC类设备)的基石。每一层都封装了特定的复杂性,并为上层提供清晰的服务接口。下面这张分层架构图展示了数据从USB主机应用到物理线缆的完整流动路径,以及各层之间的依赖关系。
上图清晰地展示了USB协议栈的对称性:主机侧与设备侧在每一层都有对应的软件或硬件模块。物理层是唯一直接通过线缆连接的层次,而其余各层则通过逻辑通道(管道)进行通信。下面我们逐层深入分析其作用与实现要点。
3.1 物理层:信号与电气特性的基石
核心原理
物理层定义了USB信号在铜线上的电气特性、时序要求和机械连接规范。对于USB 2.0,它使用一对差分信号线D+和D-,通过差分信号传输来抑制共模噪声。信号速率分为低速(1.5 Mbps)、全速(12 Mbps)和高速(480 Mbps)。物理层还负责检测设备连接/断开(通过上拉/下拉电阻)、复位信号、以及总线供电(VBUS)管理。
判断方法
在调试物理层问题时,通常使用示波器测量D+/D-波形。关键检查点包括:
- 静态电平:设备空闲时,D+(全速/高速)或D-(低速)应被上拉至3.3V,主机侧D+/D-均有15kΩ下拉电阻。
- 差分摆幅:全速信号差分幅度应在400mV±10%范围内。
- 眼图测试:高速模式需通过眼图模板验证信号完整性。
案例拆解:USB线缆过长导致枚举失败
某工业设备使用5米USB延长线连接HID键盘,出现间歇性无法识别问题。示波器测量发现D+上升沿过缓,信号摆幅降至300mV。分析原因是线缆电阻过大加上设备端上拉电阻驱动能力不足。解决方案:更换为带信号中继器的有源延长线,并在设备端增加驱动增强电路。修改后眼图测试通过,枚举成功率从82%提升至99.9%。
3.2 协议层:包结构与传输规则
核心原理
协议层定义了USB通信的基本单元——包(Packet)。每个包由同步字段(SYNC)、包标识符(PID)、数据字段(可选)和循环冗余校验(CRC)组成。协议层负责生成和解析PID(如SETUP、IN、OUT、ACK、NAK、STALL),管理令牌包、数据包和握手包的交互时序。这一层是USB传输可靠性的核心保障。
操作流程:一次完整的控制传输
- SETUP阶段:主机发送SETUP令牌包,随后发送8字节的标准请求数据包,设备返回ACK。
- DATA阶段:根据请求方向,主机或设备发送DATA0/DATA1数据包,接收方返回ACK。
- STATUS阶段:反向传输一个零长度数据包,确认整个控制传输完成。
常见误区
初学者常混淆DATA0和DATA1的切换机制。数据切换(Data Toggle)用于检测丢包和重复包。例如,若主机发送DATA1但设备期望DATA0,设备会返回NAK而非ACK,要求主机重发。忽略此机制会导致通信卡死。
3.3 传输层:端点与管道机制
核心原理
传输层引入了端点和管道的概念。每个USB设备有最多16个端点(端点0-15),每个端点有方向(IN/OUT)和传输类型(控制、中断、批量、等时)。管道是主机端点到设备端点的逻辑连接。传输层负责将协议层的包组织成有意义的传输事务,并管理带宽分配和错误重试策略。
| 传输类型 | 典型应用 | 带宽保证 | 错误重试 | 最大包长(全速) |
|---|---|---|---|---|
| 控制 | 枚举、配置 | 固定10% | 自动重试 | 64字节 |
| 中断 | HID键盘/鼠标 | 轮询保证 | 自动重试 | 64字节 |
| 批量 | CDC数据、U盘 | 无保证 | 自动重试 | 64字节 |
| 等时 | 音频、视频 | 固定带宽 | 不重试 | 1023字节 |
实战场景:HID设备中断传输配置
一个HID鼠标设备,报告描述符定义输入报告为4字节(X、Y坐标和按键)。在配置描述符中,中断IN端点需设置轮询间隔为10ms(bInterval=10)。主机将每10ms发送一次IN令牌,设备收到后返回数据包。若设备没有新数据,应返回NAK而非空数据包,以节省总线带宽。
3.4 设备层:枚举与设备框架
核心原理
设备层负责USB设备的枚举过程,即设备如何被主机识别和配置。核心是设备描述符、配置描述符、接口描述符和端点描述符的层级结构。设备通过端点0响应主机的标准请求(GET_DESCRIPTOR、SET_ADDRESS、SET_CONFIGURATION等)。设备层还管理设备的地址分配、电源配置和远程唤醒功能。
判断方法:枚举失败排查
- 检查设备描述符:使用USB分析仪查看设备是否返回正确的设备描述符(VID/PID、设备类、端点0最大包长)。
- 验证地址设置:主机发送SET_ADDRESS后,设备必须使用新地址响应后续请求。
- 配置选择:主机发送SET_CONFIGURATION(1)后,设备应使能配置描述符中声明的所有端点。
案例拆解:CDC设备枚举失败
某CDC虚拟串口设备在Windows下提示“无法识别的USB设备”。分析仪抓包发现设备在响应GET_DESCRIPTOR(Configuration)时返回的数据长度不完整。原因是配置描述符中接口关联描述符(IAD)的bFirstInterface和bInterfaceCount字段设置错误,导致主机解析描述符失败。修正IAD字段后,设备正常枚举为COM口。
3.5 功能层:类协议与设备应用
核心原理
功能层是USB协议栈的最顶层,定义了特定设备类的行为规范。HID类使用报告描述符(Report Descriptor)描述输入/输出数据的格式和含义;CDC类则定义了抽象控制模型(ACM)和通用串行总线(USB)之间的桥接。功能层不关心底层传输细节,只关注数据语义。
操作流程:HID报告描述符解析
// 一个简单的HID鼠标报告描述符示例
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x03, // Usage Maximum (3)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
0x95, 0x01, // Report Count (1)
0x75, 0x05, // Report Size (5)
0x81, 0x01, // Input (Constant)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0x81, 0x06, // Input (Data, Variable, Relative)
0xC0, // End Collection
0xC0 // End Collection
常见误区
HID设备开发者常忽略报告描述符中的Report ID。当设备有多个报告(如键盘和多媒体键)时,必须为每个报告分配唯一ID,并在数据包首字节发送该ID。否则主机无法区分数据来源。