USB学习笔记——通讯数据分析
USB的重要关键字
端点:位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有唯一确定的地址,有不同的传输特性(如输入端点、输出端、配置端点、批量传输端点)
帧:时间概念,在USB通信中,一帧就是1ms,它是一个独立的单元,包含一系列总线动作,USB将一帧分为好几份,每一份就是一个USB传输动作。
上行、下行:设备到主机为上行,主机到设备为下行。
USB 的基础知识
USB的数据格式是由二进制串构成,首先是 二进制串 构成 字段(有7种),字段 构成 包, 包 构成 事务(IN、OUT、SETUP),事务 构成传输(控制传输、批量传输、中断传输、同步传输)。
字段
字段是USB数据的最小单位,由若干位组成,字段可分为7种类型:
同步字段(SYNC):8位,固定值为0000 0001,用于本地时钟与输入同步;
标识字段(PID): 8位,4位标识符+4位标识符反码,(D1D2D3D4
D
‾
\overline{\text{D}}
D1
D
‾
\overline{\text{D}}
D2
D
‾
\overline{\text{D}}
D3
D
‾
\overline{\text{D}}
D4),因此USB的标识符共16种,又分为令牌包、数据包、握手包、特殊包四大类:
TODO 另外的几种标识符
令牌包:
0x01 (0000 0001) OUT 输出,启动一个主机到设备的传输,包含设备的地址和标号
0x09 (0000 1001) IN 输入,启动一个设备到主机的传输,包含设备的地址和标号
0x05 (0000 0101) SOF 帧起始,表示一帧的开始,并包含相应的帧号
0x0d (0000 1101) SETUP 设置,启动一个控制传输,用于主机对设备的初始化。
数据包
0x03 (0000 0011) DATA0 偶数据包
0x0b (0000 1011) DATA1 奇数据包
握手包
0x02 (0000 0010) ACK 确认收到正确的包
0x0a (0000 1010) NAK 接收端忙无法接收数据,或无数据可发送
0x0e (0000 1110) STALL 端点被禁用或不支持的请求
特殊包
0x0c (0000 1100) PRE 属于令牌包,用于启动下行端口的低速设备的数据传输
0x0c (0000 1100) ERR 属于握手包,表示分离传输错误(分离传输是指将一次完整的事务分成两个事务传输,用于提高总线在同时处理高速和全/低速传输时的利用率)
0x08 (0000 1000) SPLIT 属于令牌包,表示高速模式下的分离传输
0x04 (0000 0100) PING 属于令牌包,表示高速模式下对于 批量/控制 端点的流控探针
0x00 (0000 0000) Reserved
地址字段(ADDR): 7位,主机分配给设备的地址,设备在被主机配置、枚举之前会被分配地址 000 0000,即零地址,因此一个USB主机最多只能接127个设备。
端点字段(ENDP): 4位,一个USB设备的最大端点数为16。
帧号字段(FRAM): 11位,每一个帧都有一个特定的帧号,帧号最大容量为0x800,帧号对于同步传输有重要意义。
数据字段(DATA): 长度为0~1023字节,不同的传输类型中,数据域的长度各不相同
校验字段(CRC): CRC校验位,用于对令牌包和数据包中非PID域进行校验。
包
包分为令牌包、数据包、握手包、特殊包,由标识域(PID)的不同又可分为10种不同的握手包。
令牌包可以分为输入包、输出包、设置包和帧起始包,(其中的输入输出包中是用于设置的命令,而非传输的数据),这几种包的格式分别为:
输入包、输出包、设置包具有相同的格式:
SYNC8 + PID8 + ADDR7 + ENDP4 + CRC5 (共32位)
帧起始包:
SYNC8 + PID8 + FRAM11 + CRC5 (共32位)
数据包 分为 DATA0 和 DATA1包,USB发送数据时,若一次发送的数据大于端点的容量,就把数据分为多个包进行发送,DATA0和DATA1包交替发送(同步传输中只有DATA0包),数据包的格式为:
SYNC8 + PID8 + DATA(0-1023)
握手包 握手包有 ACK、NAK、STALL三种,结构比较简单:
SYNC8 + PID8 (共16位)
事务
事务有IN、OUT、SETUP 三类,每种事务由 令牌包、数据包(可选)、握手包三个阶段构成(阶段表示这些包的发送有一定的顺序),构成事务的三个阶段为:
令牌包阶段:启动一个输入、输出或设置事务,总是由主机发送;
数据包阶段:根据不同的令牌包发送相应的数据,可以由主机到设备,也可以由设备到主机;
握手包阶段:返回数据的接收情况(同步传输的IN、OUT事务中没有握手包阶段,同是也说明了同步传输无法保证数据的准确性)
三种事务的通信过程如下:
IN 事务
令牌包阶段:主机发送一个PID为IN的输入包给设备,通知设备要发送数据给主机;
数据包阶段:根据不同的情况作出不同的反应
- 设备端点正常,设备开始给主机发送数据包;
- 设备忙,无法向主机发送数据,则发送NAK包,IN事务结束,直到下一个IN事务到来才继续;
- 设备端点出错,则发送STALL包,事务提前结束,总线进入空闲状态;
握手包阶段:主机正确接收数据后会向设备发送ACK包。
OUT 事务
令牌包阶段:主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;
数据包阶段:主机向设备发送数据包;
握手包阶段:根据不同的情况作出不同的反应
- 设备端点接收数据正常,则设备向主机返回ACK,通知主机数据接收完成。如果数据校验出错,将不返回任何握手信息;
- 设备忙,无法接收主机发送的数据,则返回NAK包,通知主机再次发送数据;
- 设备端点出错,则向主机发送STALL包,事务提前结束,总线进入空闲状态。
SETUP 事务
令牌包阶段:主机发送一个PID为SETUP的设置包给设备,通知设备要进行设置;
数据包阶段:主机向设备发送数据包DATA0;
握手包阶段:SETUP事务中,设备必须接受主机发送的数据包,设备根据情况可能返回ACK、NAK、STALL包,如果非控制端点接收到SETUP令牌包,必须忽略事务并返回NAK。
传输
传输由 OUT 、IN 、SETUP 事务中的事务组成,传输分为 中断传输、批量传输、控制传输和同步传输。其中中断传输和批量传输结构一致,同步传输结构最简单,而控制传输最重要也最复杂。
中断传输
由OUT、 IN事务构成,主要用于键盘、鼠标等HID设备的数据传输;
批量传输
由OUT、 IN事务构成,主要用于大容量数据传输,没有固定的传输速率也不占带宽,当总线忙时,USB会优先进行其它类型的数据传输而暂停批量传输。
同步传输
由OUT和IN事务构成,相较于中断传输和批量传输,同步传输的IN 和 OUT事务中没有握手包阶段,且数据包均为 DATA0。
控制传输
控制传输时最重要也是最复杂的传输,主要用于主机对设备的识别和配置。控制传输主要由三个阶段构成:初始设置阶段、可选数据阶段、状态信息阶段,每一个阶段都可以看作是一个传输。
- 初始设置阶段:一个由SETUP事务构成的传输;
- 可选数据阶段:由一个或多个IN或OUT事务构成的传输,根据初始设置阶段是否要求发送/接收数据,此阶段可选。
- 状态信息阶段:这一阶段是获取状态信息,由IN或OUT事务构成,使用DATA1传输。
当控制端点在控制传输的数据或状态阶段向主机返回STALL时,必须对后续所有的事务返回STALL,直到接收到新的SETUP包为止。接收到新的SETUP包,设备不需要返回STALL。对于默认端点,如果在SETUP事务中返回ACK,则主机认为端点已经从异常状态(导致前面返回STALL的状态)中恢复,此时端点必须正确相应主机的指令。