谷动谷力

标题: 深入理解USB2.0通信协议——解读USB报文的神秘语言 [打印本页]

作者: sunsili    时间: 2024-4-10 14:33
标题: 深入理解USB2.0通信协议——解读USB报文的神秘语言
本帖最后由 sunsili 于 2024-4-10 14:45 编辑

深入理解USB2.0通信协议——解读USB报文的神秘语言


导言

上一节我们详细讨论了USB的比特级编解码,本章将以此为基础,进一步介绍USB字段及包的格式。USB包的构成是一个逐层的过程,信息首先以二进制串行数据的形式存在。这些串行数据按照特定规则被组织成字段(filed),字段(filed)是包(packet)的基本单元。多个字段(filed)按照一定的顺序组成一个包(packed),进一步地,多个包(packed)可以组成一个事务(transaction),事务(transaction)是USB通信中更大粒度的数据传输单元。最终,多个事务(transaction)组成一个传输(transfer),代表了一个完整的数据传输过程。本文主要讲解Packet,下一章将会探讨USB事务(transaction)的传输过程。


1 字段(filed)

所有包都有包开始(SOP)和结束(EOP)界定符。包(packet)与开始界定符(SOP)的分隔符是 SYNC 字段。输入电路使用SYNC来将输入数据与本地时钟对齐,SYNC 字段中的最后两位是一个标记,用于识别 SYNC 字段的结束,并通过推断识别 PID 的开始。字段(filed)是包(packet)的基本单元,每种包(packet)都有对应的字段。



包标识符字段(PID)


地址字段

地址字段有两部分组成:功能地址字段(ADDR)和端点字段(EP)。

如果包的地址字段与设备端点不匹配则必须忽略这个包。

「功能地址字段(ADDR Field)」

端点字段(Endpoint Field)

帧号字段(Frame Number Field)
数据字段(Data Field)
CRC字段(CRC Field)

和以太网类似,USB包在末尾也会有校验字段CRC,其CRC的校验不包括PID字段,主要校验PID之后的地址、帧号、数据等字段。USB包的CRC有两种分别应用于两种不同的场合:

「令牌CRC(Token CRC)」

「数据CRC(Data CRC)」



2 数据包(Packet)



USB(Universal Serial Bus)的数据传输基本单位是数据包(Packet)。USB数据包根据不同的令牌类型和传输阶段,有不同的格式和含义。常见的令牌类型包括IN、OUT、SETUP、SOF(Start of Frame)等。整个USB通信过程由一系列数据包组成,这些数据包通过同步和特定字段的解析,实现设备之间的可靠数据传输。


令牌包(Token Packets)
帧起始包(Start-of-Frame Packets(SOF))
数据包(Data Packets)
SPLIT包(分割事务包)

在 USB 中,分割事务(Split Transaction)是一种特殊的通信机制,允许高速 USB 主机与全速/低速 USB 设备进行通信。这个过程涉及两个令牌:开始分割事务令牌(Start-Split Transaction Token)和完成分割事务令牌(Complete-Split Transaction Token)。这种机制使得高速主机能够与全速或低速设备进行通信,同时维持 USB 总线的高速性能。分割事务的应用场景通常涉及带有分层结构的 USB 架构,例如 USB hub 将高速总线转换为全速或低速总线。


「开始分割事务令牌(Start-Split Transaction Token)」

Hub addr 字段:包含支持此全/低速事务的指定全/低速设备的集线器的 USB 设备地址(与功能地址字段涵义相同(ADD))

SC字段(开始/完成):设置为零的 SPLIT 特殊令牌包指示这是一个开始分割事务(SSPLIT)。

Port字段:包含此全速/低速事务指定的目标集线器的端口号。

S字段(速度):指定此中断或控制事务的速度 , 0 – 全速  1 – 低速

E字段(结束):对于全速等时 OUT 起始分割,S1(起始)和 E(结束)字段指定高速数据有效负载如何对应全速数据包的数据

以下开始分割情况S字段必须设置为零:

批量(bulk)事务 IN/OUT

等时( isochronous )事务 IN 开始分割

以下开始分割情况E字段必须设置为零:

批量(bulk)/控制(control)事务 IN/OUT

中断(interrupt) IN/OUT

等时( isochronous )事务 IN


ET(Endpoint Type)字段:指定全速/低速事务的端点类型


当高速主机需要与全速或低速设备进行通信时,它发送开始分割事务令牌

「完成分割事务令牌(Complete-Split Transaction Token)」

SC 字段:设置为 1 ,指示这是一个完全分割事务 (CSPLIT)

U 字段(保留/未使用):必须置为零 (0B)

完全分割令牌包的其他字段与开始分割令牌包具有相同的定义


完成分割事务令牌用于结束分割事务,确认数据已经成功传输给全速/低速设备。

握手包(Handshake Packets)

握手包有四种类型以及一种特殊的握手包:

ACK(确认)

场景:假设主机向 USB 设备的 OUT 端点发送数据,设备成功接收并处理数据。

示例:数据传输结束后,设备可以返回 ACK 作为响应。主机接收到 ACK 后,知道数据已被成功接收,可以继续下一步的通信。


「NAK(否定)」

场景:假设一个 USB 设备在接收数据的过程中发现临时无法处理,可能是因为其缓冲区已满。

示例:在一个 OUT 事务中,当设备无法接受更多的数据时,它可以返回 NAK。主机收到 NAK 后,可能会尝试重新发送数据,直到设备准备好接收。


「STALL(停止)」

场景:设备检测到数据出现错误或设备无法接受主机的请求,需要中止当前的数据传输。

示例:在一个控制事务中,主机向设备发送了一个请求,但设备当前无法响应,可以返回 STALL。这可能是因为设备不支持该请求,或者由于某种原因导致无法继续。主机接收到 STALL 后,可能采取相应的措施,例如中止或重新尝试传输。


「NYET(Not yet)」

场景:假设一个高速 USB 设备正在执行分割事务,其中包含一个低速或全速的子事务,而目标设备还没有完成数据传输。

示例:分割事务的低速或全速子事务尚未完成时,集线器可以返回 NYET。主机可以根据 NYET 信号来决定是否等待,以便在目标设备准备好接收数据时继续传输。


ERR(错误)

场景:假设一个高速 USB 集线器在执行分割事务时发生了错误,导致无法完成全速或低速事务。

示例:集线器可能返回 ERR,通知主机发生了错误。主机在接收 ERR 后,可能会采取适当的措施,如尝试重新发送数据或采取其他纠正措施。








欢迎光临 谷动谷力 (http://bbs.sunsili.com/) Powered by Discuz! X3.2