您现在的位置: USB开发网 > USB技术文档 > USB专题 > USB1.1协议中文完整在线版
USB1.1协议中文完整在线版

8 USB协议层

------分隔线----------------------------

   这章从字段(Field)和包(Packet)的定义开始,从底向上地展示USB(Univeral Serial Bus)协议。接着是对不同事务(Transaction)类型的包事务格式的描述。然后是链路层(Link layer)流程控制(Flow Control)和事务级别的故障恢复(Fault recovery)。本章的最后将讨论复执同步化(Retry synchronization),超时干扰(Babble)和总线活动丧失(Loss of bus activity)的恢复。

8.1 位定序

  数据位被发送到总线的时候,首先最低有效位(LSb),跟着是下一个最低有效位,最后是最高有效位(MSb)。在以后图表中的,包以下列形式给出,即包中单个的位和字段从左到右的顺序就是它们通过总线的顺序。
 
8.2同步字段 
 
  所有的包都从同步(SYNC)字段开始的,同步字段是产生最大的边缘转换密度(Edge TransitionDensity)的编码序列。同步字段作为空闲状态出现在总线上,后面跟着以NRZI编码的二进制串“KJKJKJKK”。通过被定义为8位长的二进制串,输入电路以本地时钟对齐输入数据。同步字段是用于同步的机制,在以后图表当中将不被表示(参照节7.1.10)。同步字段里的最后的2位是同步字段结束的记号,并且标志了包标识符(PID,Packet Identifer)的开始。
 
8.3包字段格式
 
  在后面几节将描述标记,数据和握手包的字段格式。包中位的定义是以未编码的数据格式给出。为了清楚起见,在此不考虑NRZI编码和位填充(Bit Stuffing)的影响。所有的包都分别有包开始(Start-of-Packet)和包结束(End-of-Packet)分隔符。包开始(SOP)分隔符是同步字段的一部分,而包结束(EOP)分隔符在第7章有所描述。
 
8.3.1包标识符字段
  
  所有USB包的同步字段后都紧跟着包标识符(PID)。如图8-1所示,包标识符由4位的包类型字段和其后的4位的校验字段构成。包标识符指出了包的类型,并由此隐含地指出了包的格式和包上所用错误检测的类型。包标识符的4位的校验字段可以保证包标识符译码的可靠性,这样包的余项也就能被正确地解释。包标识符的校验字段通过对包类型字段的二进制的求反码产生的。如果4 个PID检验位不是它们的各自的包标识符位的补,则说明存在PID错。
 
PID 格式
图8-1 PID 格式
 
  主机和所有功能部件都必须对得到全部PID字段实行完整的译码。任何收到包标识符,如果含有失败的校验字段,或者经译码得到未定义的值,则该包标识符被假定是被损坏的,而且包的余项将被包接收机忽略(Ignore)。如果一个功能部件(Function)收到了包含了它所不支持的事务类型或方向的合法包标识符,则不必应答。例如,只能输入的端口(IN-only Endpoint)必须忽略输出标记(Token)。表8-1列出了包标识符类型,编码及其描述。

 

表8-1 PID 类型

 

PID 类型

PID 名

PID[3:0]

描述

标记

(Token)

输出(OUT)

 

输入(IN)

 

帧开始(SOF)

 

建立(SETUP)

0001B

 

1001B

 

0101B

 

1101B

在主机到功能部件的事务中有地址+端口号

 

在功能部件到主机的事务中有地址+端口号

 

帧开始标记和帧号

 

在主机到功能部件建立一个控制管道的事务中有地址+端口号

数据

(DATA)

数据0(DATA0)

 

数据1(DATA1)

0011B

 

1011B

偶数据包PID

 

奇数据包PID

握手(Handshake)

确认(ACK)

 

不确认(NAK)

 

停止(STALL)

0010B

 

1010B

 

1110B

接收器收到无措数据包;

 

接收设备部不能接收数据,或发送设备不能发送数据;

端口挂起,或一个控制管道请求不被支持。

专用

(Special)

前同步(PRE)

1100B

主机发送的前同步字。打开到低速设备的下行总线通信。

*注解:PID位以最高位在前的顺序被表示。在USB上被发送的时候,最右的位(位0)将被第一个发出。

 

 

  包标识符被分为4个编码组:标记,数据,握手和专用。包标识符传送的前2位(PID<0 : 1>)指出了其属于哪个组。这说明包标识符编码的分布。

8.3.2地址字段

  功能部件端口使用2个字段:功能部件地址字段和端口字段。功能部件对地址和端口字段都需要进行译码。不允许使用地址或端口别名(Aliasing),并且任何一个字段不匹配,此标记都必须被忽略。另外, 对未初始化的端口的访问将使得标记被忽略。

