1. USB协议概述:从诞生到现在的技术演进
大家好,我是这次课程的主讲工程师。做嵌入式这些年,USB协议可以说是我打交道最多的接口之一了。从早期的USB 1.1到现在的USB4,这个协议栈变得越来越复杂,但核心思想其实一直没变——让设备之间能方便地通信。
这一章我们先打好基础,把USB的发展脉络、2.0和3.x的核心差异、以及物理层那些容易踩坑的细节理清楚。嗯,这些内容看似基础,但我在项目里见过太多人因为忽略物理层特性导致枚举失败的情况了。
1.1 USB的发展历史
USB(Universal Serial Bus)最初是1996年由Intel、Microsoft、IBM等公司联合推出的。当时的目标很明确:取代PC上那些乱七八糟的串口、并口、PS/2接口,实现真正的即插即用。
我最早接触USB是在2003年做一款数据采集卡,那时候用的还是USB 1.1 Full Speed,12Mbps的速率现在看来慢得可怜,但在当时已经比串口快了两个数量级。
| 版本 | 推出时间 | 理论速率 | 编码方式 | 关键特性 |
|---|---|---|---|---|
| USB 1.0 | 1996 | 1.5 Mbps (Low Speed) | NRZI | 最初规范,实际很少产品 |
| USB 1.1 | 1998 | 12 Mbps (Full Speed) | NRZI | 真正普及的版本 |
| USB 2.0 | 2000 | 480 Mbps (High Speed) | NRZI | 微帧、事务分割 |
| USB 3.0 | 2008 | 5 Gbps (SuperSpeed) | 8b/10b | 双总线架构、全双工 |
| USB 3.1 | 2013 | 10 Gbps (SuperSpeed+) | 128b/132b | Type-C接口引入 |
| USB 3.2 | 2017 | 20 Gbps | 128b/132b | 双通道聚合 |
| USB4 | 2019 | 40 Gbps | 128b/132b | 基于Thunderbolt 3 |
1.2 USB 2.0与3.x的核心区别
很多人以为USB 3.0就是USB 2.0的"提速版",其实不然。说白了,3.0几乎重新设计了一套物理层和协议层。我当年第一次看USB 3.0规范时,发现它和2.0的差异比想象中大得多。
1.2.1 总线架构的差异
USB 2.0是半双工、主机轮询的共享总线架构。所有设备共享一条数据线,主机挨个问设备"你有没有数据要发?"——效率确实不高。
USB 3.0则引入了双总线架构:保留了USB 2.0的D+/D-线用于兼容,同时新增了SSTX/SSRX两组差分对,实现全双工通信。这意味着设备可以同时收发数据,不再需要等主机轮询。
1.2.2 编码方式的区别
USB 2.0使用NRZI(Non-Return-to-Zero Inverted)编码,配合位填充(Bit Stuffing)来保证时钟同步。这种编码方式简单,但效率不高——连续6个1就要插入一个0,实际有效数据率会打折扣。
USB 3.0改用8b/10b编码(3.0)和128b/132b编码(3.1+)。8b/10b把8位数据映射成10位符号,虽然多了20%的开销,但提供了DC平衡、时钟恢复和错误检测能力。到了128b/132b,开销降到3%左右,效率大幅提升。
// USB 2.0 NRZI编码示例(伪代码)
// 数据: 0x55 (01010101)
// NRZI: 电平翻转表示0,电平不变表示1
bit_stuffing_threshold = 6; // 连续6个1插入0
// USB 3.0 8b/10b编码示例
// 数据字节: 0x55 -> 8b/10b符号: D.21.0
// 实际传输的是10位符号,包含运行差异控制
1.2.3 电源管理的差异
USB 2.0的电源管理比较粗糙——设备要么唤醒,要么挂起。USB 3.0引入了更细粒度的电源状态:U0(活动)、U1(待机)、U2(休眠)、U3(挂起)。设备可以在微秒级时间内切换状态,这对电池供电的移动设备非常友好。
| 特性 | USB 2.0 | USB 3.0/3.x |
|---|---|---|
| 数据传输方向 | 半双工 | 全双工 |
| 信号线数量 | 2 (D+/D-) | 6 (D+/D- + SSTX/SSRX + GND) |
| 编码方式 | NRZI + 位填充 | 8b/10b 或 128b/132b |
| 传输单位 | 帧 (1ms) / 微帧 (125μs) | 数据包 + 链路管理包 |
| 主机控制方式 | 轮询 (Polling) | 异步 + 轮询混合 |
| 电源状态 | 2种 (活动/挂起) | 4种 (U0/U1/U2/U3) |
| 向后兼容 | — | 保留USB 2.0通道 |
1.3 USB的物理层与电气特性
物理层是USB协议栈的最底层,也是问题最多的地方。我调试过的枚举失败案例,至少有一半是物理层的问题——电平不对、终端电阻错了、线缆太长导致信号衰减。
1.3.1 USB 2.0物理层
USB 2.0使用一对差分信号线D+和D-,特性阻抗要求90Ω ±15%。信号电平是3.3V(实际规范是3.0V-3.6V),但接收端的阈值是0.8V和2.0V——这个余量设计得挺大,就是为了抗干扰。
设备端的上拉电阻是识别设备速度的关键:
- Low Speed (1.5 Mbps): D-线上拉1.5kΩ到3.3V
- Full Speed (12 Mbps): D+线上拉1.5kΩ到3.3V
- High Speed (480 Mbps): 先以Full Speed上拉D+,收到复位信号后切换为电流驱动模式
主机端的下拉电阻是15kΩ到GND。设备插入时,主机通过检测D+或D-的电平变化来感知设备插入,并判断速度等级。
1.3.2 USB 3.0物理层
USB 3.0的物理层复杂得多。除了保留2.0的D+/D-,还新增了SSTX+/SSTX-(发送差分对)和SSRX+/SSRX-(接收差分对)。这些差分对的特性阻抗也是90Ω,但信号电平只有1.0V左右,摆幅更小,频率更高。
3.0的接收端均衡(Equalization)是个关键点。因为5Gbps的信号在铜线上衰减很严重,接收端必须做CTLE(连续时间线性均衡)和DFE(判决反馈均衡)来恢复信号质量。
// USB 3.0 物理层初始化流程(简化)
1. 设备插入,2.0通道先完成枚举
2. 主机发送LFPS(低频周期性信号)唤醒3.0通道
3. 双方进行Rx Detect,确认对方存在
4. 训练均衡器(EQ Training)
5. 进入U0状态,开始数据传输
1.3.3 线缆与连接器
线缆质量直接影响信号完整性。USB 2.0 High Speed的线缆最长5米,而USB 3.0的线缆建议不超过3米——频率高了,损耗自然更大。
Type-C接口的出现解决了"正反插"的痛点,但也带来了新的挑战:CC(Configuration Channel)线用于检测插头方向、协商供电和替代模式。我在做Type-C项目时,CC逻辑的调试花了不少时间。
| 参数 | USB 2.0 | USB 3.0 | USB 3.1/3.2 |
|---|---|---|---|
| 信号速率 | 480 Mbps | 5 Gbps | 10/20 Gbps |
| 信号摆幅 | 3.3V | 1.0V | 1.0V |
| 差分阻抗 | 90Ω ±15% | 90Ω ±15% | 90Ω ±15% |
| 最大线缆长度 | 5m | 3m | 1m (20Gbps) |
| 连接器类型 | Type-A/B, Mini, Micro | Type-A/B, Micro-B | Type-C为主 |
| 终端电阻 | 设备: 1.5kΩ上拉 主机: 15kΩ下拉 |
设备/主机: 差分终端匹配 | 设备/主机: 差分终端匹配 |
1.4 USB协议栈的整体架构
在进入后续章节之前,我们先从整体上看一下USB协议栈的分层结构。这样你在学习状态机设计时,心里有个全局图。
从这张图可以看到,USB协议栈从下到上分为五层。我们这门课的重点是协议层、链路层和设备层的状态机设计,以及枚举调试的实战技巧。物理层的问题通常用示波器和逻辑分析仪排查,而协议层以上的问题更多靠USB分析仪和固件调试。