目录
1. USB包基本结构
1.1 SOP域(Start Of Packet)
1.2 SYNC域(同步域)
1.3 PID域(标识域)
1.4 地址域(ADDR)
1.5 帧号域(Fram)
1.6 数据域(DATA)
1.7 校验域(CRC)
1.8 EOP域(End Of Packet)
2. USB包类型
2.1 令牌包
2.2 数据包
2.3 握手包
2.4 特殊包
3. USB事务处理时序
3.1 IN事务处理时序
3.2 OUT事务处理时序
3.3 SETUP事务处理时序
上一篇讲了USB帧、微帧、传输、事务、包的关系,本章重点讲USB包的基本结构和包类型。
1. USB包基本结构
包是USB总线上数据传输的最小单位,USB所有的传输最终都会被分成包进行传输,不同类型的包里面包含着不同的域,包的基本结构如下图所示:
由上图可知,一个包由SOP、SYNC、Packet Content、EOP四部分组成,其中SOP、SYNC、EOP为所有包共有的域,Packet Content是整个包的核心,Packet Content由PID、地址、帧号、数据、CRC组成,不同类型的包由不同的Packet Content组成。USB包的域段可分为8种:
- SOP域(Start Of Packet)
- SYNC域(同步域)
- PID域(标识域)
- 地址域(ADDR)
- 帧号域(Fram)
- 数据域(DATA)
- 校验域(CRC)
- EOP域(End Of Packet)
1.1 SOP域(Start Of Packet)
SOP表示包传输开始。通过将D +和D-线从空闲状态驱动到相反的逻辑电平(K状态),由始发端口发信号通知包传输开始(SOP)。这种电平切换表示SYNC字段的第一个bit,当发起新的传输时,集线器必须将SOP的第一bit宽度的变化限制在±5 ns以内。
低速设备SOP信号:总线从IDLE状态(J状态:差分0)切到K状态(差分1),即可完成低速SOP信号的发送。
全速设备SOP信号:总线从IDLE状态(J状态:差分1)切到K状态(差分0),即可完成全速SOP信号的发送。
1.2 SYNC域(同步域)
USB以异步传输的方式,USB主机和设备的时钟频率都分别由自身提供,虽然在USB设备枚举时,会共同确定USB版本,以确定数据传输速率,但是仅仅如此的话,USB主机和USB设备在运行一段时间后,时钟频率上还是会有累积误差,这会造成数据解读出错,所以USB的包有一个SYNC域段,它被用于本地时钟与输入信号的同步,以减小USB主机和设备的时钟频率误差。
- 高速包的SYNC宽度为32bit(15对KJ信号+2个K信号,编码前:0000 0000 0000 0000 0000 0000 0000 0001)
- 全速/低速包的SYNC宽度为8bit(3对KJ信号+2个K信号,编码前:0000 0001),如下图所示。
下图是协议分析仪抓包解析的SYNC域。
1.3 PID域(标识域)
对于每个包,PID都是紧跟着SYNC的,PID域共8bit,由4位类型字段和4位校验字段组成。类型字段主要是标识包的类型,校验字段主要是对类型字段进行校验。PID的4位校验字段可以确保PID的可靠解码,以便包被正确解析。PID校验字段是对数据包类型字段取补码生成的,如果4个PID校验位不是它们各自的补码,则产生PID错误标识符位。
下图是协议分析仪抓包解析的PID域。
主机和所有的外设都必须对接收到的PID域进行解码,如果出现错误或者解码为未定义的值 那么这个包就会被接收者忽略,如果外设接收到一个PID,它所指明的操作类型或者方向不被支持,外设将不做出响应。
PID 表征了包的类型,分为令牌( Token)、 数据( Data)、 握手( Handshacke)以及特殊包 4 大类,共 16 种类型的 PID。如下表所示。
注:PER和ERR的PID是一样的,但因ERR是高速模式下的包,PER是全速模式下的包,所以并不冲突。
1.4 地址域(ADDR)
设备端点都是由地址域指明的,它包括两个子域:7bit的设备地址和4bit端点地址,如下图所示。设备需要对这2个地址进行完全解码,当解析出不允许的或者不匹配的地址时,这个包将会被忽略,访问未初始化的端点也会导致包被忽略。
下图是协议分析仪抓包解析的地址域。
设备地址域(ADDR)指明此次通信的外设,ADDR共7位,因此最多可以有128个地址,因为0地址用于枚举,所以最多可以支持127个设备。
端点地址(ENDP)有4位,它表明设备可以拥有几个通信端点,低速设备最多支持 3个端点, 高速和全速设备最多支持 16个端点。
1.5 帧号域(Fram)
帧号是一个11bit字段,指明目前帧的排号,由主机在每帧的基础上递增,即发送一帧,这个域段的值加1。帧号在达到其最大值0x7FFH时翻转,并且这个域只存在于每帧开始时的SOF令牌中。
1.6 数据域(DATA)
数据字段的范围可以从0到1024字节,并且必须是整数字节。
1.7 校验域(CRC)
CRC校验不包含PID字段,令牌包是5位的CRC校验位,数据包是16位的CRC校验位。
1.8 EOP域(End Of Packet)
EOP表示包传输结束。通过将D +和D-驱动到SE0状态并维持2bit时间(SE0的意思是D+和D-都表示为低电平),然后将线路驱动到J状态并维持1bit时间表示EOP。从SE0到J状态的转换定义了接收器处的分组的结束。 J状态被置位1bit时间,然后D +和D-输出驱动器都处于高阻态,总线终端电阻将总线保持在空闲状态。
低速设备EOP信号:总线持续2位时间的SE0(单端0)状态,后跟随1位时间的J状态(差分0),即可完成低速EOP信号的发送。
全速设备EOP信号:总线持续2位时间的SE0(单端0)状态,后跟随1位时间的J状态(差分1),即可完成全速EOP信号的发送。
2. USB包类型
前面的传输类型和事务类型都是从功能角度来讲的,在实际的USB传输中,所有的数据都是经过打包(packet)后发送出去的,包是USB传输的最小单位,不能被打断或干扰,否则会引发错误,包(packet)根据功能可以分为3种:
- 令牌包(Token Packets):由主机发出,用来启动一次通信,内容有目标地址、传输方向和交互性质等。
- 数据包(Data Packets):交互的数据,内容为应用信息或控制/状态信息。
- 握手包(Handshake Packets):由数据信包接收方发出,说明对数据信包或令信包的接收情况。
2.1 令牌包
令牌包用于表明要开启一次USB数据传输。由于USB总线系统是主从结构的,所以无论是数据输入还是数据输出,都是由USB主机向USB从机发送令牌包,表明要进行数据传输。令牌包有以下4种:
- IN令牌包
- OUT令牌包
- SETUP(设置) 令牌包
- SOF(Start of Frame 帧起始) 令牌包
(1)IN令牌包
IN令牌包用于主机读取数据,即通知哪一个设备(ADDR)的哪一个端点(ENDP)接下来要发送一包数据给主机。当设备收到主机发送的IN令牌包,就会发送数据包给主机。
(2)OUT令牌包
OUT令牌包用于主机发送数据,即通知哪一个设备(ADDR)的哪一个端点(ENDP)接下来要接收主机传过来的数据。当设备的端点在收到OUT令牌包后,接下来会等待接收主机发来的数据
(3)SETUP令牌包
用于告知设备,主机将要发送一个数据包。当设备的端点在收到SETUP令牌包后,接下来会等待接收主机发来的数据。
与OUT令牌包不同的是,SETUP令牌包只能用在控制传输,USB主机之后将向从机发送一个DATA0类型(只能为此类型)数据包,数据包的目的地是USB设备的控制端点,此端点地址为0,USB从机必须接受此数据包,OUT令牌包没有这些限制。
IN、OUT、SETUP令牌包结构是一样的,它们的格式如下所示。
(4)SOF令牌包
对于SOF包,主机在每帧(或微帧)开始时以广播的形式发送(全速、低速设备1ms,高速设备125us),所有USB全速设备和高速设备都可以接收到SOF包,SOF不引起任何操作。它的格式如下所示。
2.2 数据包
数据包有4种,分别为:
- DATA0:此时数据包为偶数据包
- DATA1:此时数据包为奇数据包
- DATA2:此时为一个高速同步事务的专用数据包。
- MDATA:时为一个SPLIT(分裂)事务的专用数据包。
DATA0,DATA1这两种类型数据包通过包类型切换机制可以加强数据包连续传输的可靠性, 其原理是,假设当前传输数据包的包类型为DATA0,USB主机和从机都会通过自身的数据包标记记录当前的包类型为DATA0,当前数据包如果传输成功,那么USB主机和从机都会将标记切换为DATA1,但是一旦当前数据包传输失败,例如USB从机接收到的数据不完整,那么USB从机中的数据包标记会保持DATA0不变,而USB主机由于已经完成数据发送操作,会将下次要发送的数据包以DATA1类型进行发送,USB从机匹配DATA1数据包标记发现和自身的DATA0数据包标记不匹配,会要求USB主机将上次的数据重新再发送,USB主机收到信号后会执行重传操作,以确保之前的DATA0数据包被正确传输。
所有的连续数据包的类型都会在DATA0和DATA1之间不断翻转,以确保数据包准确传输。
DATA2,MDATA两种类型,这两种类型的数据包主要用在高速分裂(SPLIT)事务和高速高带宽同步传输中。
除了SOP、SYNC、EOP公共域段,数据包由PID和DATA字段组成。低速设备允许的最大传输数据量为8字节,全速设备最大传输数据量1023字节,高速设备的最大传输数据量为1024字节。它的格式如下所示。
2.3 握手包
握手包是接收方给发送方返回的状态,这样发送方可以知道接收方的当前状态。握手包有4种类型:
- ACK
- NAK
- STALL
- NYET
(1)ACK
- 表示肯定的应答,由数据接收方发出,主机和设备都可以发送。
- 表示数据传输成功,PID 被正确接收,发生数据域的CRC 校验错误等。
(2)NAK
- 只能由设备发出,主机不能发出。
- 表示设备没有准备好发送数据或者没有准备好接收数据。
- NAK 是USB 的一种暂时状态, 当设备处于“ 忙”的工作状态时, 就会发送NAK;等到设备处于空闲状态时, 如果主机再要求设备发送或接收数据时, 设备不再返回NAK, 而是进行正常的数据传输。
(3)STALL
- 由设备发出,主机不能发起。
- 表示设备出错,设备不支持某个请求、无法传输或接收数据。
(4)NYET
- 仅用于高速设备的数据传输,特别是USB集线器设备中。USB集线器在处理SPLIT令牌包事务处理中,如果USB集线器无法正常处理SPLIT请求,则USB集线器向USB主机返回NYET握手包。
- 表示设备没有准备好或者出错。
除了SOP、SYNC、EOP公共域段,握手包仅由PID组成。握手数据包用于报告传输的状态。它的格式如下所示。
2.4 特殊包
特殊包主要指的是一些在特殊场合才会使用的包,分为4种:
- PER包
- ERR包
- SPLIT包
- PING包
(1)PER包(令牌包)
- 是通知集线器打开其低速端口的前导令牌包,由主机发送给集线器,表示接是开启一个USB低速数据传输。
- PRE只能用于全速传输模式中,平常为了防止全速信号使低速设备误动作,集线器是不会将全速信号传送给低速从机的,当集线器接收到此信号时,会将信号通过低速模式传给低速设备。
- PRE事务处理只在USB主机和USB集线器之间进行,即只有USB集线器才可以响应PRE事务处。在全速模式下,假如需要处理低速事务,主机会发送一个PRE包,全速端口接收到此包会直接忽略,但当集线器接收到时,会打开其低速端口,然后主机就以低速模式给低速设备发送一系列令牌包、数据包等。
(2)ERR包(握手包)
- 用于高速传输。
- 在高速USB设备传输事务中,USB总线数据传输发生错误,则会给主机发送ERR握手包。
(3)SPLIT包(令牌包)
- 是高速事务分裂令牌包,可以将只有在高速模式下才能处理的数据包转化为低速或者全速数据包发送给相应的端口。
(4)PING包(令牌包)
- 仅用于高速传输,用于探测设备当前的状态。PING令牌包后面是不接数据包的,只有当收到了设备发回来的ACK或者NAK应答才会开始发数据包,这就是为什么在收到NYET握手包的时候,主机会先发一个PING令牌包,确定设备有足够空间了才发送数据包,这就避免了浪费资源。
- 发送PING包后,如果设备正确接收数据,则会给主机发送ACK握手包。如果设备没有准备好接收主机的数据或者没有准备好给主机发送数据,则会给主机发送NAK握手包。如果设备不能进行传输,则会给主机发送STALL握手包。
3. USB事务处理时序
了解了包的基本结构和分类,下面看下基本的事务处理时序,主要是理解令牌包和数据包、握手包的各种组合关系。
3.1 IN事务处理时序
IN事务处理:表示USB主机从总线上的某个USB设备接收数据包的过程。
(1)正常的输入事务处理时序
(2)设备忙时的输入事务处理时序
(3)设备出错时的输入事务处理时序
3.2 OUT事务处理时序
事务处理:表示USB主机把一个数据包输出到总线上的某个USB设备接收的过程。
(1)正常的输出事务处理时序
(2)设备忙时的输出事务处理时序
(3)设备出错的输出事务处理时序
3.3 SETUP事务处理时序
(1)正常的设置事务处理时序
(2)设备忙时的设置事务处理时序
(3) 设备出错的设置事务处理时序