8.3.2.1地址字段

  功能部件地址(ADDR)字段通过其地址指定功能部件,至于是数据包的发出地还是目的地,则取决于标记PID的值。如图8-2所示,ADDR<6 : 0>指定了总共128个地址。地址字段被用于输入,建立和输出标记。由定义可知,每个ADDR值都定义了单一的功能部件。刚一复位(Reset)和加电(Power-up)的时候,功能部件的地址默认值为零,并且必须由主机在枚举过程(Enumeration Process)中编程。功能部件地址零被用作为缺省地址,不可被分配作任何别的用途。

 

图8-2 地址字段
 
8.3.2.2端口字段
  
  如图8-3所示,附加的4位的端口(ENDP)字段在功能部件需要一个以上端口时候允许更灵活的寻址。除了端口地址0之外,端口个数是由功能部件决定的。端口字段只对输入,建立和输出标记PID有定义。所有的功能部件都必须在端口0提供一个控制管道(缺省控制管道)。对于低速(Low Speed)设备,每个功能部件最多提供3个管道:在端口0的控制管道加上2个附加管道(或是2个控制管道,或是1个控制管道和1个中断端口,或是2个中断端口)。全速(Full Speed)功能部件可以支持最多可达16个的任何类型的端口。
 
 
图8-3 端口字段
图8-3 端口字段
 

8.3.3帧号字段

  帧号字段是一个11位的字段,主机每过一帧就将其内容加一。帧号字段达到其最大值7FFH时归零,且它仅每个帧最初时刻在SOF标记中被发送。

8.3.4数据字段

  数据字段可以在0到1,023字节之间变动,但必须是整数个字节。图8-4为多字节显示格式。每个字节的范围内的数据位移出时都是最低位(LSb)在前。

 

数据字段格式
图8-4 数据字段格式
 
  如同在第5章所描述的那样,数据包大小随着传送类型而变化。
 
8.3.5循环冗余校验
 
  循环冗余校验(CRC)被用来在标记和数据包中保护所有的非PID字段。在上下文中,这些字段被认为是保护字段。PID不在含有CRC的包的CRC校验范围内。在位填充之前,在发送器中所有的CRC都由它们的各自的字段产生。同样地,在填充位被去除之后,CRC在接收器中被译码。标记和数据包的CRC可100 %判断单位错和双位错。失败的CRC指出了保护字段中至少有一个字段被损坏,并导致接收器忽略那些字段,且在大部分情况下忽略整个包。为了CRC的发生和校检,发生器和检验器里的移位寄存器置成为全1(All-ones)型。对于每个被发送或者被收到的数据位,当前余项的最高一位和数据位进行异或(XOR),然后,余项是左移1位,并且,最低一位置零。如果异或的结果是1,余项和生成多项式作异或。当检查的字段的最后的一位被发送的时候,发生器里的CRC被颠倒,再以最高位(MSb)在前发给检验器。当检验器收到CRC的最后的一位,且不发生错误的时候,余项将等于多项式的的剩余。如果剩余与包接收器中最后计算出的检验和余项(Checksum remainder)不匹配,则存在CRC误差。对于CRC,必须满足位填充的要求,且如果前6位都是1的话,这包括在CRC的最后插入零。
 
8.3.5.1标记CRC
  
  标记使用了5位的CRC字段,它覆盖了输入,建立和输出标记的ADDR和ENDP字段,或SOF标记的时间戳字段。生成多项式如下:
G(X) = X5 + X2 + 1
 
  这个多项式的二进制位组合是00101B。如果所有的标记位都被准确无误地收到,接收机中的5位剩余将是01100B。
 
8.3.5.2数据CRC
 
  数据CRC是作用于数据包的数据字段上的16位多项式。产生的多项式是如下
G(X) = X16 + X5 + X2 + 1
 
  这个多项式的二进制位组合是1000000000000101B。如果全部的数据和CRC位被准确无误地收到,16位剩余将是1000000000001101B。
 

8.4包格式

  这节展示标记,数据和握手包的包格式。这些图将以位被挪动到总线上的顺序显示包内的字段。

8.4.1标记包

  图8-5显示了标记包的字段格式。标记由PID,ADDR和ENDP构成,其中PID指定了包是输入,输出还是建立类型。对于输出和建立事务,地址和端口字段唯一地确定了接下来将收到数据包的端口。对于输入事务的,这些字段唯一地确定了哪个端口应该传送数据包。只有主机能发出标记包。输入PID定义了从功能部件到主机的数据事务。输出和建立PID定义了从主机到功能部件的数据事务。

 

标记包格式
图8-5 标记包格式
 
  如上图所示,标记包包括了覆盖地址和端口字段的5位CRC。CRC并不覆盖PID,因为它有自己的校验字段。标记和帧开始(SOF)包是由3个字节的包字段数据后面的包结束(EOP,End of Packet)界定的。如果包被译码为合法标记或SOF,但却没有在3个字节之后以EOP终止,则它被认为是无效的,并被接收器忽略。

