问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

USB 2.0 详解:数据包格式、传输类型与设备枚举

创作时间:
作者:
@小白创作中心

USB 2.0 详解:数据包格式、传输类型与设备枚举

引用
CSDN
1.
https://blog.csdn.net/Liuqz2009/article/details/142166930

USB(Universal Serial Bus)是一种广泛应用于计算机和外部设备之间的串行总线标准,支持热插拔和即插即用功能。USB 2.0是USB标准的重要版本之一,其传输速度可达480Mbps。本文将详细介绍USB 2.0的数据包格式、传输类型以及设备枚举过程,帮助读者深入了解USB通信机制。

USB数据包格式

1. USB数据包结构

USB总线上传输数据是以包为基本单位,上图表示一个包结构,一个包被分成不同的域(field),不同类型的包所包含的域是不一样的,但是所有的包都有一个共同点,就是都要以同步域(SYNC)开始,紧跟着一个包标识符PID(Packet Identifier),最终以包结束符EOP(End of Packet)来结束这个包。

  • SOP:用来表示包的起始
  • SYNC:用来同步时钟,在很多文档里,把SOP和SYNC统一称为 “SYNC” ,它的意思是 “SYNC” 中含有 “SOP” 。
  • PID:表示包的类型
  • 地址:发给所有设备时包里不含有设备地址;发给某个设备时包里含有设备地址、端点号
  • 帧号、数据等跟PID相关的内容
  • CRC校验码

发起一次完整的传输,可能涉及多个包。那么,第1个包里含有设备地址、端点号,后续的包就没必要包含设备地址、端点号。

1.1 SOP

低速/全速

SOP:Start Of Packet,SOP就是 Hub 驱动D+、D-这两条线路从Idle状态跳变为K状态,这就是开始传输的信号。

1.2 SYNC 域

SYNC 可以用来同步主机端和设备端的数据时钟,对于低速和全速设备,SYNC使用的是00000001(二进制数,总线上的发送顺序),经过 NRZI 编码后的波形如下:

1.3 PID 域

包标识符PID是用来标识一个包的类型的,PID 有8位,但实际使用的只有4位,前4位表示PID,后4位是前 4 位的取反。接收方发现后 4 位不是前 4 位的取反的话,就认为发生了错误。格式如下:

根据包数据里的PID的bit1,bit0可以分为4类:

  • 令牌包(Token):01B
  • 数据包(Data):11B
  • 握手包(Handshake):10B
  • 特殊包(Special):00B

根据bit3,bit2进一步细分。如下表(来自《圈圈教你玩USB》)所示:

1.4 EOP

EOP:End Of Packet,由数据的发送方发出EOP,数据发送方驱动D+、D-这两条线路,先设为SE0状态并维持2位时间,再设置为J状态并维持 1 位时间,最后 D+、D- 变为高阻状态,这时由线路的上下拉电阻使得总线进入Idle状态。

SE0 的意思就是,D+ 和 D- 同时都保持为低电平。

2. 包的类别

2.1 令牌包(Token)

令牌包分为四种,分别为输出 (OUT),输入(IN),建立(SETUP) 和帧起始(SOF, Start Of Frame)。

对于OUT、IN、SETUP令牌包,它们都是要通知到具体的设备,具有相同的结构:同步域 (SYNC),包标识域 (PID),地址域 (ADDR),端点域 (ENDP),CRC5校验域 (CRC5) 和包结束 (EOP),格式如下:

SOF令牌包格式如下:

2.2 数据包

Host使用令牌包(OUT、IN、SETUP)来通知设备:我要传输数据了。紧跟着通过 “数据包” 进行传输数据。

数据包都具有相同的结构,格式如下:

2.3 握手包

握手包用来表示一个传输是否被对方确认。握手包只有同步域、PID和EOP,格式如下:

握手包有4类:ACK、NAK、STALL、NYET

  • ACK:数据接收方用来回复发送方,表示正确接收到了数据并且有足够的空间保存数据,主机和设备都可以使用ACK来确认。
  • NAK:NAK表示没有数据需要返回,或者数据正确接收但没有足够的空间来容纳,Host发送数据给设备时,Host 读到设备回应的NAK时,就知道设备未准备好,主机会在合适的时机重新传输。
  • STALL:表示发生了错误,比如设备无法执行这个请求(不支持该断点等待)、断点已经挂起。设备返回STALL后,需要主机进行干预才能解除STALL状态。
  • NYET:仅适用于高速设备。表示设备本次数据成功接收,但没有足够的空间接收下一次数据。

NAK,STALL,NYET只有设备能返回,主机不能使用这些握手包。

USB传输类型

1. 传输(Transfer)和事务(Transaction)

