一文读懂 USB 协议:大话通用串行总线,从历史、架构到端点通信(下)
1.USB 的数据传输和数据包
1.1 USB 数据传输
USB 是一种异步的串行通信方式(USB 2.0 协议为半双工通信),同一时间总线上只有一包数据在传送。在 USB 总线上,数据是小端的, 也就是说先发送最低位,再发送最高位。
USB 上的数据信号线采用的是一对差分信号,信号 D+ 和信号 D-,可以表示两种数据:
- Diff.1:当 D+ 为高电平、D-为低电平时,该数据称为“差分 1”
- Diff.0:当 D+ 为低电平,D-为高电平时,该数据称为“差分 0”
Diff.1 和 Diff.0 是 USB 信号物理层的差分信号,在表示的数据方面,数据采用的是 NRZI 反相不归零的编码方式:
- 当 NRZI 编码数据为'0'时:差分信号电平翻转,差分数据变化
- 当 NRZI 编码数据为'1'时:差分信号保持电平,差分数据不变

需要注意的是,差分数据和 NRZI 编码数据之间的关系:当USB传输"数据 0"时,物理层会产生"diff.0"的差分数据,但"diff.0"信号不一定代表"数据 0",也有可能是 NRZI 编码中的电平翻转。
如果总线上连续发送很多个'1',将导致电平长时间不翻转,这样不利于主从设备两端的时钟同步(USB 协议没有单独的时钟线)。 因此,USB 协议中规定了以下机制:

- 位填充(Bit Stuffing):
- 当 USB 数据线上连续出现 6 个"1"时,会强制插入一个"0"位作为同步信号
- 这种位填充操作可以保证电平的翻转,接收端使用这段同步码来同步自己的接收时钟,与发送端保持一致
- 接收端去填充:
- 接收端在解码数据时,需要识别并去除这些填充的"0"位
- 用户无需进行此操作,由芯片进行实现
- 可以还原出原始的数据序列
1.2 USB 数据包
在 USB 总线上,数据传输的基本单位是数据包(Packet),每个数据包由多个不同的域组成,具体包括:
- 同步域(SYNC)

-
用于帮助接收端同步时钟和数据
-
由一组数据 0 和一个数据 1 组成,一组数据 0 将导致总线上的电平连续的翻转
-
根据 NRZI 编码,接收端可以根据电平翻转的频率,与发送端同步时钟
-
全速/低速设备发送 7 个 0,高速设备发送 31 个 0
-
包标识符(PID, Packet Identifier)
- 标识当前数据包的类型,如 TOKEN、DATA、HANDSHAKE 等
- PID 有 8 位数据,但我们只能只用其中的低四位数据,高四位数据是低四位数据的补码,用于校验
-
其他域
- 根据不同类型的数据包,可能包含地址、数据负载、校验等其他域
-
包结束符(EOP, End of Packet)
![4.PNG]()
- 标识当前数据包的结束
- 全速和低速设备同时保持 D+ 和 D-为低电平两个数据位,也就是两个数据位的 SE0 信号
- 高速设备则用的是位填充错误信号,主机需要检查 CRC 校验位:
- 如果通过则是 EOP 包结束符
- 没有通过则是位填充错误
对于任何包,都是以一个同步域和一个 PID(包标识符,Packet Identifier)开始,以 EOP(包结束符,End Of Packet)结束的。
这些不同的域组成了 USB 数据包的标准格式。根据数据包的不同用途,USB 协议定义了多种类型的数据包,如:
- 令牌包(Token Packet)
- 包含地址和端点信息,用于标识数据传输的目标
- 包括 OUT、IN、SETUP 等类型
- 数据包(Data Packet)
- 传输实际的数据
- 包括 DATA0 和 DATA1 两种数据包类型
- 握手包(Handshake Packet)
- 用于传递传输状态信息,如 ACK、NAK、STALL 等
- 特殊包(Special Packet)
- 包括 SOF(Start of Frame)、RESET、SPLIT 等特殊用途的数据包,完成同步、复位等特殊功能
具体数据包规定如下表所示:

接下来,我们逐一对各个数据包进行介绍。
1.2.1 令牌包(Token Packet)
在 USB 系统中,所有的数据传送事务都是由主机发送一个令牌包开始的。

令牌包由以下几个域组成:
- SYNC - 同步域:用于帮助接收端同步时钟和数据
- PID - 包标识符:表示当前为令牌包,值为 OUT、IN、SOF 或 SETUP
- ADDR - 设备地址:指明数据传输的目标设备地址
- ENDP - 端点号:指明数据传输的目标端点号
- CRC5 - 5 位循环冗余校验:用于检验前面字段的完整性
- EOP - 包结束符:标识当前令牌包的结束