8.4.2 帧开始(SOF,Start-of-Frame)包

  主机以每1.00 ms ±0.0005 ms一次的额定速率发出帧开始(SOF)包。如图8-6中所示,SOF包是由指示包类型的PID和其后的11位的帧号字段构成。

 

帧开始包
图8-6 帧开始包图8-6 帧开始包
 
  SOF标记组成了仅有标记的(token-only)事务,它以相对于每帧的开始精确计算的时间间隔发送SOF记号(Marker)和伴随的帧数。包括集线器的所有全速功能部件都可收到SOF包。SOF标记不会使得接收功能部件产生返回包;因此,不能保证向任何给定的功能部件发送的SOF都能被收到。SOF包发送2个时间调配(Timing)信息。当功能部件探测到SOF的PID的时候,它被告知发生SOF。对帧时间敏感而不需要追踪帧数(例如集线器)的功能部件,仅需对SOF的PID译码 ;可忽略帧数和其CRC。如果功能部件需要追踪帧数,它必须对PID和时间戳都进行译码。对总线时间调配信息的没有特别需要的全速设备可以忽略SOF包。
 
8.4.3数据包
 
  如图8-7所示,数据包由PID,包括至少0个字节数据的数据区和CRC构成。有2种类型的数据包,根据不同的PID:DATA0和DATA1来识别。2种数据包PID是为了支持数据切换同步(Data Toggle Synchronization)(在第8.6节提到)而定义的。
 
 
图8-7 数据包格式

图8-7 数据包格式

  数据必须以整数的字节数发出。数据CRC仅通过对包中的数据字段计算而得到,而不包括PID,它有自己的校验字段。

8.4.4握手包

  如图8-8所示,握手包仅由PID构成。握手包用来报告数据事务的状态,能还在表示数据成功接收,命令的接收或拒绝,流控制(Flow Control)和停止(Halt)条件。只有支持流控制的事务类型才能返回握手信号。握手总是在事务的握手时相(Phase)中被返回,也可在数据时相代替数据被返回。握手包由1个字节的包字段后的EOP确定界限。如果包被解读为合法的的握手信号,但没有以1个字节后面的EOP终止,则它被认为是无效的,且被接收机忽略。

 

握手包
图8-8 握手包

有3种类型的握手包:

  • ACK表示数据包没有位填充或数据字段上的CRC错,并且数据PID被正确收到。ACK在下列的情况下被发放,当时序位(Sequence Bit)匹配且接收器能接受数据的时候,或者当时序位失配,但发送方和接收器互相之间必须再同步(Resynchronize)(在第8.6节详细提到)的时候。ACK握手信号只适用于数据被传送且期待握手信号的事务中。对于输入事务,ACK由主机返回,而对于输出或建立事务则由功能部件返回;
  • NAK表示功能部件不会从主机接受数据(对于输出事务),或者功能部件没有传输数据到主机(对于输入事务)。NAK仅由功能部件在输入事务的数据时相返回,或在输出事务的握手时相返回。主机决不能发出NAK。出于流控制的目的,NAK用于表示功能部件暂时不能传输,或者接收数据,但是最终还是能够在不需主机干涉的情况下而传输或接收数据;
  • STALL作为输入标记的回应,或者在输出事务的数据时相之后由功能部件返回(见图8-9和图8-13)。STALL表示功能部件不能传输,或者接收数据,或者不支持一个控制管道请求。在任何条件下都不允许主机返回STALL。

  STALL握手由设备用于在两个不同的场合之一。第一种情况,是当设置了与端口相联系挂起特征(Halt feature)的时候,称为“功能STALL(functional stall) ”(挂起特征在这文档的第9章中详细说明)。功能STALL的特殊情况是“命令STALL(commanded stall)”。如同在第9章中详细叙述的那样,命令STALL发生在主机显式地设置了端口的挂起特征的时候。如果功能部件的端口被挂起,则功能部件必须继续返回STALL,直到引起停止的条件通过主机干涉而被清除。

  如同在节8.5.2中详细叙述的那样,第二种情况称为“协议STALL(protocol stall)”。协议STALL对于控制管道是唯一的。协议STALL和功能STALL在意义和持续时间上是不同。协议STALL在控制传送(Control Transfer)的数据或状态阶段(Stage)被返回,并且,STALL条件在下一个控制传送的开始终止(建立事务)。这节的剩下的部分将提到功能STALL的一般情况。

8.4.5握手回答(Handshake Response)

  传输和接收功能部件必须根据从表8-2中到表8-4详细叙述的优先顺序返回握手。不是所有的握手都是被允许,依赖于事务类型和功能部件或主机是否发出握手。如果标记在传输到功能部件的阶段里发生了错误,则功能部件将不以任何包回应,直到下一个标记被收到并成功地译码。

8.4.5.1功能部件对输入事务回答

  表8-2显示了功能部件作为对输入标记的反应而可能做的回答。如果由于停止或流控制条件,功能部件不能发送数据,它将发出STALL或NAK握手。如果功能部件能发出数据,它就发出数据。如果收到的标记被损坏,则功能部件不应答。

