8 USB协议层
这章从字段(Field)和包(Packet)的定义开始,从底向上地展示USB(Univeral Serial Bus)协议。接着是对不同事务(Transaction)类型的包事务格式的描述。然后是链路层(Link layer)流程控制(Flow Control)和事务级别的故障恢复(Fault recovery)。本章的最后将讨论复执同步化(Retry synchronization),超时干扰(Babble)和总线活动丧失(Loss of bus activity)的恢复。
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.3.3帧号字段
帧号字段是一个11位的字段,主机每过一帧就将其内容加一。帧号字段达到其最大值7FFH时归零,且它仅每个帧最初时刻在SOF标记中被发送。
8.3.4数据字段
数据字段可以在0到1,023字节之间变动,但必须是整数个字节。图8-4为多字节显示格式。每个字节的范围内的数据位移出时都是最低位(LSb)在前。
8.4包格式
这节展示标记,数据和握手包的包格式。这些图将以位被挪动到总线上的顺序显示包内的字段。
8.4.1标记包
图8-5显示了标记包的字段格式。标记由PID,ADDR和ENDP构成,其中PID指定了包是输入,输出还是建立类型。对于输出和建立事务,地址和端口字段唯一地确定了接下来将收到数据包的端口。对于输入事务的,这些字段唯一地确定了哪个端口应该传送数据包。只有主机能发出标记包。输入PID定义了从功能部件到主机的数据事务。输出和建立PID定义了从主机到功能部件的数据事务。
8.4.2 帧开始(SOF,Start-of-Frame)包
主机以每1.00 ms ±0.0005 ms一次的额定速率发出帧开始(SOF)包。如图8-6中所示,SOF包是由指示包类型的PID和其后的11位的帧号字段构成。
图8-7 数据包格式
数据必须以整数的字节数发出。数据CRC仅通过对包中的数据字段计算而得到,而不包括PID,它有自己的校验字段。
8.4.4握手包
如图8-8所示,握手包仅由PID构成。握手包用来报告数据事务的状态,能还在表示数据成功接收,命令的接收或拒绝,流控制(Flow Control)和停止(Halt)条件。只有支持流控制的事务类型才能返回握手信号。握手总是在事务的握手时相(Phase)中被返回,也可在数据时相代替数据被返回。握手包由1个字节的包字段后的EOP确定界限。如果包被解读为合法的的握手信号,但没有以1个字节后面的EOP终止,则它被认为是无效的,且被接收机忽略。
有3种类型的握手包:
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所示,批处理事务是由标记,数据和握手包构成的三时相的事务。
在某些流控制和挂起条件下,数据时相被握手信号替换,从而产生了没有数据传输的两时相的事务。
当主机准备好了接收批处理数据的时候,它发出输入标记。功能部件端口通过返回数据包,或者如果不能返回数据,则返回NAK或STALL握手作为应答。NAK表示功能部件暂时不能返回数据,而STALL表示端口永久地被停止,需要USB系统软件干涉。如果主机收到合法的的数据包,则它用ACK握手来应答。如果收到数据时主机检测到错误,它不返回握手包给功能部件。
当主机准备好了传送成批数据的时候,它首先发出一个后跟数据包的输出标记包。如果数据由功能部件无错地接收到,那么它将返回三个握手中的一个 :
如果接收到的数据有CRC或者位填充错,那么不返回任何握手。
图8-10说明了时序位和数据PID在成批读和写中的用法。数据包同步经数据时序切换位(Sequence Toggle Bit)和DATA0/DATA1 PID的使用而达到。当端口经历配置事件(Configuration event)(配置事件在节9.1.1.5和9.4.5中有解释)的时候,批处理端口的切换时序被初始化为DATA0。端口上的数据切换不是作为短包传送或IRP撤消的直接结果而被初始化的。
控制传送的状态阶段是序列中的最后一个操作。状态阶段是以相对前面的阶段的数据流方向的变化来刻划的,并且总是使用DATA1 PID。例如,如果数据阶段由输出事务构成的,状态是单一的输入事务。如果控制传送序列没有数据阶段,那么它由建立阶段和其后的由输入事务构成的状态阶段构成。图8-12说明了事务顺序,数据时序位的值和控制读写序列的数据PID类型。时序位显示在括号中。
当控制端口在控制传送的数据和状态阶段中发送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系统软件清除中断条件之前,每次数据功能部件被选中时就必须要发送中断数据。
用于切换模式时,中断端口被端口上的任何配置事件初始化为DATA0 PID,其行为和图8-10所示的批处理一样。
另外, 中断端口可被用来为某些同步功能部件传达速率反馈信息。用于这种模式时,在每个数据包被送到主机之后,都不管握手包是否存在或类型如何,数据切换位都应该改变。只有中断输入端口支持这种能力。
8.5.4同步事务
如图8-14所示,同步(ISO)事务有标记和数据时相,而没有握手时相。主机发出输入或输出标记,后跟着端口(输入)或主机(输出)传送数据的数据时相。ISO事务不支持握手时相或重试能力。
注解:设备或主机控制器都应该能接受DATA0和DATA1。设备或主机控制器应该只发送DATA0。
ISO事务不支持切换时序。
8.6数据切换同步和重试
USB提供一种机制以保证多事务中数据发送器和接收器之间的数据序列同步。这种机制提供一种保证发送器和接收器正确地解释事务的握手时相的方法。同步通过DATA0和DATA1 PID,以及分别从属于数据发送器和接收器的切换时序位的使用而完成。
仅在接收器能接受数据并且收到带有正确的数据PID的无错数据包的时候,接收器时序位才切换。而仅在数据发送器收到合法的ACK握手的时候,发送器时序位才切换。数据发送器和接收器必须在事务开始的时候同步它们的时序位。使用的同步机制随着事务类型而变化。
ISO传送不支持数据切换同步。
8.6.1 通过建立标记初始化
控制传送使用建立标记初始化主机和功能部件的时序位。如图8-15所示,主机向功能部件发送建立包,其后跟着输出事务。圆圈里的数代表发送器和接收器的时序位。功能部件必须接受数据并返回ACK。当功能部件接受事务的时候,它必须设置其时序位,以便主机和功能部件的时序位在建立事务的最后都等于1。
8.6.2成功的数据事务
图8-16说明了有两个成功的事务的情况。对于数据发送器,这表示它根据ACK的接收情况来切换其时序位。仅当接收器收到合法的的数据包,并且包的数据PID和其时序位的当前值相匹配的时候,才切换其时序位。发送器在它收到数据包的ACK时才切换其时序位。
在每个事务中,接收器比较发送器的时序位(在数据包PID中编码为DATA0和DATA1)接收器的时序位。如果数据不能被接受,接收器必须发出NAK,并且,发送器和接收器的时序位保持不变。如果数据能被接受,并且接收器的时序位和PID相匹配,则数据被接受,并且时序位被切换。没有数据包的两时相的事务不使得发送器和接收器改变其时序位。
8.6.3损坏,或者不被接受数据
如果数据不能被接受,或者得到的数据包被损坏,接收器将根据情况发出NAK或STALL握手,或者超时(Timeout),并且,接收器将不切换其时序位。图8-17说明了事务被返回NAK,然后被重试的情况。任何非ACK握手或是超时都将产生类似的重试动作。没有收到ACK握手的发送器,将不切换其时序位。其结果是失败的数据包事务使得发送器和接收器的时序位同步并不切换。然后事务将被重试,如果成功,将引发发送器和接收器时序位的切换。
8.6.4损坏的ACK握手
发送器是根据其收到ACK握手确切地知道事务是否成功的最后并且唯一代理。如图8-18所示,丢失或者损坏的ACK握手使得发送器和接收器之间的暂时失去同步。这里发送器在发出合法的数据包,且接收机成功地收到;但是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说明了一个主机发出标记和握手并收到数据包的低速输入事务。
所有传送到低速设备的下行包都需要前同步信号(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)。不过,低速信号确有某些限制,这包括:
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个条件:
注意超时间隔是对事务速度敏感的。对于全速事务,主机必须等待16个全速位的时间;对于低速事务,它必须等待16个低速位的时间。
如果主机收到带有合法CRC的数据包,则它假定包是完整并且没有必要在发出下一个标记的过程中延迟。
8.7.4超时干扰(Babble)和活动性丧失(Loss of Activity)的恢复
USB必须能检测使其无限期地等待一个EOP或使总线在帧的结尾时不处于空闲状态的条件,并从中恢复。
LOA和Babble会使总线陷入僵局或者破坏下一个帧开头。无论哪一个条件都是不可接受,并且必须防止其发生。作为有责任控制连接的USB部件,集线器有责任检查和恢复Babble/LOA。通过使最近的集线器禁止与USB设备相连的端口的方法,防止所有不能在帧结束完成传输的USB设备传输超过一帧结束的数据。集线器Babble/LOA恢复机制的细节在节11.8.1中涉及到。
USB开源项目
百合电子工作室曾在2009年推出了一个USB开源项目:Easy USB 51 Programer,此项目以开源的形式展示了USB通信的基础性内容、USB HID设备类固件程序开发及PC端应用程序开发、自定义USB设备类固件程序开发及PC端驱动程...
|
USB产品
EASY USB D12 是原EASY USB 51 PROGRAMER的升级版,是百合电子工作室历时一年精心设计的一款USB学习板/开发板,与老款相比,其实例更丰富,技术文档更详尽,更重要的是此款USB学习板还提供技术支持。......
|