文章目录
- 数据包结构
- 包(Packet)
- PID
- 令牌包
- SETUP&OUT&IN令牌包
- SOF令牌包
- 数据包
- 握手包
- ACK 握手包
- NAK 握手包
- 事务(Transaction)
- Setup事务
- OUT事务
- IN事务
- 传输(Transfer)
- 控制传输
- 中断传输
- 批量传输
- 同步传输/等时传输
- 端点
数据包结构
USB的通讯数据由多个传输组成,一个传输内会存在多个事务,一个事务中同样会存在多个数据包。
包(Packet)
数据包可以被认为是数据传输的最小元素。每个数据包以当前传输速率传输整数个字节。数据包以同步模式开始,随后是数据包的数据字节,并以数据包结束 (EOP) 信号结束。所有 USB 数据包模式都先传输最低有效位。数据包前后,总线处于空闲状态。
USB协议定了多种类型的包,有令牌包、数据包和握手包。
PID
USB协议定义的包格式PID由8位组成,低4位是类型字段,高4位为低四位的补码。
下表中列举的USB2.0数据包中可能存在的PID。
PID | 含义 | 说明 |
---|---|---|
0001 | 令牌OUT | 主机发送数据到USB设备 |
1001 | 令牌IN | 主机接收从USB设备发出的数据 |
0101 | 令牌SOF | 此时作为一个帧或者小帧的开始信息 |
1101 | 令牌SETUP | 主机向USB设备发送配置信息 |
0010 | 握手ACK | 数据正确接收 |
1010 | 握手NAK | 数据未正确接收 |
1110 | 握手STALL | 使用的端点被挂起 |
0110 | 握手NYET | 接收方没有响应 |
0011 | 数据DATA0 | 数据包偶数包 |
1011 | 数据DATA1 | 数据为奇数据包 |
0111 | 数据DATA2 | 此为作为一个高速同步事务的专用数据包 |
1111 | 数据MDATA | 此时作为一个SPLIT事务的专用数据包。 |
1100 | PRE令牌包 | 低速数据的先导包 |
1100 | 特殊用途ERR | SPLIT事务中表示出现错误 |
1000 | 特殊用途SPLIT | 高速主使用事该SPLIT事务解决从高速模式到低速和全速模式的转换 |
0100 | 特殊用途PING | 仅用于高速模式下主机使用该事务判断设备是否可以接收数据 |
令牌包
令牌包全部由USB主机发出,其内容包括包标识PID,包目标地址ADDR,包目标地址(ENDP)和CRC5校验位域。
令牌包指明了后续数据包的目标地址和端点。
令牌包的PID有:
PID | 含义 | 说明 |
---|---|---|
0001 | 令牌OUT | 主机发送数据到USB设备 |
1001 | 令牌IN | 主机接收从USB设备发出的数据 |
0101 | 令牌SOF | 此时作为一个帧或者小帧的开始信息 |
1101 | 令牌SETUP | 主机向USB设备发送配置信息 |
1100 | PRE令牌包 | 低速数据的先导包 |
1000 | 特殊用途SPLIT | 高速主使用事该SPLIT事务解决从高速模式到低速和全速模式的转换 |
0100 | 特殊用途PING | 仅用于高速模式下主机使用该事务判断设备是否可以接收数据 |
SETUP&OUT&IN令牌包
这三种令牌包格式由8位的包标识字段PID,7位的地址字段ADDR、4位的段点字段和5位的循环字段CRC共24位3字节组成。
- 包标识字段PID:定义了数据传输方向
- ADDR字段:指明了USB设备地址。
- ENDP字段:指明了接收数据的端点号。
- CRC字段:用于ADDR字段和ENDP字段进行循环冗余校验。
注意:
- 从令牌包的ADDR可以看到,USB设备的地址为7位,所以从这里也反映了出了一条USB总线为什么支持127个设备(1-127,其中地址0用于设备的初始化)。2^7=128
- 另外,从从ENDP可以看到,ENDP占4位,所以一个USB设备最大支持16个双向通道。
SOF令牌包
SOF令牌包是最广泛的令牌包,由主机发送。主要作用是以防止USB设备进入挂起状态,也用于USB主机和USB设备之间进行时钟同步、调整。
SOF令牌包包格式由8位的包标识字段PID,11位的帧号字段和5位的循环字段CRC共24位3字节组成。
- 包标识字段PID:定义了数据传输方向为USB主机到USB设备。
- 帧号字段:指明了USB传输的帧号,其11位。
- CRC字段:用于帧号字段进行循环冗余校验。
数据包
USB主机发出的包在USB总线上广播,所有在USB总线上的设备需要根据自己的设备地址对由USB主机广播的令牌包进行过滤。如果该令牌包的地址与其自身地址不匹配,USB设备默认不处理即忽略该令牌包。
常用的数据包有以下几种:
PID | 含义 | 说明 |
---|---|---|
0011 | 数据DATA0 | 数据包偶数包 |
1011 | 数据DATA1 | 数据为奇数据包 |
0111 | 数据DATA2 | 此为作为一个高速同步事务的专用数据包 |
1111 | 数据MDATA | 此时作为一个SPLIT事务的专用数据包。 |
数据包中并没有其传输的目的地址和端点信息,所以数据包必须紧跟在令牌包之后。
数据包是用于传输数据的,由8位的包标识PID,数据字段和16位的循环冗余校验字段CRC组成。
在USB高速同步传输过程中,通过抓包DATA0,DATA1,DATA2事务是交替进行数据传递的。(在同步传输中,所有的数据包都是为DATA0)
握手包
握手包跟随在令牌包或者数据包之后,组成一个完整的事务,是对一次事务完成的确认。USB主机或者USB设备会根据事务的完成状态返回相应的握手包。
握手包由8位的PID构成,用于数据传输的末位报告本次数据传输的状态。握手包之后使是整个事务处理的结束信号EOP。
握手包根据PID的不同,可分为:
PID | 含义 | 说明 |
---|---|---|
0010 | 握手ACK | 数据正确接收 |
1010 | 握手NAK | 数据未正确接收 |
1110 | 握手STALL | 使用的端点被挂起 |
0110 | 握手NYET | 接收方没有响应 |
1100 | 特殊用途ERR | SPLIT事务中表示出现错误 |
ACK 握手包
当 USB 数据传输的接收方正确接收到数据包时,接收方将返回 ACK 握手包。 ACK 握手包表征了一次正确的数据传输,之后才可以进行下一次事务处理。
如上图所示,上图为一次数据的输出事务。主机输出数据到设备,主机发起OUT令牌,指名接收数据的设备地址为15,端点地址为2,然后使用数据DATA1向设备发送了31个字节的数据。当设备接收到这些数据确认无误后,向主机发送一个ACK包,表示数据正确接收。
NAK 握手包
NAK 握手包一般由 USB 功能设备发出。对于IN数据传输,表示 USB 设备没有计划向 USB 主机发送数据;对于 OUT 数据传输,表示 USB 设备无法接收 USB 主机发送的数据。
事务(Transaction)
数据在所谓的事务中传输。通常,它们由三个数据包组成:
- 令牌包,指名了该事务的传输的类型,包括目标设备的地址和端点。
- 数据包,有些事务可以没有数据,数据的长度不得超过该端点的最大包大小。
- 握手包,对有数据或无数据传输的结果进行反馈,如SET_ADDRESS请求就无数据包。
一个USB事务是一次数据的可靠传输,数据的可靠性使用握手包来实现。
USB事务可包含如下几类
- Setup事务
- OUT事务
- IN事务
- PING事务
- SPLIT事务
Setup事务
Setup事务是由SETUP令牌,数据包和握手包组成的。
一个成功的Setup事务保证了Setup令牌和数据包传输的可靠传输。Setup事务是由主机到设备的,并且如果Setup事务含有数据包,必须使用DATA0包。
有数据包的SETUP事务可见下图。
- 此SETUP事务使用SETUP令牌包(0xB4),其目标设备地址为0,目标设备端点地址也为0。
- 数据包使用DATA0(SETUP事务必须使用DATA0包)来传输主机发给设备的USB请求命令。这里为获取USB设备的设备描述符请求,更多的可见USB标准请求一节。
- USB设备收到主机的数据包后,回握手包ACK,表示其正确无误地收到标准请求命令。
Setup事务的处理机制如下图所示:
- 无论是Setup令牌或者是DATA0数据包在发向主机的传输过程中,如果出现发送错误或者超时,USB设备均不向主机返回任保握手包。
- 当USB主机发送SETUP令牌和DATA0数据包后,在规定的超时时间内并没有收到设备返回的握手ACK时,则重传该事务。
OUT事务
OUT事务和其它事务一样,也包含三个包,分别为OUT令牌包,数据包(输出)和握手包(成功时为ACK)。
OUT事务用于由USB主机发送数据,所以在数据包之前发送为的OUT令牌包,
USB2.0 OUT事务的处理机制如图所示:
- 无论是OUT令牌或者是数据包在发向主机的传输过程中,如果出现发送错误或者超时,USB设备均不向主机返回任保握手包。
- 当USB主机发送OUT令牌和数据包后,在规定的超时时间内并没有收到设备返回的握手ACK时,则重传该事务。
握手包三种状态:
- ACK:表示数据已经正确无误的收到
- STALL:表示数据端点已经被停止(HALT)
- NAK:表示当前数据包无法收到。高速模式下主机使用PING事务来判断是否可以继续接收数据,低速或全速则重传该事务。
IN事务
- IN事务的数据方向和OUT事务的数据方向相反,IN是用于向主机输入数据,OUT事务用于主机向设备发送数据。
- IN事务和其它事务一样,也包含三个包,分别为IN令牌包,数据包和握手包。
IN事务ACK握手包如下图所示:设备向主机返回了18字节的设备描述符
IN事务NAK握手包如下图所示:USB设备无数据或数据尚未准备好向主机发送,返回NAK包。
USB2.0 IN事务的处理机制如图所示:
传输(Transfer)
传输(数据流类型)可以由一个或多个事务组成。支持以下传输类型:
- 控制传输:通常用于设置 USB 设备。他们总是使用 IN/OUT端点 0。
- 中断传输:可用于定期发送数据的地方,例如状态更新。
- 同步传输:传输实时数据,例如音频和视频。它们有保证的固定带宽,但没有错误检测。
- 批量传输:可用于在时间不重要的情况下发送数据,例如发送到打印机
控制传输
控制传输是一种特殊的传输方式。当USB设备初次连接主机时,用控制传输传送控制命令等对设备进行配置。同时设备接入主机时,需要通过控制传输去获取USB设备的描述符以及对设备进行识别,在设备的枚举过程中都是使用控制传输进行数据交换。
控制传输相对于其它三个传输方式比较复杂,且具有以下特点:
- 无论低速设备还是高速设备都可以使用控制通道。
- 控制传输的应用场合:主要应用于设备的枚举过程(如读取设备描述符,设置地址,设置配置等)和对数据准确性要求较高的场合。
控制传输最大包长度。
- 高速模式的最大包长固定为64个字节;
- 全速模式可在8、16、32、64字节中选择;
- 低速模式的最大包长固定为8个字节。
控制传输分为三个过程:
- 建立过程
- 数据过程(可选)
- 状态过程。
其中状态过程只使用DATA1包,并且传输方向与数据过程相反。主机写数据(OUT)完成,从机要上报接收状态,这就需要使用(IN)。
同理。主机读数据(IN)完成,主机要下发接收状态,这就需要使用(OUT)。
中断传输
中断传输一般用于小批量的和非连续的数据传输,通俗的来说就是用于数据量小的数据不连续的但实时性高的场合的一种传输方式,主要应用于人机交互设备(HID)中的USB鼠标和USB键盘等。
USB中断传输和我们传统意义上的中断不一样。它不是由设备主动地发起一个中断请求,主机响应再操作,而是由主机保证在不大于某个时间间隔内安排的一次传输,所以USB的中断实际意义是实时查询操作,即USB的中断传输是主机在一定的时间不断地主动轮询设备检查其是否有数据需要传输。
USB中断数据流传输包括IN传输和OUT传输,分别对应于数据的读和写,其也分为3个阶段,分别为令牌阶段、数据段和握手段。
- 当主机准备接收中断时,其发送IN令牌包,USB设备响应并返回DATAx数据包,NAK或STALL握手包。
- 当主机发送中断数据时,其发送OUT令牌包和DATAx数据包,而USB设备将向其返回ACK、NAK和STALL握手包。
批量传输
批量传输一般用于批量的和非实时的数据传输,通俗的来说就是用于数据量大但对时间要求又不高的场合的一种传输方式,类似用于USB打印机和USB扫描仪等等。
批量传输使用批量传输事务,一次批量传输事务分为三个阶段:令牌包阶段、数据包阶段、握手包阶段。批量传输分为批量读和批量写,批量读使用批量输入事务,批量写使用批量输出事务。注意:不论输入还是输出都是以主机为参考的。
对于批量传输,如果启动批量传输,如果USB总线中有多余的总线带宽,批量传输会立即执行,但当带宽比较紧张时,批量传输会把带宽让给其它传输类型。所以批量传输的优先级相对其它传输优先级比较低。
批量传输数据流传输包括IN传输和OUT传输,分别对应于数据的读和写,其也分为3个阶段,分别为为令牌阶段、数据段和握手段。
从数据包的组成上看,批量传输和中断传输是一模一样的。区分的方法是在枚举的时候确定好的。
偏移量/字节 | 域 | 大小/字节 | 说明 |
---|---|---|---|
0 | bLength | 1 | 该描述符的长度(7 Byte) |
1 | bDescriptorType | 1 | 该描述符的类型(0x05) |
2 | bEndpointAddress | 1 | 该端点的地址及输入输出属性 |
3 | bmAttributes | 1 | 该端点的传输类型属性 |
4 | wMaxPacketSize | 2 | 该端点支持的最大包长 |
6 | bInterval | 1 | 端点的查询时间 |
bmAttributes是端点的属性。最低两位D1~D0:表示该端点的传输类型。0为控制传输;1为等时传输;2为批量传输;3为中断传输。两个位,也就四种情况:00 01 10 11
同步传输/等时传输
等时传输也有“同步传输”的叫法,一般用于要求数据连续、实时且数据量大的场合,其对传输延时十分敏感,类似用于USB摄像设备,USB语音设备等等。
同步事务没有握手包。当一个同步传输中有多个事务时,最后一个事务之前的事务的数据长度必须是端点所支持的最大包长度。如果最后个事务的数据长度小于端点支持的最大包长度。
同步传输事务需要保证固定的时间段有固定的数据传输量,所以它允许有一定的误码率。
由于同步传输只关心数据的实时性,不关心的数据的正确性,故没有握手阶段,所以只有两个阶段,也就是令牌阶段和数据阶段:
端点
端点可以描述为数据源或接收器,并且仅存在于 USB 设备中。存储在端点的数据可以从 USB 主机接收或等待发送到 USB 主机。
端点可以配置为支持USB 规范中定义的四种传输类型(控制传输、中断传输、同步传输和批量传输)。在硬件限制范围内,端点可以使用 USB 中间件进行配置(例如,将端点限制为某种传输类型)。
这些规则适用于所有微控制器设备:
- 一个设备最多可以有16 个 OUT和16 个 IN端点。
- 每个端点只能有一个 传输 方向。
- 端点 0仅用于控制传输,不能分配给任何其他功能。