表8-2 功能部件对输入事务的回应

收到的标记损坏

功能部件的发送

端口的挂起特征

功能部件能发送数据

采取的动作

不管

不管

不回应

置了位

不管

发送STALL握手

没置位

发送NAK握手

没置位

发送数据包

8.4.5.2主机对输入事务回答

  表8-3显示了主机对输入事务回答。主机只能返回1种类型的握手:ACK。如果主机收到了损坏的数据包,它把数据丢弃且不应答。如果主机不能从功能部件接受数据,则(出于类似内部缓冲溢出的问题)这条件被认为是错误,并且主机不应答。主机能接受数据,并且如果数据包是完整无错地被接收到,则主机接受数据并发出ACK握手。

表8-3 主机对输入事务的回应

数据包损坏

主机能接受数据

主机返回的握手

N/A

丢弃数据,不回应

丢弃数据,不回应

接受数据,发送ACK

8.4.5.3功能部件对输出事务回答

  对输出事务的握手回答由表8-4表示。假设标记译码成功,功能部件收到数据包后,可以返回三种握手类型中的任何一种。如果数据包被损坏,功能部件不返回握手。如果数据包是被完整无错地接收到,而功能部件的接收端口被停止,则功能部件返回STALL。如果事务正维持着时序位同步而探测到失配(在第8.6节有详细描述),那么功能部件返回ACK,并丢弃数据。如果功能部件能够接受数据并完整无错收到数据,它返回ACK。如果由于流控制的原因,功能部件不能接受数据包,它返回NAK。

表8-4 功能部件对输出处理的回应(按优先顺序)

数据包损坏

接收器的挂起特征

时序位匹配

功能部件可接收数据

功能部件返回的握手

N/A

N/A

N/A

置了位

N/A

N/A

STALL

没置位

N/A

ACK

没置位

ACK

没置位

NAK

8.4.5.4功能部件对建立事务的回答

  建立事务定义了特殊的主机-功能部件的数据事务,它允许主机初始化端口的同步位为主机的同步位。一收到建立标记,功能部件就必须接受数据。功能部件不能对建立标记用STALL或NAK应答,并且,接收功能部件必须接受建立标记后的数据包。如果非控制端口收到建立标记,它必须忽略事务且不应答。

8.5事务格式

  包事务格式根据端口类型而变化。有4种端口类型:批处理(Bulk),控制(Control),中断(Interrupt)和同步(Isochronous)。

8.5.1批处理事务

  批处理事务类型的特点是以错误检测和重试的方式保证主机和功能部件之间的数据的无错发送的能力。如图8-9所示,批处理事务是由标记,数据和握手包构成的三时相的事务。

  在某些流控制和挂起条件下,数据时相被握手信号替换,从而产生了没有数据传输的两时相的事务。

 

USB批处理事务格式
图8-9 批处理事务格式

  当主机准备好了接收批处理数据的时候,它发出输入标记。功能部件端口通过返回数据包,或者如果不能返回数据,则返回NAK或STALL握手作为应答。NAK表示功能部件暂时不能返回数据,而STALL表示端口永久地被停止,需要USB系统软件干涉。如果主机收到合法的的数据包,则它用ACK握手来应答。如果收到数据时主机检测到错误,它不返回握手包给功能部件。

  当主机准备好了传送成批数据的时候,它首先发出一个后跟数据包的输出标记包。如果数据由功能部件无错地接收到,那么它将返回三个握手中的一个 :

  • ACK表示数据包无错地接收到,通知主机可以发送下一个包;
  • NAK表示数据被无错地收到,但主机应该重新发送数据因为数据功能部件处于妨碍它接受数据的暂时的条件(例如缓冲满)中;
  • 如果端口被停止,则返回STALL以告诉主机不要重试传输,因为功能部件上有错误条件。

  如果接收到的数据有CRC或者位填充错,那么不返回任何握手。

   图8-10说明了时序位和数据PID在成批读和写中的用法。数据包同步经数据时序切换位(Sequence Toggle Bit)和DATA0/DATA1 PID的使用而达到。当端口经历配置事件(Configuration event)(配置事件在节9.1.1.5和9.4.5中有解释)的时候,批处理端口的切换时序被初始化为DATA0。端口上的数据切换不是作为短包传送或IRP撤消的直接结果而被初始化的。

 

批处理读和写
图8-10 批处理读和写
  
  主机总是通过配置事件初始化总线传送的第一个事务为DATA0 PID。第二的事务使用DATA1 PID,并且,剩余的后继数据传送轮流切换。数据包发送器根据ACK的接收情况来切换而接收器根据数据包的接收(receipt)和验收(acceptance)的情况切换(参见第8.6节)。
 
