×
嵌入式 > 嵌入式开发 > 详情

USB学习系列之四——USB包结构

发布时间:2022-07-18 发布时间:
|
1.USB的数据传输以包为单位,一个包被分成不同的域。USB传输时使用的是LSB在前,MSB在后的方式。

2.不同的包所包含的域是不同的,但是都有共同的特点是:以同步域开始,紧跟着一个包标识符PID,最终以包结束符EOP结束这个包。

3.同步域:高速USB串行接口引擎数据传输要开始了,同时也提供同步时钟。对于低速设备和全速设备,同步域使用的是0000 0001(二进制数);对于高速设备使用的是00000000 00000000 00000000 00000001。

注意:这个是对发送端的要求,接收端解码时,0的个数可以少于这个数目。

4.包结束符:包结束符一共有8位,其中USB协议使用的只有4位(PID0~PID3),另外4位(PID4~PID7)是前四位的取反,用来校验PID。USB协议规定了四类包,分别是:令牌包(PID1~PID0为01)、数据包(PID1~PID0为11)、握手包(PID1~PID0为10)和特殊包(PID1~PID0为00)。以下为USB2.0协议的包,带*的为USB1.1协议没有的:

5.令牌包:令牌包用来启动一次USB传输。主机发送一个令牌来通知哪个设备进行响应,如何响应。

输入令牌包:用来通知设备将要输出一个数据包。

输出令牌包:用来通知设备返回一个数据包。

建立令牌包:只用在控制传输中,通知设备输出一个数据包,建立令牌包后只使用DATA0数据包,且只能发送到设备的控制端点,并且设备必须要接收,而输出令牌包没有这些限制。

帧起始包:在每帧开始时发送,以广播的形式发送。USB全速设备没毫秒产生一个帧,高速设备每125微秒产生一个帧。USB主机会对当前的帧号进行计数,在每次帧开始时通过SOF包发送帧号(或者微帧开始时,每毫秒有八个微帧,这8个微帧的帧号是一样的)。SOF中的帧号是11位。
注意:在4个令牌包中,只有SOF令牌包之后不能跟数据传输,其他的都有数据传输。每个令牌包之后都有一个CRC5的校验,它只校验PID之后的数据,不包括PID本身,因为PID本身的后4位已经有取反的校验机制了。

由于SOF令牌包之后不跟随数据传递,所以SOF令牌包和其他三种包的结构不同,具体如下图所示:

SOF令牌包结构

IN、OUT、SETUP令牌包结构图

6.数据包

USB1.1中只有DATA0和DATA1两种数据包。

USB2.0中增加了DATA2和MDATA两种数据包,这两种数据包主要用在高速分裂事物和高速高带宽同步传输中。

数据包的统一结构:同步域 + 8位包标志PID + 整数字节数据 + CRC16校验 + EOP。

之所以有不同类型的数据包,是用在握手包出错时纠错。具体解释如下:

主机和设备都会维护自己的一个数据包类型切换机制:当数据包成功发送或者接收时,数据包类型切换。当检测到对方所使用的数据包类型不对时,USB系统认为这发生了一个错误,并试图从错误中恢复。数据包类型不匹配主要发生在握手包被损坏的时候。当一端已经正确接收到数据并且返回确认信号后,确认信号在传输过程中被损坏。这时另一端就无法知道刚才发送的数据是否已经发送成功,这时只好继续保持自己的数据包类型不变。如果对方下一次使用的数据包类型跟自己的不一致,则说明它刚刚已经成功接收到数据包;如果对方下一次使用的数据包跟自己的一致,则说明对方没有切换数据包类型,也就是刚刚的数据包没有发送成功,这是上一次的重试操作。

7.握手包

握手包用来表示一个传输是否被对方确认。

握手包的结构:同步域 +包标识符PID + EOP。

握手包有ACK、NAK、STALL和NYET。

ACK:表示正确接收数据,并且有足够的空间来容纳数据。主机和设备都可以用ACK来确认,而NAK、STALL和NYET只有设备能够返回,主机不能使用这些握手包。

NAK:表示没有数据需要返回,或者数据正确接收但是没有足够的空间来容纳。当主机接收到NAK时,知道设备还没有准备好,主机会在以后合适的实际进行重试传输。

STALL:表示设备无法执行这个请求,或者端点已经被挂起,它表示一种错误的状态,设备返回STALL之后,需要主机进行干预才能解除这种STALL状态。

NYET:只有在USB2.0高速设备输出事物中使用,它表示设备本次数据成功接收,但是没有足够的空间来接收下一次数据。主机在下一次输出数据时,将先使用PING命令牌包来探测设备是否有足够的空间接收数据,一面不必要的带宽浪费。

注意:NAK并不表示数据出错,当USB主机或者设备检测到数据出错时,将什么都不返回,这时等待接收握手包的一方就会收不到握手包从而等待超时。

8.特殊包

特殊包是在一些特殊场合使用的包。总共有四种:PRE、ERR、SPLIT和PING。其中PRE、SPLIT、PING是令牌包,ERR是握手包。ERR、SPLIT、PING三个是在USB2.0协议中增加的。

(1)PRE:通知集线器打开其低速端口的一种前导包,PRE只能使用在全速模式中。一般情况下集线器不会将全速信号发送给低速设备,只有当接收到PRE令牌包之后,才打开其低速端口。

PRE令牌包结构:同步域 +PID +EOP。

当需要传送低速事务时,主机首先发送一个PRE令牌包(以全速模式发送)。对于全速设备,将会忽略这个令牌包。集线器在接收到这个令牌包之后,打开其连接了低速设备的端口,接着主机就会以低速模式给低速设备发送令牌包和数据包等。

(2)PING:令牌包结构同OUT令牌包。但是PING令牌包后不发送数据,而是等待设备返回ACK或者NAK,以判断设备是否能够传送数据。在USB2.0中的高速环境中才会使用PING令牌包,且只被使用在批量传输和控制传输事务中。

(3)SPLIT:高速事务分裂令牌包,通知集线器将高速数据包转化为全速或者低速数据包发送给其下面的端口。

(4)ERR:在分裂事务中表示错误使用。高速分裂事务的过程比较复杂,而且主要是由集线器完成,所以不详细说明。

9.数据包的处理

一般的USB接口芯片都会完成如CRC校验、位填充、PID识别、数据包切换、握手等协议的处理。当USB接口芯片正确接收到数据时,入股偶有空间保存,则它将数据保存并返回ACK,同时,设置一个标志表示已经正确接收到数据;如果没有空间保存数据,则会自动返回NAK。

收到输入请求时,如果有数据需要发送,则发送数据,并等待接收ACK。只有当数据成功发送出去之后,才设置标志位,表示数据已经成功发送;如果没有数据需要发送,则它自动返回NAK。

通常只需要根据芯片提供的一些标志,准备需要发送的数据到端点,或者从端点读取接收到的数据即可。所要发送和接收的数据指的是数据包中的数据,至于同步域、包标识、地址、端点、CRC等是看不到的,在BUSHound中抓到数据也是如此,仅是数据包;并且在BUSHound中只能看到成功传输的数据,即只有ACK确认过的数据包。由于控制传输比较特殊,SETUP包也会有相应的标志供我们使用。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机汇编语言 如何实现点亮熄灭二极管