USB协议定义了四种传输类型,批量传输、中断传输、实时传输、控制传输。暂时记住这个关系:

  • BIT组成域(Field)
  • 域组成包(Packet)
  • 包组成事务(Transaction)
  • 事务组成传输(Transfer)

传输和事务的对应关系如下:

一个批量/中断/实时传输由一个批量/中断/实时事务实现。

一个控制传输由多个事务实现。

2. 批量传输

批量事务由3个阶段(phase)组成:令牌阶段 (Token) 、数据阶段 (Data) 、握手阶段 (Handshake) 。每个阶段都是一个完整的包,所谓完整的包就是这个包里面含有 SOP、SYNC、PID、EOP。

下图是一个批量事务的流程图,各个矩形框就对应一个完整的包。

下图解释一下批量输入事务的流程:

下图解释一下批量输出事务的流程:

高速设备中增加了PING令牌包:

使用usbprotocolsuite工具来看一下 USB 数据的格式,是 LeCroy(力科)公司的 USB 协议分析软件,百度搜索 “usbprotocolsuite” 就可以安装。

下图是一个批量输入传输:

下图是一个批量输出传输:

3. 中断传输

中断事务由3个阶段(phase)组成:令牌阶段、数据阶段、握手阶段。每个阶段都是一个完整的包,所谓完整的包就是这个包里面含有SOP、SYNC、PID、EOP。

下图是一个中断事务的流程图,各个矩形框就对应一个完整的包。

4. 实时传输

实时事务由2个阶段(phase)组成:令牌阶段、数据阶段。每个阶段都是一个完整的包,所谓完整的包就是这个包里面含有SOP、SYNC、PID、EOP。

下图是一个实时事务的流程图,各个矩形框就对应一个完整的包。

5. 控制传输

控制传输相比之前三种传输要复杂一点,控制传输分为3个过程:

  • 建立过程(stage),使用 (建立)SETUP事务,建立事务的流程如下:

  • 数据过程(stage),使用批量事务:

数据过程是可选的,就是说一个控制传输可能没有数据过程,如果有,数据过程是使用批量事务实现的。

  • 控制写传输:由批量输出事务实现
  • 控制读传输:由批量输入事务实现

需要注意的是,数据过程中所有的事务必须是同一个方向的,比如控制写传输,所有的事务必须是批量输出事务,一旦数据传输方向发生了改变,就认为进入了状态过程。

  • 状态过程(stage),使用批量事务:

  • 控制写传输:由批量输入事务实现,和数据过程相反

  • 控制读传输:由批量输出事务实现,和数据过程相反

状态过程中设备会向主机报告之前建立过程和数据过程的结果,控制读和控制写都会返回三种结果,如下图所示:

如下图,是一个控制传输:

在上图中,状态过程设备返回ACK表示之前的操作已经成功完成。

下图表示几种控制传输的框图,每一个方框都表示一个完整的事务:

枚举

1. 什么是枚举

当一个USB设备连接至USB主机,就要对设备进行枚举,所谓枚举就是从设备读取各种描述符信息,这样主机就可以根据这些信息加载合适的驱动程序,并且知道设备是什么样的设备。

这个枚举过程就会使设备的状态发生一系列的改变,如下图是一个USB设备的状态切换图:

各个状态的描述如下表:

2. 回顾控制传输

传输类型在之前的文章中有介绍,现在再来详细看一下控制传输,因为在设备的枚举过程中都是使用控制传输。

控制传输分为三个过程:建立过程,数据过程(可选),状态过程。

建立过程如下图所示:

在建立过程中的SETUP令牌包,只是通知要开始一个控制传输,那么到底是读数据还是写数据,读/写什么数据是由数据包DATA0的内容决定的,那么数据包DATA0的内容是什么呢?用一个实际的例子来说明一下:

下图是一个控制传输的建立过程,图中红框就是DATA0数据包的数据部分。我们来看一下这些数据具体代表什么意义。

3. USB设备的枚举过程

复位后主机为什么需要再次获取设备描述符呢?

这是因为有些USB设备的端点0的最大包长度为8字节(USB 规定端点 0 的最大包长至少有 8 字节长),而设备描述符有18个字节,所以第一次获取设备描述时如果要想获取全部的描述符需要多次获取,而实际上系统只是取前8字节的设备描述符,后续的数据是不再获取的,这样有可能获取的描述符是不完全的,而复位后是要获取设备描述符的全部18字节。

4. 使用 usbprotocolsuite

了解了设备的枚举过程,那么实际是不是这样呢,我们使用usbprotocolsuite看一下:

  1. 主机获取设备描述符

  2. 分配地址

  3. 使用新地址再次获取设备描述符

  4. 获取字符串描述符(如果有)

  5. 获取配置描述符

注意这里返回的不仅有配置描述符,接口描述符,端点描述符不能单独获取,必须跟随配置描述符以一个集合的方式一并返回。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号