8.5.2控制传送
 
  控制传送最少有2个事务阶段:建立和状态。控制传送可以有选择性地包括建立和状态阶段之间的数据阶段。在建立阶段里,建立事务用于向功能部件的控制端口传输信息。建立事务在格式上类似于输出,但是使用的是建立而不是输出的PID。图8-11说明了建立事务的格式。建立总是在建立事务的数据时相上使用DATA0 PID。收到建立的功能部件必须接受建立数据并用ACK应答,如果数据被损坏,则丢弃数据且不返回握手。
 
 
 控制建立事务
图8-11 控制建立事务
 
  控制传送的数据阶段,如果有的话,由一个以上的输入或输出事务构成,遵守和批处理传送相同的协议规则。所有的数据阶段里的事务都必须有相同的方向(即全部输入或者全部输出)。在数据时相中要发送的数据的数量和其方向在建立阶段里被指定。如果数据的数量超过了先前确定的数据包大小,数据在支持最大的包大小的多个事务中被发送(输入或者输出)。任何剩下的数据都作为剩余在最后的事务中被发送。

  控制传送的状态阶段是序列中的最后一个操作。状态阶段是以相对前面的阶段的数据流方向的变化来刻划的,并且总是使用DATA1 PID。例如,如果数据阶段由输出事务构成的,状态是单一的输入事务。如果控制传送序列没有数据阶段,那么它由建立阶段和其后的由输入事务构成的状态阶段构成。图8-12说明了事务顺序,数据时序位的值和控制读写序列的数据PID类型。时序位显示在括号中。

 

控制读写序列
图8-12 控制读写序列
 

  当控制端口在控制传送的数据和状态阶段中发送STALL握手的时候,必须对以后所有对此端口访问返回STALL握手,直到收到建立PID为止。

  端口收到建立PID之后,不应返回STALL握手。

8.5.2.1汇报状态结果

  状态阶段向主机做汇报传送中的先前的建立和数据阶段的结果。可能返回三种结果:

  • 命令序列成功地完成了;
  • 命令序列没能完成;
  • 功能部件还在忙于完成指令。

  汇报状态总是从功能部件到主机的方向。表8-5概括了每一种所需的应答类型。控制写传送在状态阶段的事务的数据时相返回状态信息。而对于控制读传送,主机在状态阶段事务的数据时相中发出零长度的数据包之后,功能部件在握手时相返回状态信息。

表8-5 状态阶段的响应

 

状态响应

控制写传送(在数据时相发送)

控制读传送(在握手时相发送)

功能部件完成

零长度的数据包

ACK握手

功能部件有一个错

STALL 握手

STALL握手

功能部件忙

NAK 握手

NAK握手

   对于控制读,主机向控制管道发送输出标记以启动状态阶段。主机在这一时相中只发送零长度的数据包,但是,功能部件可以把任何长度包作为合法的的状态查询接受下来。应答这个数据包的管道握手表明了现在的状态。NAK说明了功能部件还在事务指令,并且主机应该继续状态阶段。ACK说明了功能部件完成指令,准备好了接受新指令。STALL说明了功能部件现在有妨碍它完成指令的错误。

  对于控制写,主机发送输入标记到控制管道用以启动状态阶段。功能部件使用握手或零长度的数据包应答以说明其现状。NAK说明功能部件还在事务指令,并且主机应该继续状态阶段;返回零长度的包表明指令正常完成;而STALL表示功能部件不能完成指令。功能部件期待主机在状态阶段中对数据包以ACK应答。如果功能部件收不到ACK,它仍处于指令的状态阶段中,并且只要主机再发输入标记,它将继续返回零长度的数据包。

  如果在数据阶段里指令管道被发送或者被请求返回比在建立时相(见节8.5.2.2)中的约定更多的数据,它应该返回STALL。如果控制管道在数据阶段里返回STALL,对于那个控制传送将没有状态阶段。

8.5.2.2可变长度数据阶段

  控制管道可以放进可变长度的数据时相,在可变长度的数据时相中主机请求比指定的数据结构中所能包含的更多的数据。当全部的数据结构被返回到主机的时候,功能部件应该向管道返回一个短于包最大长度(MaxPacketSize)的包以表明数据阶段的结束。如果数据结构是数据是管道包最大长度(wMaxPacketSize)整数倍,功能部件将返回零长度的包以表明数据阶段的结束。

8.5.2.3最后数据事务的出错处理(Error Handling)

  如果输入事务的ACK握手损坏,功能部件和主机在事务是否成功上这个问题上将暂时不一致。如果此事务的后面跟着另一个输入事务,切换重试机制(Toggle Retry Mechanism)将检测失配并从错误中恢复原状。如果此ACK是数据阶段最后的输入事务上的,则不能使用切换重试机制而必须使用另一种机制。

  成功收到最后输入数据的主机将会发送ACK,然后主机将发出输出标记以启动传送的状态阶段。如果功能部件收不到结束数据阶段的ACK,功能部件将好象主机成功地收到数据那样去解释状态阶段的开始。而控制写则没有这种模棱两可的情况。如果输出事务上的ACK握手损坏,主机将不进入状态阶段而是重发最后的数据。节8.6.4有重试策略的详细分析。

