3、USB协议分层:物理层、协议层、传输层、设备层、功能层的关系与作用

USB协议栈并非单一 monolithic 协议,而是由五个逻辑层次构成的协同体系。理解这五层——物理层、协议层、传输层、设备层、功能层——是掌握USB设备开发(尤其是HID和CDC类设备)的基石。每一层都封装了特定的复杂性,并为上层提供清晰的服务接口。下面这张分层架构图展示了数据从USB主机应用到物理线缆的完整流动路径,以及各层之间的依赖关系。

USB协议五层模型与数据流向 USB 主机 (Host) USB 设备 (Device) 功能层 主机应用软件 (如HID类驱动、CDC驱动) 功能层 设备应用逻辑 (如键盘扫描、串口数据) 设备层 USB核心驱动 (枚举、配置、端点管理) 设备层 USB设备控制器 (端点0、标准请求处理) 传输层 管道(Pipe)管理 (控制/中断/批量/等时) 传输层 端点(Endpoint) (FIFO、传输类型) 协议层 USB协议引擎 (PID、握手、CRC) 协议层 USB协议引擎 (PID、握手、CRC) 物理层 USB PHY (D+/D-) 物理层 USB PHY (D+/D-) 类协议 (HID Report / CDC ACM) 标准设备请求 (SET_CONFIGURATION) 管道/端点通信 包传输 (SETUP/IN/OUT/ACK) USB 2.0 线缆 (D+/D-, VBUS, GND)

上图清晰地展示了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%。

风险提示:物理层设计不当会导致数据包CRC错误、设备掉线等隐蔽问题。在PCB布局时,D+/D-差分对必须等长、紧耦合,并远离时钟和电源干扰源。

3.2 协议层:包结构与传输规则

核心原理

协议层定义了USB通信的基本单元——包(Packet)。每个包由同步字段(SYNC)、包标识符(PID)、数据字段(可选)和循环冗余校验(CRC)组成。协议层负责生成和解析PID(如SETUP、IN、OUT、ACK、NAK、STALL),管理令牌包、数据包和握手包的交互时序。这一层是USB传输可靠性的核心保障。

操作流程:一次完整的控制传输

  1. SETUP阶段:主机发送SETUP令牌包,随后发送8字节的标准请求数据包,设备返回ACK。
  2. DATA阶段:根据请求方向,主机或设备发送DATA0/DATA1数据包,接收方返回ACK。
  3. STATUS阶段:反向传输一个零长度数据包,确认整个控制传输完成。

常见误区

初学者常混淆DATA0和DATA1的切换机制。数据切换(Data Toggle)用于检测丢包和重复包。例如,若主机发送DATA1但设备期望DATA0,设备会返回NAK而非ACK,要求主机重发。忽略此机制会导致通信卡死。

经验要点:在调试协议层问题时,使用USB协议分析仪(如Total Phase Beagle)抓取总线上的原始包序列,比单纯看软件日志更有效。重点观察PID序列是否符合规范,CRC是否报错。

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而非空数据包,以节省总线带宽。

设计建议:对于CDC设备,批量传输端点应使用双缓冲(Double Buffering)来提升吞吐量。在STM32等MCU上,可通过配置端点寄存器启用双缓冲模式,有效减少CPU干预频率。

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口。

重要提醒:设备描述符中的bMaxPacketSize0字段必须与实际端点0 FIFO大小匹配。若声明64字节但实际只有32字节,高速枚举时会导致控制传输失败。

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。否则主机无法区分数据来源。

总结复盘:五层协议栈中,物理层和协议层通常由硬件(USB PHY和SIE)实现,设备层由MCU固件实现,功能层由设备应用逻辑实现。开发时应自底向上逐层验证:先确保物理层信号正常,再验证协议层包交互,然后检查设备层枚举,最后调试功能层数据语义。任何一层出现问题,都会表现为设备无法正常工作,但根因可能在上层或下层。