本文转自公众号欢迎关注
基于DWC2的USB驱动开发-USB包详解 (qq.com)
一.前言
不管什么通讯协议,比如UART,SPI,USB等等,不管是并口还是串口,不管是同步还是异步,我们从抽象的角度去看,其本质都是一样的。都是先定义物理信号,物理信号可能是差分,单端,电流驱动电压驱动等等,不管是什么样的物理信号,我们从抽象角度看就是不同的物理状态和数字1和0的对应, 这里的状态不一定是电压(虽然数字通讯大部分就是电压),也可能是频率,相位等等,这里的状态也不一定是电平状态也可能是跳变状态,只要是有不同状态可以区分的都可以,甚至你可以自由发挥自我创造。这里的数字1和0即bit,至此我们就到了数字的世界,一切都是1和0的世界了,这个转化是由PHY的收发器完成的。bit再按照一定规则组成帧或者包,然后在包的基础上定义各层协议。任意的通信协议都不外呼上述的过程,USB也是如此。这样一看USB也没有那么可怕了,和我们用的UART等协议本质是一样的,只是物理层信号不一样,协议不一样而已。这一篇我们就来介绍协议层,底层相关的一些内容,这一篇主要关注USB的包,不涉及物理层信号,也不管位填充等等。
二.协议的一般约定
上面提到,协议都是建立在bit之上的,bit组成byte然后组成包或者帧。那么对于bit和byte在总线上的出现就有一个顺序的约定,对于bit先发低位即 LSb ,对于byte先发低字节即 LSB 。对于协议中的多字节数据域都是 小端模式 ,即低字节在低地址,总线上先发送。
三.包组成
前面提到了包就是一系列的1,0序列组成,但是为了协议能解析,包需要分成一些特定的区域以代表不同的功能。比如一些常见的协议一般都有同步域,头,负载,校验等部分。
USB也类似,下面就介绍USB包的组成部分,不同包类型可能由不同的部分扭组合而成。
3.1SYNC同步域
所有USB的数据包以一个SYNC同步区域开始,接收电路可以利用该区域进行时钟对齐。类似的CAN协议也有硬同步机制都差不多。所谓的硬对齐即通过一个特殊的状态(区别于正常的数据,比如一个长串的1,长串的0,任何可以区别于其他状态的都可以)来表示开始,然后以该开始状态后的一个时钟边沿作为对齐。
SYNC的最后两位用于标志SYNC的结束,承接PID的开始。
我们看到SYNC就是KJ对,所以有,边沿这样接收端就可以根据这些边沿进行和北部时钟同步,注意有意第一个KJ对有失真,所以不能用于同步。
SYNC是包的同步机制,不含协议层的有效信息,所以一般协议分析中就不会体现这部分了,只有硬件分析时才可能关注该部分,比如要示波器抓包则可以设置触发条件来触发到包头触发。
另外图中SYNC开始,即从Idle到K也叫SOP,表示包的开始。
3.1.1全速/低速
8位:3个KJ对加两个K,KJKJKJKK
如下所示
3.1.2高速
32位:15个KJ对加两个K,KJKJKJKJ KJKJKJKJ KJKJKJKJ KJKJKJKK .
当重复数据包时,集线器允许从SYNC开始最多丢弃4位,但不能破坏SYNC字段的任何重复位。因此,在被5个集线器重复之后,SYNC字段可以短至12位。
但是注意对于接收方不一定要接收8位或者32位,对于高速接收到至少12位就算(KJKJKJKJKJKK)
3.2包ID区域
SYNC后面就是PID区域,可以看到和我们通常的协议都是一个套路,比如我们使用串口自定义应用层协议,一般前面会用几个特殊字节作为同步域用于标志包的开头,如果用AA,55这种还可以用于时钟同步,波特率自适应。然后定义一个TYPE字段表示该包的作用和类型,这样看来USB也不过如此,这种套路我们早就用过很多了。
USB的PID定义如下,用于表示包的类型,
低4位为包类型编码,高四位为其取反用于校验,接收方如果校验低4位不是高4位的取反则为PID错误。对于编码类型位定义或者PID校验错误的包丢弃。
对于PID合法但是不符合预期的比如对IN端点收到了OUT令牌则不响应。
PID的编码如下,注意如下是按照高位在左,实际传输是低位先传输,注意观察下表
可以看到PID分为了4组,通过PID<0:1> 区分。
比如,以下为一个控制传输的实例,和上表对应,高低4位相加都是0xF
SETUP是0x2D
DATA0 是0xC3
ACK是0xD2
IN是0x69
NAK是0x5A
3.3地址域
地址域包括功能地址域和端点域。地址域必须完全独立匹配,不容许重名(别名),不符合的SETUP必须忽略,访问未初始化的端点的SETUP也要忽略。
一个设备对应一个地址,地址有7位,所以可以寻址128个设备。
一个设备地址对应一个功能,默认设备地址是0,在枚举阶段,标准请求设置地址。
设备地址0即做枚举使用,不能分配给其他使用。
IN,STEUP,OUT,PING,SPLIT都需要带ADDR以表明是和哪个设备通讯。
ADDR后面是端点域,4位可以表示16个端点。所以可以到设备最多16个端点。
端点0用于控制传输是必须支持的,所以很多控制端点是默认使能的,不需要手动使能,
其他端点是功能相关。
SETUP,IN,OUT,PING都要带端点,表示和哪个端点通讯。
低速设备支持最多3个端点,控制端点0+两个端点(两个控制端点,控制端点+中断端点,或者两个中断端点)。
注意控制端点不一定要是端点0,也可以是其他端点,但是必须要有端点0的控制端点。
全速和高速设备支持最多16个IN和OUT端点。
3.4帧序号域
帧序号区域11位,由主机每1mS递增1.
到达最大值0x7FFH时绕回,只有SOF包中有。
SOF包在低速全速时是1mS发一次,
高速则是125uS发一次,注意只有1mS才子等一次,即一个微帧内不递增,也就是8个SOF才递增一次。
3.5数据域
数据域范围从0到1024字节,不同速度不同端点类型长度不一样,低字节先发
不同速度不同端点类型包长如下表
控制 | 中断 | 批量 | 同步 | |
---|---|---|---|---|
高速 | 64 | ≤1024 x 3 | 512 | ≤1024 x 3 |
全速 | 8, 16, 32, 64 | ≤64 | 8, 16, 32, 64 | ≤1023 |
低速 | 8 | ≤8 | 无 | 无 |
3.6校验域
校验区域采用CRC校验,保护非PID区域,这里为什么不包括PID呢? 因为PID自带校验了。
注意:CRC是在bit填充之前生成的,带CRC的结果之后才是bit填充,接收是先bit填充恢复,然后才是CRC计算。这个很好理解bit填充是硬件层对于信号编码的处理,所以是最后一步,CRC是协议层的内容肯行在前。
对于CRC错误的丢弃该部分数据,一般就是整个包。
Token的CRC
对IN,SETUP和OUT包的ADDR ENDP部分
SOF包的时间戳部分
PING和SPLIT包的ADDR ENDP部分
进行5位CRC校验。
G(X) = X5+ X **2 ** + 1
数据的CRC
数据包使用16位CRC,对数据域进行校验
G(X) = X16+ X15+ X **2 ** + 1
四.各种包格式
4.1令牌包
PID可以是IN,OUT,SETUP,PING
只有主机才能发令牌包,为什么呢? 因为USB架构是主从架构的,只有主机发起通讯,即由令牌包开始,从机才能会响应,否则这么多设备一起启动发送就会乱套了。哪怕是设备要发送数据也是必须要主机发IN令牌包,从机才能响应。
令牌和SOF包由数据之后三字节的EOP间隔。如果一个数据包解码为非有效的令牌或SOF没有有效的EOP终止,则它必须被视为无效包被忽略。
4.2SOF包
全速时1.00 ms ±0.0005 ms 发一次SOF包
高速则125 µs ±0.0625 µs 发一次
SOF包不需要响应。
SOF包由主机或者HUB发送
注意高速的微帧内帧序号是不递增的,只有下一个ms才递增,可以通过判断帧号的递增来同步到该微帧是1ms内的第一个微帧,接下来的是剩余的7个。
4.3数据包
数据包有以下几种
DATA0,DATA1,DATA2,MDATA
DATA1 DATA1 DATA0用于高带宽ISO传输,即一个微帧传3包则按照DATA2-DAT1-DATA0传输。
DATA1-DATA0用于传输翻转差错控制
不同速度的不同传输类型包长不一样进前面的说明。
4.4握手包
握手包用于数据传输时报告状态, 反应数据命令是否成功接收或接受,流控,halt等。
注意不是所有的包都需要握手,比如ISO数据是不需要握手的,因为其注重实时性,不管可靠性,IN和OUT数据之后对方收没收到不管,好比UDP和TCP的区别。
例如如下的ISO的IN,设备返回数据后主机是不需要回ACK的
握手包格式如下,只有PID域:
握手包有如下几种类型,具体什么情况回什么包,可以参考规格书的第8章的不同传输的拓扑图,比如对于中断传输的IN设备可能回NAK和STALL。
4.4.1ACK
ACK由数据的接收方回,表示数据被接收且没有任何错误。
4.4.2NAK
NAK用于流控,由设备回,注意主机不能回NAK。
表示数据没有准备好,或者不能接收数据。
4.4.3STALL
STALL由设备回,表示不能收发数据,或者指定的请求不支持。
主机不能回STALL。
在端点相关的特征Halt之后,再请求端点相关的特征则回STALL。
还有就是控制传输时可能回STALL,具体参考规格书中各种传输的拓扑图。
4.4.4NYET
只有高速有,
PING协议中对数据包回NYET表示本包接收,不能继续接收下一包。
HUB在split传输时也可能回NYET表示split船速和未完成或者不能处理split传输。
4.4.5ERR
只有高速HUB使用
用于报告全速/低速总线上的错误。
规格书8.4.6章节对响应有一个总结,
IN传输设备的响应
IN传输主机的响应,可以看到主机不能NAK要不就是ACK要不就是不响应。
OUT传输设备响应
设备对SETUP的响应
设备不能对SETUP和其数据做STALL和NAK响应,要么就是ACK要么就是不响应。
4.5SPLIT相关令牌包
这部分内容也比较多,后面单独一篇讲。
五.总结
熟悉USB包的格式,是后面查看协议分析仪,示波器抓波形分析等基础,所以需要了解。USB报的格式没有什么特殊,和其他协议套路都是一样的,要从抽象的结构去理解。
审核编辑:汤梓红
-
usb
+关注
关注
60文章
7938浏览量
264490 -
SPI
+关注
关注
17文章
1706浏览量
91512 -
编程
+关注
关注
88文章
3614浏览量
93686 -
开发板
+关注
关注
25文章
5033浏览量
97378 -
代码
+关注
关注
30文章
4780浏览量
68529 -
单板计算机
+关注
关注
0文章
74浏览量
15627 -
编译
+关注
关注
0文章
657浏览量
32852 -
驱动开发
+关注
关注
0文章
130浏览量
12072 -
DWC2
+关注
关注
0文章
35浏览量
125
发布评论请先 登录
相关推荐
评论