8.5.2.4 控制管道返回的STALL握手

  控制管道具有在控制传送中根据功能部件的问题返回STALL握手的独特能力。如果设备不能完成指令,它将在控制传送的数据和(或)状态阶段中返回STALL。与功能STALL的情况不同,协议STALL并不表示设备错误。协议STALL条件一直持续到接受到下一个建立事务,且功能部件将对于任何输入或输出事务返回STALL直到管道上的建立事务被收到为止。一般来说,协议STALL表示请求或者其参数不能被设备所理解,这样提供用来扩展USB请求的机制。

  另外, 控制管道也可以支持功能STALL,但是不推荐使用。因为控制管道上的功能STALL表示它失去和主机通信的能力,所以这是一种退化的情况。如果控制管道的确要支撑功能STALL,它必须拥有能被主机设置或者清除的停止特征。第9章详细叙述事务在控制管道上停止特征的特殊情况的方法。设计良好的设备将把其全部功能和停止特征,与非控制端口联系起来。而控制管道应该预留用于为USB请求提供服务。

8.5.3中断事务

  中断事务可由输入或输出构成。一收到输入标记,功能部件便可返回数据,NAK或STALL。如果端口没有新的中断信息(即没有等待事务的中断)可供返回,功能部件在数据时相里返回NAK握手。如果中断端口的停止特征被设置了,功能部件将返回STALL握手。如果中断是等待事务的,功能部件象数据包那样返回中断信息。作为对数据包接收的反应,主机如果数据无错地被接受则发出ACK握手,或者如果数据包损坏则不返回握手。图8-13说明了中断事务格式。

 

USB中断事务格式
图8-13 中断事务格式

  当端口为实际的中断数据使用中断传送机制的时候,必须遵循数据切换协议。这使功能部件得知主机收到了数据,并且事件条件被清除。这种“确保的”事件传送允许功能部件只发送中断信息直到它被主机接收,而不是在USB系统软件清除中断条件之前,每次数据功能部件被选中时就必须要发送中断数据。

  用于切换模式时,中断端口被端口上的任何配置事件初始化为DATA0 PID,其行为和图8-10所示的批处理一样。

  另外, 中断端口可被用来为某些同步功能部件传达速率反馈信息。用于这种模式时,在每个数据包被送到主机之后,都不管握手包是否存在或类型如何,数据切换位都应该改变。只有中断输入端口支持这种能力。

8.5.4同步事务

  如图8-14所示,同步(ISO)事务有标记和数据时相,而没有握手时相。主机发出输入或输出标记,后跟着端口(输入)或主机(输出)传送数据的数据时相。ISO事务不支持握手时相或重试能力。

 

USB同步事务格式
图8-14 同步事务格式

注解:设备或主机控制器都应该能接受DATA0和DATA1。设备或主机控制器应该只发送DATA0。
ISO事务不支持切换时序。

8.6数据切换同步和重试

  USB提供一种机制以保证多事务中数据发送器和接收器之间的数据序列同步。这种机制提供一种保证发送器和接收器正确地解释事务的握手时相的方法。同步通过DATA0和DATA1 PID,以及分别从属于数据发送器和接收器的切换时序位的使用而完成。

  仅在接收器能接受数据并且收到带有正确的数据PID的无错数据包的时候,接收器时序位才切换。而仅在数据发送器收到合法的ACK握手的时候,发送器时序位才切换。数据发送器和接收器必须在事务开始的时候同步它们的时序位。使用的同步机制随着事务类型而变化。

  ISO传送不支持数据切换同步。

8.6.1 通过建立标记初始化

  控制传送使用建立标记初始化主机和功能部件的时序位。如图8-15所示,主机向功能部件发送建立包,其后跟着输出事务。圆圈里的数代表发送器和接收器的时序位。功能部件必须接受数据并返回ACK。当功能部件接受事务的时候,它必须设置其时序位,以便主机和功能部件的时序位在建立事务的最后都等于1。

 

 建立初始化
图8-15 建立初始化

8.6.2成功的数据事务

  图8-16说明了有两个成功的事务的情况。对于数据发送器,这表示它根据ACK的接收情况来切换其时序位。仅当接收器收到合法的的数据包,并且包的数据PID和其时序位的当前值相匹配的时候,才切换其时序位。发送器在它收到数据包的ACK时才切换其时序位。

  在每个事务中,接收器比较发送器的时序位(在数据包PID中编码为DATA0和DATA1)接收器的时序位。如果数据不能被接受,接收器必须发出NAK,并且,发送器和接收器的时序位保持不变。如果数据能被接受,并且接收器的时序位和PID相匹配,则数据被接受,并且时序位被切换。没有数据包的两时相的事务不使得发送器和接收器改变其时序位。

图8-16 连续的传送
 