上表中列出的 4 种令牌包中,OUT、IN、SETUP 包的数据格式是一样的。 SOF 令牌包则略有不同。每种令牌包的 CRC5 校验只校验 PID 之后的数据:
- OUT 令牌包:
- 主机通知设备即将向其发送数据包
- 设备需要准备接收数据
- IN 令牌包:
- 主机告知设备需要从其读取数据
- 设备需要准备发送数据
- SETUP 令牌包:
- 与 OUT 类似,通知设备即将发送一个数据包
- 但随后的数据包只能是 DATA0,且只能发送到控制端点
- SOF(Start of Frame)令牌包:
- 主机周期性发送,用于与设备之间的同步
1.2.2 数据包(Data Packet)
数据包的结构固定为:同步域和 PID 之后跟着 N 个字节的数据,最后是 16 位的 CRC16 校验和包结束符 EOP。

其中,PID 可以为 DATA0 或 DATA1,DATA0 和 DATA1 是两种不同类型的数据包,这是一种确保在高速传输模式下数据传输可靠性的机制,在 USB1.1 协议中,就定义了 DATA0 和 DATA1 两种数据包:
- DATA0 和 DATA1 的交替使用:
- 主机和设备在传输数据时会交替使用这两种数据包类型
- 帮助接收端识别数据包的先后顺序
- 容错纠错机制:
- 当接收端检测到数据包类型不匹配时,会认为上次传输发生了错误
- 这会触发重传机制,提高数据传输的可靠性
- 数据包类型切换:
- 主机和设备各自维护一个数据包类型切换状态机
- 在成功发送或接收数据后,会切换到下一种数据包类型
在 USB2.0 中又增加了 DATA2 和 MDATA 包,用于高速分裂事务和高速高带宽同步传输中:
- DATA2 数据包
- 用于高速分裂事务(High-Speed Split Transaction)
- 在 USB Host 和高速设备之间进行分裂式数据传输时使用
- 提高了主机和高速设备之间的互操作性
- MDATA 数据包
- 用于高速高带宽同步传输(High-Speed High-Bandwidth Isochronous)
- 可以在一个微帧(Microframe)内传输多个数据包
- 满足对实时性和带宽有严格要求的应用
1.2.3 握手包(Handshake Packet)
握手包有同步域、PID 和 EOP,用于确认一次传输:

常见的握手包类型有以下几种:
- ACK:主机或设备成功接收数据
- NAK:设备通知主机数据还未准备好
- STALL:设备的端点被挂起
- NYET:表示设备本次数据成功接收,但没有足够的空间来接收下一次数据
1.2.4 特殊包(Special Packet)
特殊包用于一些特殊功能,包括:
- SOF (Start of Frame)
- 主机周期性发送的特殊包
- 用于与设备之间进行同步
- 包含 1 毫秒为单位的帧号
- RESET
- 主机发送以复位 USB 设备
- 设备在收到 RESET 后进入默认状态
- SPLIT
- 用于实现高速设备和全/低速设备之间的分裂事务
- 主机先发 SPLIT 包给全/低速设备,再进行数据传输
- ERR
- 标识高速分裂事务中出现错误
- PING
- 主机发送以检查高速设备是否准备好接收数据
- 高速设备回复 ACK 或 NAK,可用于用于高速设备的流控
2.USB 的数据帧和事务
USB 数据传输中,最顶层的单位是一个数据帧,每个帧持续 1 毫秒。一帧由帧起始 (SOF) 数据包和一个或多个事务组成,SOF 标志着 USB 总线上新帧的开始。

USB 的基本传输单元称为事务(Transaction),一个完整的事务包括以下几个步骤:
- 令牌阶段(Token Phase)
- 主机发送令牌包 Token Packet,指明本次事务的目标设备和端点
- 令牌包包括 IN、OUT 和 SETUP 三种类型,分别用于指示数据传输的方向和类型
- 数据阶段(Data Phase)
- 如果有数据需要传输,主机或设备会发送数据包 Data Packet
- 数据包的大小受端点最大包长度的限制
- 数据传输可以是 IN 方向(从设备到主机)或 OUT 方向(从主机到设备)
- 状态阶段(Status Phase)
- 接收方发送握手包 Handshake Packet,表示数据传输的状态(成功/失败)
这三个阶段组成了一个完整的 USB 事务。主机根据设备的端点类型,采用不同的事务类型,如控制、批量、中断和等时传输。主机会根据设备描述符信息,合理地调度各个设备之间的事务,避免冲突,确保公平性。这种分阶段的事务机制,使得 USB 协议能够灵活地适应不同类型数据传输的需求,为设备提供高效稳定的工作环境。
综合上述内容,可以看到数据帧(Frame)、传输事务(Transaction)和数据包(Packet)之间的关系如下:

- 数据帧提供了时间同步和调度的基本框架
- 传输事务是在一个数据帧内完成的基本数据交互单元
- 每个事务由多个数据包组成,数据包是最小的传输单元

USB 是一种异步的串行通信方式(USB 2.0 协议为半双工通信),同一时间总线上只有一包数据在传送。在 USB 总线上,数据是小端的, 也就是说先发送最低位,再发送最高位

浙公网安备 33010602011771号