8 协议层(Protocol Layer)
协议层管理 Host 和 Device 间 end-to-end 数据流,是建立在链路层正确传输基础上的。本章详细描述:
- 包类型;(LMP,DP,TP,ITP)
- 包格式;
- 包期待的响应;
- 四种 transaction 类型
8.12 TP 流程(TP Sequences)
由事务处理组成的包依赖端点类型变化。有四种端点类型:块,控制,中断和同步。
8.12.1 块事务处理(Bulk Transactions)
块事务处理类型具有通过错误检测与重试保证无错误的在主机与设备之间传输数据的属性。块事务处理使用由 TPs 和 DPs 组成的双相事务处理。
8.12.1.1 状态机注释信息(State Machine Notation Information)
这个区域展示详细的需要在 IN 和 OUT 管道上提出协议的主机和设备状态机制。
Figure 8-35 展示了状态机的图解。
8.12.1.2 块输入事务处理(Bulk IN Transactions)
当主机准备好接收块数据时,它就发送一个 ACK TP 给设备指示它想要的从设备得到的包顺序号与包数量。
主机应该为每个从设备收到的有效 DP 发送一个 ACK TP 。如果前一个 ACK TP 指示主机期待设备发送不止 1 个 DP(Data Packet)(依赖于 TP(Transaction Packet) 中 NumP 域值),则设备不必等待 ACK TP 就可以发送下一个 DP 给主机。 ACK TP 暗中用前一个被主机成功接受到的顺序号来应答最后的 DP 也对设备指示下一个顺序号的 DP 和主机想要从设备获得的包数量。如果主机在收到 DP 时检测到一个错误,它应该发送一个顺序号值被设置为发生错误的第一个包顺序号的 ACK TP ,其 retry 位也要置位,即使是这个包以后的包都没有错误发生。设备需要重新发送从发生错误的那个顺序号包开始的所有 DPs 。
当端点初始化后(通过命令 Set Confguration,Set Interface,ClearFeature(STALL)参考 Chapter 9 命令),主机开始第一次从端点接收数据的传输,主机期待第一个 DP 的顺序号被设为 0 。第二个被设备端点发送的 DP 顺序号应该被设置为 1 ;第三个被设备发送的 DP 顺序号应该设为 2 ,…… 直到顺序号为 31,顺序号 31 的下一个 DP 的顺序号又为 0 。一个设备端点保持它发送的包顺序号递增,除非它收到一个带有 retry 位置位的 ACK TP ,这指示主机不得不重新发送前一个 DP 。
如果主机要求从设备获得多个 DP,设备在那时刻没有那么多有效的 DPs 可以发送,则设备发送最后的 DP 应该在 DPH(Data Packet Header) 中的 EOB(End Of Burst) 标志置位(因为有部分数据可以发送,所以不发送 NRDY TP)。当再有数据发送时,设备要发送 ERDY TP 给主机。注意:如果被发送给主机的 DP 的数据量比端点中定义的最大包尺寸少(短包),则没有必要设备 EOB 标志。当设备发送了所有被主机期待的数据时或发送了一个比最大数据包尺寸小的 DP(短包)时,传输就完成了。当主机想要开始一次新的传输,它应该发送另外的期待从设备获得的下一个顺序号和 DPs 数量的 ACK TP 。例如,如果数据量比最大包尺寸小的 DP 为 2 , 则主机应该通过发送一个带有期待顺序号被设为 3 的 ACK TP 来开始新传输。
8.12.1.3 块输出事务处理(Bulk OUT Transactions)
当主机准备发送块数据时,它会发送一个或多个 DPs 给设备。如果设备收到有效的 DPH(有效的 device address,endpoint number,direction 和期待的顺序号),它应该以 Section 8.11.3 定义的 应答。
在端点初始化之后,主机总是在第一次对端点输出数据的传输中,以第一个 DP 顺序号为 0 开始。第二个被设备端点发送的 DP 顺序号应该被设置为 1;第三个被设备发送的 DP 顺序号应该设为 2,…… 直到顺序号为 31,31 的下一个顺序号为 0 。主机保持它发送的包顺序号递增,除非它收到一个带有 retry 位置位的 ACK TP ,这指示主机不得不重新发送前一个 DP 。
传输是在主机发送完所有它要发给设备的数据时完成。然而,传输的最后 DP 可能有或没有一个等于端点最大包尺寸大小的数据。当主机想要开始一次新传输,它应该发送另外的 DP ,这个 DP 带有下一个目标端点想要的顺序号。
8.12.1.4 块流协议(Bulk Streaming Protocol)
流(Stream )协议遵循标准超速块(Enhanced SuperSpeed Bulk )协议,因此在支持流的超速块管道上进行的数据包交换与不支持流的超速块管道上的数据包交换没有什么区别。流协议通过包头中的流 ID 域的操作被严格管理。
注意:如这个区域描述一样,流协议适用于管道状态,它被描述成单个实体。实际上,流协议在管道的一端独立的被主机追踪,在另外一端被设备追踪。所以由于在主机与设备间的包传播延迟,任何时刻两端可能随时不相同。
Figure 8-38 展示了流协议状态机制(SPSM,General Stream Protocol State Machine)的基本状态转变。这里描述了当它们都适用于 IN 和 OUT 端点时的一般 SPSM 转变。IN 和 OUT 端点的 SPSM 的详细操作在随后的区域中被描述。
Disabled —— 这是在被配置后管道的初始化状态。如果在任何其他状态中检测到错误,则转变到这个状态。一个端点 buffer 第一次被分配到一个管道时,主机应该把 SPSM 转变成 Prime Pipe 状态。如果由于错误进入 Disabled 状态,那么错误条件必须在状态退出之前由软件的介入来消除。注意错误(stall,超时等)应该要把任何 SPSM 状态转变成 Disabled 状态。
Prime Pipe —— 这个状态总是被主机初始化,通知设备端点 buffer 设置已经被软件添加或修改。
ldle —— 这个状态指示当前流没有被选择。在这种状态,SPSM 正 等待 Prime Pipe 或主机初始化转变成 Move Data 状态,或者设备初始化转变成 Start Stream 状态。主机和设备初始化转变的对象是开始一次流(被主机或设备各自设置为当前流),开始移动数据。
Start Stream —— 当想要选择一个流或开始一次数据传输时,这个状态总是被设备初始化得来的。如果设备选择的流被主机接收,则当前流被设置,管道进入 Move Data 状态。如果设备选择的流被主机拒绝,管道返回 Idle 状态。
Move Data —— 在这个状态中,流数据被传输。如果这个状态是由于主机初始化流选择而进入的,则当前流应该被主机设置。如果这个状态是从 Start Stream 状态进入的,则当前流选择被设备设置。当流传输完成时或者如果主机或设备决定终止流传输时 SPSM 转变回 Idle 状态。转变成 Idle 状态使管道的当前流无效。
注意:一般规则是,Stream 状态机仅在接收到良好的 DP 或 TP 时才会前进。例如,如果接收到的 DP 带有错误的 DPP,则 Stream 状态机应在当前状态下执行任何重试,并且仅在传输了良好的数据包时才前进。
8.12.1.4.1 流 ID(Stream IDs)
一个 16 位域的流 ID 域在 DP 头中被保留,也保留在主机和设备间传输流 ID 的 ACK,NRDY,ERDY TP 中。流协议和其他 SID 表示法保留的特定 SID 值包括:
Nostream —— 这个流 ID 指示没有流 ID 被分配给各个相关的总线包,流 ID 域应该不被解释成有效流。NoStream 流 ID 值是 FFFFh 。
Prime —— 这个流 ID 被用来定义转变到 Prime Pipe 状态或从 Prime Pipe 状态中转变出来。Prime 流 ID 是 FFFEh。
Stream n —— n 是在 1 到 65533(FFFDh) 之间的值。这个标记是用来指示一个有效流 ID 。如果使用这种标记,则在包头中的流 ID 域是有效的。有效的 Stream n 流 ID 值当中的 n 值,是在 1 到 65533(FFFDh) 之间。
Stream 0 —— 这个值保留,不被管道用来支持流。Stream 0 流 ID 值是 0000h 。它需要被标准块管道使用。
CStream —— 代表被分配给管道的当前流 ID 的值,一个 CStream 值都被主机和设备操控。流协议确保 CStream 值在主机与设备中是一致的。有效值是 NoStream 或 Stream n 。
LCStream —— 代表在最后一个状态转变之前被分配给管道的 CStream 流 ID 的值。一个 LCStream 值被主机操控,有效值为 Prime,NoStream,或 Stream n 。例如,当在 Move Data 状态下 CStream=Stream n 的管道从 Move Data 到 ldle 状态转变时,LCStream 被设置为 Stream n,CStream 被设置为 NoStream,因此 LCStream 记录了 “最后的(上一个)当前流” 值。
Stream n 流 ID 值被主机分配,被传递到一个设备。Stream n 流 ID 值应该被设备当成一个逻辑值对待,即设备不应该从值中推断出任何意思或修改它。
注意:下面描述的块 IN 和 OUT 流协议是简化了的状态机制,没有明确仔细说明超速端点的突发特性(允许 DP 没有收到 ACK 就被发送)。一个实施应该扩展这些状态机制管理突发。
8.12.1.4.2 块 IN 流协议(Device IN Stream Protocol)
本部分定义了增强型 SuperSpeed 数据包交换,该数据包交换将 IN 批量端点上的流协议的设备端从一种状态转换为另一种状态。
对于 IN 管道,主机中端点 buffers 从设备收到功能数据:
Disabled,端点被配置以后,管道在 Disabled 状态。主机应该通过发送流 ID 域设置为 Prime 的 ACK TP 将管道转变成 Prime Pipe 状态。这个转变在端点 buffers 被系统软件分配到管道上后发生。
设备会通过发流 ID 域设置为 Prime 的 NRDY TP 引起管道退出 Prime Pipe 状态,转变到 ldle 状态。
注意:如果中间的集线器(deferred)延迟了 ACK TP,则主机和设备会犹如设备发送一个 NRDY TP 一样。即,当收到延迟应答时,主机会转变到 Idle 状态。当收到延迟 ACK TP 时,设备会转变到 Prime Pipe 状态,然后立刻转变到 Idle 状态犹如它已经发送了流 ID 域设置为 Prime 的 NRDY TP。
在 ldle 状态下,管道正在等待流选择(例如一次到 Start Stream 或 Move Data 的转变)或等待端点 buffers 已经为管道被添加或修改的主机通知(转变到 Prime Pipe)。在 Idle 状态,被主机初始化的流选择通过流 ID 被设置为 Stream n 和 NumP 值大于 0 的 ACK TP 确认。这个包会将 ISPSM 从 ldle 状态转变成 Move Data 状态。如果最后一次的 ISPSM 是从 Start Stream 或 Move Data 转变的,则主机会由于两个可能的条件而开始一次从 ldle 到 Move Data 状态的转变:
如果为 LCStream 而给管道布置端点 buffer ,并且最后的 ISPSM 转变不是由于一个 NRDY(Stream n)Move Data 状态退出;
如果是为新的流布置端点 buffer(例如新发送的不等于 LCStream 的流 ID )。在 ldle 中,被设备开始的流选择是通过一个流 ID 被设置为 Stream n,NumP 值大于 0 的 ERDY TP 来确认的。这个包会将 ISPSM 从 ldle 状态到 Start Stream 状态转变。当设备想要开始流传输时,不管它是否在一个流控制条件中,都应该开始这个转变。
在 Start stream 状态下,管道正等待主机接收或拒绝设备发起的流选择。主机会通过发送一个 StreamID=Stream n 和 NumP>0 的 ACK TP 来指示接收到设备初始化的流选择这个包会历经从 Start Stream 状态到 Move Data 状态的 ISPSM 转变。主机会通过发送 StreamID=NoStream ,NumP=0,Packet Pending(PP)= 0 的 ACK TP 来指示拒绝由设备初始化的流选择。这个包会历经从 Start Stream state 到 Idle state 的 ISPSM 转变。如果没有有效端点 buffer 为设备选择流 ID ,主机会拒绝流选择。
ISPSM 独立的在主机和设备上执行。一种条件发生:如果设备发送一个 ERDY 给主机,并且进入 Start Stream 状态,与此同时,主机发送 ACK(Prime,PP=0) 给设备,并且进入 Prime Pipe 状态。为了从此条件中恢复,如果设备在 Start Stream 状态下接收到一个 ACK(Prime,PP=0),它会转变到 Prime Pipe Ack 状态,并且发送一个 NRDY(Prime) 给主机为主机完成从 Prime Pipe 到 ldle 状态的转变,和为设备完成从 Prime PipeAck 到 ldle 状态的转变。
在 Move Data 状态,当前流在管道的两端被设置,并且管道被激活移动数据到主机。总线事务处理在 Move Data 状态的执行和它的退出条件在下面的 IN Move Data State Machine 详细定义
如上面描述,IN Move Data 状态机制(IMDSM)是从 Start Stream 或 ldle 状态进入的。当转变到 INMvData Device 状态,就立刻进入 IMDSM。 所有被 IMDSM 产生的包的流 ID 域会是 Stream n 。
每次进入 INMvDataDevice 状态时,设备都会进行下面的操作进入 IMDSM:
if (Device Function Data bytes > Max Packet Size) { 设备会产生一个 EOB 域值为 0 的 DP ,这会引起管道转变成 INMvDataHost 状态 } else if (Device Function Data bytes = Max Packet Size) { 设备会产生一个 EOB 域值为 1 的 DP ,这会引起管道转变成 INMvDataDeviceTerminate 状态 } else (Device Function Data bytes < Max Packet Size ) { 设备会产生一个短包 DP ,这会引起管道转变成 INMvDataDeviceTerminate 状态 }
可选择的,设备可以产生一个流 ID 设置为 Stream n 的 NRDY TP 终止流,会引起管道退出 IMDSM,转变成 Idle 状态。设备可以使用这个转变来拒绝由主机初始化的 Move Data 。
注意:如果中间的集线器(deferred)延迟了 ACK TP,主机和设备会视如设备发送了一个 NRDY TP 。即当主机收到延迟的应答,它会转变到 Idle 状态。当设备收到(deferred 延迟的 ACK TP 时犹如它收到了一个流 ID 域设置为 Stream n 的 NRDY TP ,它会退出 IMDSM,转变到 Idle 状态。如果设备接收主机初始化的流 ID,它会发送一个流 ID 域设置为 Stream n 的 ERDY。如果设备拒绝由主机初始化的流 ID,它会停留在 ldle 状态,并且等待下一个主机或设备初始化的流选择。
INMvData Host 状态的进入是因为设备有更多的功能数据要发送,所以主机要执行下面的操作进入 IMDSM:
if ( 在此次突发中能安排另外的 DP ) { if (主机有更多的有效端点 buffers) { 产生 NumP>0 的 ACKTP,这会引起管道转变到 INMvDataDevice 状态 } else (主机没有有效空间) { 产生一个NumP=0 and PP=0 的 ACK TP 结束,这会引起管道退出 IMDSM 转变到 Idle 状态。 } } else (已经收到突发的最后一个 DP) { 终止突发; if (主机有更多的有效端点buffers) { 通知设备突发完成(NumP=0)主机应该为 CStream 安排另外一次突发(PP=1)产生 NumP=0,PP=1 的 ACK TP,这会引起管道转变成 INMvData Burst End 状态。 } else { // (主机没有有效空间) 产生 NumP=0 and PP=0 的 ACK TP 终止,这会引起管道退出 IMDSM ,转变成 Idle 状态。 } }
在 INMvData Burst End 状态中,主机会产生 NumP>0 and PP=1 的 ACK 开始下一次突发,引起管道转变成 INMvData Device 状态。
Pseudo 码描述 IMDSM 假设收到的 DP 是有效的。如果它无效,则 ACK TP 被产生,这会把管道转变成 INMvDataDevice 状态。ACK TP 中的顺序号不会上涨,然后,重试位可以减少发送的 NumP 值。如果 NumP=0,并且主机中还有有效的端点 buffer,PP 会被设置为 1 ;否则,PP 被设置为 0 。
INMvData Device Terminate 状态的进入是因为设备没有更多的功能数据要发送,所以主机会产生一个 NumP=0 and PP=0 的 ACK TP 终止,这会引起管道退出 IMDSM,并且转变成 ldle 状态。如果主机在最后一个被设备发送的 DP 中检测到一个错误,它会以带有重试位的 ACK TP(Stream n,NumP>0,Rty) 应答,IMDSM 会转变成 INMvDataDevice 状态。
注意:如果 DP 错误在 INMvDataHost 中被检测到,主机会产生一个 NumP>0 and Rty=1 的 ACK TP,这会引起管道转变成 INMvDataDevice 状态,并且重新发送包。
8.12.1.4.3 块 OUT 流协议(Device OUT Stream Protocol)
这个区域定于了超速包交换进行从一个状态转变到另外一个状态的输出块端点上的流协议
对于输出管道,主机的端点数据被发送到功能设备的 buffers 中,除非另外的规定,DP 将包含端点数据。
在端点配置后,管道在 Disabled 状态。主机通过发送带有流 ID 域设为 Prime 的 DP 要将管道转变成 Prime Pipe 状态。这个转变发生在端点 buffers 被主机软件分配给管道之后。
8.12.1.4.4 主机 IN 流协议(Host IN Stream Protocol)
对于 IN 管道,主机中的端点缓冲区从设备接收函数数据。
8.12.1.4.5 主机 OUT 流协议(Host OUT Stream Protocol)
对于 OUT 管道,设备中的函数缓冲区从主机接收端点数据。
USB3.2 摘录(五)(下):https://developer.aliyun.com/article/1598693?spm=a2c6h.13148508.setting.14.718e4f0ecD7glF