8.6.3损坏,或者不被接受数据

  如果数据不能被接受,或者得到的数据包被损坏,接收器将根据情况发出NAK或STALL握手,或者超时(Timeout),并且,接收器将不切换其时序位。图8-17说明了事务被返回NAK,然后被重试的情况。任何非ACK握手或是超时都将产生类似的重试动作。没有收到ACK握手的发送器,将不切换其时序位。其结果是失败的数据包事务使得发送器和接收器的时序位同步并不切换。然后事务将被重试,如果成功,将引发发送器和接收器时序位的切换。

重试的不被确认的事务
图8-17 重试的不被确认的事务

8.6.4损坏的ACK握手

  发送器是根据其收到ACK握手确切地知道事务是否成功的最后并且唯一代理。如图8-18所示,丢失或者损坏的ACK握手使得发送器和接收器之间的暂时失去同步。这里发送器在发出合法的数据包,且接收机成功地收到;但是ACK握手损坏。

重试的ACK损坏的事务
图8-18 重试的ACK损坏的事务

  在事务i的最后,由它们各自的时序位间的失配可看出发送器和接收器暂时失去了同步。接收器已经收到了正确的数据,但是,发送器不知道它是否成功地发送了数据。在下一个事务中,发送器将重发使用DATA0 PID的先前的数据。接收器时序位和数据PID将不匹配,于是接收器知道它以前接受了这个数据。从而它丢弃此数据包且不切换其时序位。然后接收器发放ACK,使得发送器知道被重试的事务成功了。ACK的接收使得发送器切换其时序位。在事务i+1的开头,其时序位被切换,于是再一次同步了。

  数据发送器必须保证任何被重试的数据包都和先前的事务发送的包相同(相同长度和内容)。由于类似缓冲欠载(Underrun)条件等问题,数据发送器不能传送和在先前的数据包中数据完全一样的数据中,它必须通过产生一位填充违反(Bit Stuffing Violation);来中止事务。这将引起一个接收器的可检测的错误,从而保证接收器不会将部分的包解释为好包。发送器不应该通过发送已知的坏的CRC在接收器产生一个错误。带有“坏”CRC的坏包会被接收器解释成好包。

8.6.5低速事务

  USB支持以两种速度发信号:以12.0Mb/s发信号的全速(Full-speed)和以1.5Mb/s发信号的低速(Low-speed)。在发全速下行(Downstream)信号中,集线器禁止所有挂有低速设备的端口收到下行总线通信。这是出于EMI和防止低速设备将一个全速包曲解为包是发送给它的考虑。图8-19说明了一个主机发出标记和握手并收到数据包的低速输入事务。

 

USB低速事务
图8-19 USB低速事务

 

  所有传送到低速设备的下行包都需要前同步信号(Preamble)。前同步信号由SYNC和其后的PRE(Preamble) PID构成——二者都以全速发送。集线器必须解释PRE PID ;所有其他的USB设备都可以忽略它,把它当作未定义来处理它。在前同步信号PID的结束后,主机必须等待至少4个全速位时间(Bit time),而此间集线器必须完成启动和低速设备连接的端口上的重复器(Repeater)功能。在这个集线器建立的间隔里,集线器必须把它们的全速和低速端口置于它们各自的空闲状态。集线器必须在集线器建立间隔结束之前,准备好重复低速端口上所发的低速信号。

低速连接规则概括如下:

1.低速设备在连接过程中被识别,并且连接它们的集线器端口被识别为低速;

2.所有的下行低速包必须用打开低速集线器端口上的输出缓冲区的前同步信号(全速发送)开始;

3.低速集线器端口输出缓冲区在接受到EOP时被关上,并且直到前同步信号PID被检测到,才再一次被打开;

4.上行连接不受集线器端口是全速还是低速的影响。

  低速信号是以主机用低速发送SYNC开始的,后面跟着包的剩余部分。包的结束是通过End-of-Packet(EOP)而被识别的,此时所有的集线器都断开并禁止任何连接有低速设备端口。集线器不对上行信号切换端口;低速端口对低速和全速信号在上行方向一直是允许的。

  低速和全速事务维持高度的协议通用性(Commonality)。不过,低速信号确有某些限制,这包括:

  • 数据有效负载(Payload)被限制在最多8个字节的范围内
  • 只中断和控制类型的传送被支持
  • 低速设备不接受SOF包

8.7错误检测和恢复

  USB允许可靠的端到端(End-to-end)的通信,这种通信容许产生物理信号层上的错误。这包括可靠地检测到大量可能的错误的能力和基于事务类型的从错误中恢复的能力。例如,控制事务需要高度数据可靠性;它通过使用错误检测和重试的方法支持端到端的数据完整性。出于同步事务的带宽(Bandwidth)和等待时间(Latency)的要求的原因,它不允许进行重试,且必须对未纠正的错误有较高的容忍程度。

8.7.1包错误种类

  USB使用3种错误检测机制:位填充违反,PID检验位和CRC。位填充违反在节7.1.9中定义。PID错误在节8.3.1中定义。CRC错误在节8.3.5中定义。

  除SOF标记之外,任何被收到的损坏的包都使得接收器忽略它并丢弃随包而来的数据或其他的字段信息。表8-6列出了错误检测机制,它们适用的包的种类和包接收器相应的反应。

表8-6 包错误类型

字段

错误

动作

包标识符

PID校验,位填充

忽略包

地址

位填充,地址CRC

忽略标记

帧号

位填充, 帧号CRC

忽略帧号字段

数据

位填充, 数据CRC

丢弃数据

8.7.2总线周转(Turn-around)时间

  设备和主机都不会发出指示以指出其收到的包有错误的。不作肯定答复则被认为是有错误的。作为这种错误汇报的方法的结果,主机和USB功能部件需要知道从发送器发完包的时候算起直到它开始收到应答为止过了多少时间。这一段时间被称为总线周转时间。当EOP的SE0-to-‘J’转换出现时,计时器开始计数,而当SOP的Idle-to-‘K’转换被检测到的时候停止计数。设备和主机都需要周转计时器(Timer)。设备总线周期时间定义为最坏情况下的往返延迟(Round trip delay)加上最大设备应答延迟(Maximum device response)(见节7.1.18)。如果发送器在最坏情况下的超时范围内没有收到应答,则认为包传输失败。USB设备超时(Timeout)(从先前的EOP的结束算起)应不少于16位的时间且不超过18位的时间。如果主机想通过超时表示一个错误条件,它必须在发出确保所有下行设备都超时的下一个标记之前最少要等待18个位的时间。

  图8-20所示,设备在标记和数据时相之间或数据和握手时相之间使用其总线周转计时器。主机在标记和数据时相之间或数据和握手时相之间使用其计时器。

  如果主机收到不可靠的数据包,它必须在发出下一个标记之前等待。这一等待的间隔能确保主机不试图在错误的EOP之后立即发出标记。

总线周转计时器用法

图8-20 总线周转计时器用法

 

8.7.3错误的EOP

  错误的EOP必须被处理,以确保当前事务的包在主机或其它设备试图传输新包之前完成。如果发生这样的事件,它将构成总线冲突,并有能力损坏2个连续的事务的。错误的EOP的检查依赖于这样的事实:被插入错误EOP的包将呈现为被截短的带有CRC失效的包。(包的最后的16位是正确的CRC概率将非常低。)

  主机和设备以不同的方式处理错误EOP。当设备发现一个损坏的数据包时,它不发出应答而是等待主机发送下一个标记。这保证了当主机还在传输数据包的时候,设备不试图返回握手。

  如果发生错误的EOP,主机数据包将最终结束,而设备将能检测下一个标记。如果设备发出带有错误的EOP的被损坏的数据包,主机将忽略此包,并且不发出握手。期待从主机传来握手信号的设备将超时。

  如果主机收到损坏的数据包,它假定可能发生了错误的EOP并等待16位的时间来看是否有任何后继的上行(Upstream)通信量。如果主机在16位间隔的范围内没有检测到总线转换,并且总线处于空闲状态,则主机可以发出下一个标记。否则主机将等待设备结束发送其包的剩余部分。等待16个位的时间保证了2个条件:

  • 第一个条件是确定了设备已结束发送它的包。这是由比最坏情况下6位时间的位填充间隔更长的超时间隔(没有总线转换)保证的;
  • 第二的条件是保证发送器的总线周转计时器终止。

  注意超时间隔是对事务速度敏感的。对于全速事务,主机必须等待16个全速位的时间;对于低速事务,它必须等待16个低速位的时间。

  如果主机收到带有合法CRC的数据包,则它假定包是完整并且没有必要在发出下一个标记的过程中延迟。

8.7.4超时干扰(Babble)和活动性丧失(Loss of Activity)的恢复

  USB必须能检测使其无限期地等待一个EOP或使总线在帧的结尾时不处于空闲状态的条件,并从中恢复。

  • 活动性丧失(LOA)描述为SOP发出之后总线缺乏活动性(Lack of bus activity)(总线一直处于‘J’或‘K’)并且每帧结束时没有发出EOP;
  • 超时干扰描述为SOP之后总线一直保持其活动性甚至超过了帧的结束。

  LOA和Babble会使总线陷入僵局或者破坏下一个帧开头。无论哪一个条件都是不可接受,并且必须防止其发生。作为有责任控制连接的USB部件,集线器有责任检查和恢复Babble/LOA。通过使最近的集线器禁止与USB设备相连的端口的方法,防止所有不能在帧结束完成传输的USB设备传输超过一帧结束的数据。集线器Babble/LOA恢复机制的细节在节11.8.1中涉及到。

------分隔线----------------------------
USB开源项目
联系我们
  • Q Q: 1148374829 点击这里给我发消息
  • 旺旺:jhoneqhsieh 点击这里给我发消息
  • 电话:(0)15923141204
  • 淘宝网店