USB 3.0规范中译本 第8章 协议层
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com。
协议层管理设备及其主机之间端到端的数据流。这一层建立在链路层提供对某些类型的包的保证传输(guarantees delivery of certain types of packets)的假设基础上;本层基于传输类型,增加了对其余类型的数据包的端到端传输的可靠性(end to end reliability for the rest of the packets)。
本章详细描述了以下内容:
- 数据包类型(Types of packets)
- 数据包格式(Format of the packets)
- 对由主机和设备发送的数据包的预期反应(Expected responses)
- 4个超高速事务类型(SuperSpeed transaction types)
- 支持对流批量传输类型(Streams for the bulk transfer type)
- 主机或设备可能会收到或发送的各种响应和包的时序参数(Timing parameters)
8.1超高速事务【SuperSpeed Transactions】
超高速事务(SuperSpeed transactions)由主机对设备端点请求或发送数据开始,并在端点发送数据或确认收到数据时完成。超高速总线上的数据传输(transfer)是主机请求设备应用程序生成的数据,然后该请求被分解成一个或多个突发事务(burst transactions)。当等待完成当前的总线事务时,超高速主机可以启动一个或多个OUT总线事务到一个或多个端点。
然而,在满足如下条件之一前,超高速主机不可以发起另一个IN总线事务到任何端点:
• 接收到所有DPs,或者一个NRDY,或者一个STALL TP,或者发送给非等时(non-isochronous)端点的当前ACK TP事务超时;或者
• 接收到所有的已经请求过的DPs,或者接收到一个短包(short packet),或者接收到一个last packet flag被设置的DP,或者发送给等时(isochronous)端点的当前ACK TP事务超时。
对于非等时传输(non-isochronous transfers),端点可能通过如下方式对有效的事务(valid transactions)做出响应:
• 返回一个NRDY事务包(Transaction Packet)
• 返回ACK事务包(Transaction Packet)来接受OUT事务
• 返回一个或多个数据包来响应IN事务
• 如果遇到端点内部错误,返回一个STALL事务包(Transaction Packet)
NRDY 事务包(TP)响应表示端点没有准备好接受或者发送数据。结果,在该端点通知主机它已经准备好之前,主机和该端点之间不应该有进一步的活动。这就允许主机和设备之间的链路被设置到低功耗状态(reduced power state),直到端点准备好接受或者发送数据。一旦准备好,端点异步发送一个通知(ERDY TP)给主机,告诉主机它现在已经准备好搬移数据,而主机也通过重新调度先前的请求来做出对该通知的响应。注意等时传输不使用ERDY 或者 NRDY TPs,因为它们是由主机周期性地服务的。此外,在等时端点上发送或者接收的数据包不需要确认,也就是说,没有ACK TPs被发送来确认数据包的接收。
端点只响应由主机作出的请求。主机负责调度总线上的事务,并维护总线上数据搬移的优先级和公平性(priority and fairness);这是通过对IN和OUT请求进行计时和排序(timing and ordering)达到的。事务不是广播;包通过一条直接的路径在主机和设备间穿越(traverse a direct path)。任何没有被使用的链路都可以被设置到低功耗状态(reduced power states),使得总线可以满足严苛的电源管理要求(amenable to aggressive power management)。
8.2 数据包类型【Packet Types】
超高速USB使用4种基本数据包类型,每个类型又有一个或者多个子类型。这4种类型如下:
• 链路管理包【Link Management Packets (LMP)】 只在一对链路(一对直接连接的端口)之间传送,主要用于管理这条链路。
• 事务包【Transaction Packets (TP)】在所有的直接连接主机和设备的链路上传送。它们被用于数据包流程控制制,配置设备及集线器等等。事务包没有数据负载。
• 数据包【Data Packets (DP)】 在所有的直接连接主机和设备的链路上传送。数据包有两部分:数据包头【Data Packet Header (DPH)】以及数据包负载【Data Packet Payload (DPP)】。
• 等时时戳包【Isochronous Timestamp Packets (ITP)】是在主机到一个或多个设备间的所有活动链路(active links)上的多播(multicast)。
所有的包都包含一个14字节的头部,紧接包尾的2字节链路控制字(Link Control Word)(总共16字节)。所有的头都有一个Type字段【已勘误】,被接收实体(receiving entity)(例如主机,集线器,或者设备)用来判断如何处理这个包。所有的头部都包含2字节CRC (CRC-16)。包头具有在1020个比特中少于1个不可校正或不可检验(uncorrectable or undetectable)的错误率。
所有的设备(包括集线器)以及主机都消耗掉它们接收到的链路管理包(LMPs)。集线器有附加的责任来转发DPs, ITPs, 以及TPs到接近设备的下行端口(downstream port nearer a device),或者到接近主机的上行端口(upstream port nearer the host)。注意等时时戳包(ITPs)只由主机发送,而由设备接收。所有除链路管理包(LMPs)之外的包都会被集线器转发,除非这个包是路由给该集线器自己的。对路由等时时戳包(ITPs)的附加规则在第8.7节中描述。注意,在TP, ITP, 或者DPH中的链路控制字(Link Control Word)可能会被集线器在转发之前改变。链路控制字(Link Control Word)的字段在8.3.1.2节描述。
如果Type字段的值是Transaction Packet 或者Data Packet Header,那么Route String和Device Address字段将依照Type字段而定。Route String字段被集线器用于路由在其上行端口出现的数据包到适当的下行端口。从设备来的数据包总是从集线器的下行端口路由到其上行端口。Device Address字段用来供主机识别一个数据包的源。所有其它的字段将在本章后面得以详述。
数据包在包头中包含附加的信息用来描述数据块(Data Block)。数据块(Data Block)总是紧跟4字节的CRC-32字段,用以判定数据的正确性。数据块和CRC-32一起被称作数据包负载(Data Packet Payload)。
8.3 数据包格式
这一节定义超高速数据包。定义组成包类型和子类型(packet type and subtypes)的各个字段。
在本节中,数据包字节和bit位定义使用未编码的数据格式来定义。添加到串行数据流中的符号的效果(例如,数据包分帧(frame packets),控制或者修改链路(control or modify the link)等),bit编码,bit加扰, 以及链路层分帧(link level framing)等已经被删除掉,以便更清楚明了。请参阅第6和第7章以获得更详细的信息。在讨论总线性能(bus performance),有效性(efficiency)以及时序(timing)的时候,前述的底层操作的效果会被讨论到,以提供更多的上下文。
8.3.1 所有头包都有的字段【Fields Common to all Headers】
所有的超高速头包都是以Type字段开始的,用以判定如何解释该包。在高层次上这告诉包的接收者如何处理它:要么使用它来管理链路,要么用来控制设备和主机之间的数据流。
8.3.1.1 保留值和保留字段的处理【Reserved Values and Reserved Field Handling】
保留字段和保留值不允许以Vendor特定的方式使用。
发送方应该将所有的保留字段都设置为零值,接收方应该忽略所有的保留字段。
发送方不允许将已定义的字段设置成保留值,接收方应该忽略所有的将已定义字段的值设成了保留值的数据包。注意,接收方仍然需要确认这些数据包的接收,按第7.2.4.1节所述返回相关的值。
8.3.1.2 Type字段
Type字段是一个5-bit的字段,用于指定数据包的具体格式。类型是被中间的链路用于判定数据包如何被使用或者被转发。
8.3.1.3 CRC-16
所有的包头都有16-bit CRC字段。这个字段是对前面的12字节进行CRC计算而得到的。参见第7.2.1.1.2节用于计算这个值的多项式(polynomial)。
8.3.1.4 链路控制字(Link Control Word)
对链路控制字的使用如7.2.1.1.3节所定义。
Table 8-2. Link Control Word Format
宽度 (bits) |
偏移 (DW:bit) |
描述 |
3 |
3:16 |
Header Sequence Number. 有效值在 0 到 7之间。 |
3 |
3:19 |
Reserved (R). |
3 |
3:22 |
Hub Depth. 本字段只在Deferred bit被设置时有效,用于在返回给主机的deferred TP或者deferred DPH中向主机指示该集线器在USB总线上的层级(hierarchical)。这就通知了主机,该数据包原本所期望被从之转发的端口(the port on which the packet was supposed to be forwarded on)当前正处于低功耗状态(U1 或者 U2)。该字段唯一有效的值在0到4之间。 |
1 |
3:25 |
Delayed (DL). 这个位应该在Header Packet 被重发(resent)或者Header Packet 的发送被延迟(delayed)的时候被置位。第7章和第10章提供了更多关于何时设置该位的细节。这个位不应该被该包所穿越过的后续集线器(any subsequent hub that this packet traverses)复位。 |
1 |
3:26 |
Deferred (DF). 这个位只可能(may only)被集线器设置。这个位只应该在该数据包需要被从之发送的下行端口(downstream port on which the packet needs to be sent)处于电源管理状态时设置。这个位不应该被该包所穿越过的后续集线器复位。 |
5 |
3:27 |
CRC-5. 这个字段是对该字前面的11比特进行正确性验证的CRC值。参阅7.2.1.1.3节关于计算该值的多项式。 |
8.4 链路管理包【Link Management Packet (LMP)】
Type 字段设置成Link Management Packet 的数据包被称作链路管理包 LMPs。这些数据包被用来管理单个链路。它们不携带地址信息,因此不能被路由。它们可能因执行集线器端口命令而被生成。例如,一个集线器命令可被用来设置U2不活动超时值(U2 inactivity timeout)。此外,他们被用来交换端口能力信息以及完成测试目的。
8.4.1 Subtype字段
LMP Subtype 字段的值进一步标示LMP的内容。
8.4.2 Set Link Function
Set Link Function LMP应该被用来配置可以无须脱离活动状态(U0)就能被改变的功能性(functionality)。
一旦接收到一个Force_LinkPM_Accept bit有效的(asserted)LMP包,端口应该接受所有的LGO_U1 和 LGO_U2链路命令,直到端口接收到Force_LinkPM_Accept无效的(de-asserted)LMP包。
设备必须保持在U1或U2,直到下行端口发起退出到U0。软件在发起导致生成LGO_U1 或者LGO_U2链路命令的SetPortFeature命令之前,需要确保链路层级上没有正在等待的包(no pending packets at the link level)。在常规操作期间,该特性只能在所有将链路状态从U0降低到U1或U2的其他方式都失败的情况下使用。这个LMP是在集线器接收到一个SetPortFeature (FORCE_LINKPM_ACCEPT)命令时,发送给连接给特定端口上的设备。参考第10.4.2.2节和第10.6.2.1节更多细节。
注意,不恰当地使用Force_LinkPM_Accept功能可能极大地影响链路性能,而在某些情况下(仅指在常规操作期间使用时)可能导致设备不能被返回到正常操作。【已勘误,原来说该功能应该只被用来做兼容性和测试(compliance and testing)目的,现在允许该命令也可以在常规情况下使用!】
这个LMP被集线器在接收到SetPortFeature (FORCE_LINKPM_ACCEPT)命令时,发送给连接到特定端口上的设备。参阅第10.14.2.2节和第10.14.2.10节更多细节。
8.4.3 U2不活动超时(Inactivity Timeout)
U2不活动超时LMP应该被用来定义从U1转换到U2的超时值。【已勘误,对于上行端口,没有U1不活动定时器。】参阅第10.4.2.1节关于这个LMP的更多细节。
表8-5. U2不活动超时功能(Inactivity Timer Functionality)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
0:5 |
Subtype. 这个字段应该被设置为0010b 用于 U2 Inactivity Timeout LMP. |
8 |
0:9 |
U2 Inactivity Timeout. 这8比特代表U2 Inactivity Timeout值,该值与被发送给集线器的Set Port Feature (PORT_U2_TIMEOUT)命令中的值相同。参阅第10.14.2.9节更多关于该字段编码的细节。 |
8.4.4 制造商设备测试(Vendor Device Test)
使用这个LMP主要是为了制造商特定的测试目的,不应该用于正常的链路操作。
Table 8-6. 制造商特定的测试功能
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
0:5 |
Subtype. 这个字段应该被设置为0011b用于Vendor Device Test LMP. |
8 |
0:9 |
Vendor-specific device test. 该字段的功能是制造商特定的。 |
64 |
1:0 |
Vendor-defined data. 该字段也是有制造商定义的。 |
8.4.5 端口能力(Port Capabilities)
端口能力LMP(Port Capability LMP)描述每个端口的链路能力,且在成功完成训练和链路初始化之后,链路伙伴双方都要发送。在端口从Polling进入U0之后,端口应该发送在链路初始化(参见第7.2.4.1.1节)完成之后的tPortConfiguration时间内发送Port Capability LMP。注意端口可能不总是从Polling直接转换进入U0,而是在进入U0之前可能通过其他中间状态(例如,Recovery或Hot Reset)转换。不论在Polling和进入U0之间经过了什么状态,设备都应该在进入U0时立即发送一个Port Capability LMP【已勘误】。
如果一个链路伙伴在tPortConfiguration时间内没有接收到这个LMP,那么:
- 如果链路伙伴有下行能力,它应该按照第10.14.2.6节所描述的那样发送一个错误信号。
- 如果链路伙伴只支持上行能力,那么上行端口应该转换到SS.Disabled状态,并且应该尝试以这个设备支持的其它速度进行连接。
表8-7. 端口能力LMP 格式
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
0:5 |
Subtype. 这个字段应该被设置为0100b用于Port Capability LMP |
7 |
0:9 |
Link speed. 这个字段是个掩码,用于描述这个设备支持的速度。 比特位 0 这个位应该被设为1来指示该设备支持5Gbps信号 6:1 Reserved. |
16 |
0:16 |
Reserved |
8 |
1:0 |
Num HP Buffers. 这个字段指定该设备支持的header packet buffers的个数。所有兼容本规范版本的设备都应该返回值4。所有其它值都是保留的。 |
8 |
1:8 |
Reserved |
2 |
1:16 |
Direction (D). 该字段用于标示该端口的上行或者下行能力(upstream or downstream capabilities)。所有的端口都至少要设置这些位中的1位。 比特位 0 如果这位被设为1,那么该端口可以被配置为下行端口 1 如果这位被设为1,那么该端口可以被配置为上行游端口 |
2 |
1:18 |
Reserved |
4 |
1:20 |
Tiebreaker. 这个字段只在 Direction |
40 |
1:24 |
Reserved. |
在交换端口能力LMPs之后,链路伙伴应该根据表8-8所指定的那样来判定由哪一方被配置为下行端口。
表8-8. 端口类型选择矩阵
端口及其原有属性 |
端口2 |
|||
只上行 |
只下行 |
上下行 |
||
端口 1 |
只上行 |
未定义 |
端口2为下行 |
端口2为下行 |
只下行 |
端口1为下行 |
未定义 |
端口1为下行 |
|
上下行 |
端口1为下行 |
端口2为下行 |
Tiebreaker值更高的端口成为下行端口(注1) |
注意1: 如果TieBreaker字段相等,那么链路伙伴双方应该用新的不同TieBreaker值来重新交换端口能力LMPs。端口生成TieBreaker字段值的顺序应该足够随机。【译注:TieBreaker本身就含有决胜局之意。】
8.4.6 端口配置(Port Configuration)
这一节只描述与端口能力LMP有区别的字段。所有的支持下行端口能力的超高速端口都应该能够发送这个LMP。如果即将被配置成上行模式的端口没有在链路被初始化之后的tPortConfiguration时间内接收到这个LMP,那么这个上行端口应该切换到SS.Disabled状态,并且应该尝试以这个设备支持的其它速度进行连接。
表 8-9. 端口配置LMP格式 (与端口能力LMP有区别之处)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
0:5 |
Subtype. 这个字段应该被设置为0101b用于Port Configuration LMP. |
7 |
0:9 |
Link speed. 该字段描述上行端口应该工作的链路速度。链路伙伴所发送的端口配置LMP中的这个字段只应该有其中1位能够被设置。 比特位 0 如果这个比特被设置,那么这个设备应该工作在5Gbps。 6:1 Reserved. |
80 |
0:16 |
Reserved. |
被配置为下行模式的端口应该发送这个端口配置LMP给上行端口。发送该LMP的端口应该只选择Link Speed字段的其中1个比特。如果有能力充当下行端口的端口不能与其链路伙伴协同工作,那么该有能力充当下行端口的端口应该按照第10.14.2.6节所描述的那样发送一个错误信号。
8.4.7 端口配置响应(Port Configuration Response)
这个LMP是由上行端口作为对端口配置LMP的响应而发出的。他被用作对端口配置LMP的接受或者拒绝的指示。这一节也只描述与端口能力LMP有区别的字段。
所有支持上行端口能力的超高速端口都应该能够发送这个LMP。
如果下行端口在tPortConfiguration之内没有收到这个LMP,则它应该该按照第10.14.2.6节所描述的那样发送一个错误信号。
表 8-10. 端口配置响应LMP格式 (与端口能力LMP有区别之处)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
0:5 |
Subtype. 这个字段应该被设置为0110b用于Port Configuration Response LMP. |
7 |
0:9 |
Response Code. 该字段指示被接受的在发送给一个设备的Port Configuration LMP的设置信息。 比特位 0 如果这个比特被设置,那么这个设备接受Link Speed的设置。. 6:1 Reserved. |
80 |
0:16 |
Reserved. |
如果Response Code 指示Link Speed 被上行端口拒绝, 下行端口应该按照10.14.2.6所描述的那样发送一个错误信号。
8.5 事务包【Transaction Packet (TP)】
事务包 (TPs) 穿越主机和设备之间的直接路径。事务包被用来控制数据流和管理端到端的连接。 Type字段的值应该设置为Transaction Packet (即00100b)。 Route String字段是被集线器用来路由出现在其上行端口上的包到正确的下行端口。从设备发出的事务包的路由字串被设置为零。当主机发送一个事务包时,Device Address字段包含预定的接收者的地址。当设备发送一个事务包给主机时,它将Device Address字段设置为它自己的设备地址。该字段被主机用来识别事务包的来源。事务包中SubType字段被接收者用来判定事务包的格式和使用方式。
8.5.1 确认事务包【(ACK)Transaction Packet】
这个事务包用于两个目的:
- 对于IN端点,由主机发送该事务包,用来从设备请求数据,以及对主机之前接收到的数据包进行确认。
- 对于OUT端点,由设备发送该事务包,用来对主机之前发送的数据包进行接收确认,以及通知主机在接收到这个包后设备还有多少个数据包缓冲区可用。
表 8-12. 确认事务包 ACK TP 格式
宽度 (bits) |
偏移 (DW:bit) |
描述 |
20 |
0:5 |
Route String/Reserved. 该字段只被集线器使用。与集线器深度联合,用来路由包到正确的下行端口。参考第8.9节中的详情。当被设备端发送时,该字段是被保留的。 |
7 |
0:25 |
Device Address. 该字段指定设备,通过地址,该设备是包的接收者还是源。参考第8.8节。 |
4 |
1:0 |
SubType. 该字段应该被设置为0001b (ACK)用于ACK TP。 |
2 |
1:4 |
Reserved (Rsvd). |
1 |
1:6 |
Retry Data Packet (rty). 该字段用于告知主机或者设备没有接收到数据包或者接收到的数据包被损坏,并且请求数据发送方重新发送由指定的序列号开始的一个或者多个数据包。 |
1 |
1:7 |
Direction (D). 该字段定义发送或者接收这个事务包的设备端点的方向。参见第8.8节。 值 0b 主机到设备 1b 设备到主机 |
4 |
1:8 |
Endpoint Number (Ept Num). 该字段判定发送或者接收这个事务包的设备端点。参考第8.8节。 |
3 |
1:12 |
Reserved (Rsvd). |
1 |
1:15 |
Host Error (HE). 该字段只在这个ACK TP是被主机发送给设备的情况下才有效。该比特应该被主机在由于主机端的内部问题而无法接收有效数据包的情况下设置。对于非等时传输,如果主机设置了这个字段,还必须同时设置 |
5 |
1:16 |
Number of Packets (NumP). 该字段用于指示接收方可以接受多少个数据包缓冲区。这个值应该小于或等于端点伴侣描述符(Endpoint Companion Descriptor,参考9.6.7节)的Burst Size 字段所指定的端点所能支持的最大突发大小(maximum burst size)。 |
5 |
1:21 |
Sequence Number (Seq Num). 该字段用于识别预期的下一个数据包(next expected data packet)的序列号。 |
6 |
1:26 |
Reserved. |
16 |
2:0 |
Stream ID/Reserved. 如果这个ACK TP的目标是一个支持流(Streams)的 Bulk端点(即流管道),那么这个字段包含一个在1到65535之间的Stream ID。Stream ID 值0对流管道是保留的,如果接收到该字段为0值则该TP应该被认为是无效的。所有其他管道都应该将该字段作为保留字段对待。 |
11 |
2:16 |
Reserved. |
1 |
2:27 |
Packets Pending (PP). 该字段只能由主机设置。如果该字段被设置,则主机已经准备好从该端点/流(endpoint/Stream)接收另一个DP,其中端点由Endpoint Number 和 Direction |
4 |
2:28 |
Reserved. |
8.5.2 未就绪事务包【 (NRDY) Transaction Packet】
只能由设备的非等时端点发送这个事务包。OUT端点在设备没有包缓冲区来接收主机已经发送来的数据包DP的情况下,发送这个TP给主机。IN端点在不能发送数据包DP给主机的情况下,发送这个TP给主机,作为对主机已经发送来的ACK TP的响应。
本节只描述与ACK TP有区别的字段。
表 8-13. NRDY TP 格式(与 ACK TP 有区别部分)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0010b用于NRDY。 |
3 |
1:4 |
Reserved |
20 |
1:12 |
Reserved. |
5 |
2:27 |
Reserved. |
8.5.3 端点就绪事务包【 (ERDY) Transaction Packet】
只能由设备的非等时端点发送这个事务包。它被用来通知主机,端点已经准备好发送或者接收数据包。
本节只描述与ACK TP有区别的字段。
表 8-14. ERDY TP 格式 (与 ACK TP 有区别部分)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0011b用于ERDY。 |
3 |
1:4 |
Reserved |
4 |
1:12 |
Reserved. |
5 |
1:16 |
Number of Packets (NumP). 对于OUT 端点, 参考表 8-12 对这个字段的描述. 对于IN 端点,这个字段被端点设置为在主机恢复与该端点之间的事务之后,其能够发送的包的个数。这个值不应该超过端点伴侣描述符(Endpoint Companion Descriptor,参考9.6.7节)的Burst Size 字段所指定的端点所能支持的最大突发大小(maximum burst size)。注意这个字段报告的值可能只被主机当作参考信息。 |
11 |
1:21 |
Reserved. |
5 |
2:27 |
Reserved. |
8.5.4 状态事务包【STATUS Transaction Packet】
只能由主机发送这个事务包。它被用来通知设备的控制端点,主机已经发起控制传输的状态阶段。这个TP应该只被发送给控制端点。
本节只描述与ACK TP有区别的字段。
表 8-15. STATUS TP 格式(与 ACK TP 有区别部分)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0100b用于STATUS。 |
3 |
0:4 |
Reserved |
52 |
1:12 |
Reserved. |
8.5.5 STALL Transaction Packet
只能由设备的端点发送这个事务包。它被用来通知主机,端点已经被暂停(halted)或者控制传输无效。
本节只描述与ACK TP有区别的字段。
表 8-16. STALL TP 格式 (与 ACK TP 有区别部分)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0101b用于STALL。 |
3 |
0:4 |
Reserved |
52 |
1:12 |
Reserved. |
8.5.6 设备通知事务包【(DEV_NOTIFICATION) Transaction Packet】
只能由设备发送这个事务包。它被设备用来通知主机,设备或者接口状态有异步改变,例如,用来识别设备中引起设备执行一次远程唤醒操作的功能(function)。这个事务包不是从一个特别的端点发送的,在总体上是由设备发送的。
本节只描述与ACK TP有区别的字段。
表 8-17. 设备通知 TP 格式 (与 ACK TP 有区别部分)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0110b用于DEV_NOTIFICATION。 |
4 |
1:4 |
Notification Type. 这个字段标示设备通知的类型。 值 0000b Reserved 0001b FUNCTION_WAKE 0010b LATENCY_TOLERANCE_MESSAGE 0011b BUS_INTERVAL_ADJUSTMENT_MESSAGE 0100b – 1111b Reserved |
8.5.6.1 功能唤醒设备通知【Function Wake Device Notification】
表 8-18. 功能唤醒设备通知【Function Wake Device Notification】
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0110b用于DEV_NOTIFICATION。 |
4 |
1:4 |
Notification Type. FUNCTION_WAKE - 0001b |
8 |
1:8 |
Interface. 该字段标示引起设备执行远程唤醒操作的功能中的第一个接口 |
48 |
1:16 |
Reserved. |
8.5.6.2 延迟忍耐消息设备通知【Latency Tolerance Message (LTM) 】
延迟忍耐消息设备通知(Latency Tolerance Message Device Notification)是可选的标准特性(optional normative feature),可以使得平台操作更具功耗有效性(power efficient)。
表 8-19. 延迟忍耐消息设备通知
宽度 (bits) |
偏移 (DW:bit) |
描述 |
||||||||||
4 |
1:0 |
Subtype. 这个字段应该被设置为0110b用于DEV_NOTIFICATION。 |
||||||||||
4 |
1:4 |
Notification Type. LATENCY_TOLERANCE_MESSAGE - 0010b |
||||||||||
12 |
1:8 |
BELT. 本字段描述最大努力延迟忍耐(Best Effort Latency Tolerance) 值,代表设备能够等待服务的以钠秒计的时间(time in nanoseconds that a device can wait for service),超过该时间则设备将遭遇非预期的操作性副作用(experiencing unintended operational side effects)。 比特位 9:0 延迟值(以钠秒为单位)【LatencyValue (ns)】
|
||||||||||
44 |
1:20 |
Reserved. |
8.5.6.3 总线间隔调整消息设备通知【Bus Interval Adjustment Message Device Notification】
表 8-20. 总线间隔调整消息设备通知
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0110b用于DEV_NOTIFICATION。 |
4 |
1:4 |
Notification Type. BUS_INTERVAL_ADJUSTMENT_MESSAGE - 0011b |
8 |
1:8 |
Reserved. |
16 |
1:16 |
Bus Interval Adjustment. 这个字段是在-32768 到 +32767之间的2的补码(two's complement value),以BusIntervalAdjustmentGranularity为单位表示。 |
8.5.6.4 功能唤醒通知【Function Wake Notification】
如果远程唤醒(remote wakeup)被使能,一个功能(function)可以通过发送Function Wake Device Notification,告知主机它想要从设备挂起(device suspend)(在将链路转换进入U0状态后)或者功能挂起(function suspend)状态退出。参考第9.2.5节更多细节。
8.5.6.5 延迟忍耐消息【Latency Tolerance Messaging】
延迟忍耐消息(Latency Tolerance Messaging)是一个可选的标准USB电源管理特性(optional normative USB power management feature),利用所报告的BELT (Best Effort Latency Tolerance)值来使能更好的平台操作功耗有效性(power efficient)。
BELT值是主机将设备置于无服务状态的最大时间(将所有已配置端点的服务需求都计入在内)。特别地,BELT值是主机从接到设备的ERDY开始,到主机传送对ERDY的响应之间的时间。
设备通过使用BOS描述符中的SUPERSPEED_USB Device Capability描述符中的LTM Capable字段,来指示是否有能力发送LTM事务包(参考9.6.2节)。LTM Enable (参考9.4.10) 特性选择子使能 (或禁用) LTM capable的设备发送LTM事务包。
8.5.6.5.1 可选的标准LTM和BELT要求【Optional Normative LTM and BELT Requirements】
总体设备要求【General Device Requirements】
• LTM TPs应该只能源自于外围设备。
• LTM TPs适用于除等时端点之外的所有端点类型。
• 一旦BELT值被设备发送给了主机,所有的设备端点都可以预期在指定的BELT时间内得到服务。
• 设备应该在tMinLTMStateChange时间之内,发送一个BELT字段值为tBELTdefault的LTM TP,来响应LTM Enable状态的任何改变。
• 设备应该保证足够经常判定(determined frequently enough)其BELT值,从而在需要更改BELT值之前能够提供合理的关于设备服务延迟忍耐性的估计。此外,还需要满足如下条件:
- LTM TPs的最大个数受限于tBeltRepeat。
- 每个LTM TP应该具有不同的BELT值。
• 系统应该对所有设备使用1 ms为默认BELT值 (参见表8-33)。
• BELT的最小值是125 μs (参考表8-33)。
支配BELT值的建立的设备要求【Device Requirements Governing Establishment of BELT Value】
• LTM机制应该使用U1SEL和U2SEL来为设备提供系统延迟(system latency)的信息(见第9.4.12节–Set SEL)。在这个上下文中,系统延迟(system latency)是指,在允许的最深链路状态是U1或U2状态的情况下,从设备发送ERDY到它从主机接收到事务包(类型特定于方向,direction-specific)之间的时间。这些值由设备用来恰当地调整它们的BELT值,将它们在USB链路拓扑中的位置计入在内。
- 允许其链路进入U1,而不允许进入U2的设备,应该将U1系统退出时延【U1 System Exit Latency (U1SEL)】从其总体延迟忍耐时间中减去,并将结果作为LTM TP中的BELT字段值发送。
- 允许其链路进入U1和U2的设备,应该将U2系统退出时延【U2 System Exit Latency (U2SEL)】从其总体延迟忍耐时间中减去,并将结果作为LTM TP中的BELT字段值发送。
8.5.6.6 总线间隔调整消息【Bus Interval Adjustment Message】
【译注:这段话实在是拗口啊,费解啊!劝君还是看原文吧,即使原文也让人晕啊!】
该设备通知可由设备发送用来请求增加或者减小总线间隔(bus interval)的长度。这将典型地由设备用于尝试将主机的总线间隔时钟(host's bus interval clock)与外部时钟(external clock)同步。总线间隔调整请求是相对于当前总线间隔的。例如,如果设备请求增加一个BusIntervalAdjustmentGranularity单元,并且之后再请求增加两个BusIntervalAdjustmentGranularity单元,则主机总共增加三个BusIntervalAdjustmentGranularity单元。
主机应该支持绝对范围在-37268到37267个BusIntervalAdjustmentGranularity单位之间的调整值。设备每八个总线间隔的调整要求不应该超过一次(A device shall not request adjustments more than once every eight bus intervals)。直到设备等待足够长时间而在后续的ITPs的时间戳字段上精确观察到前一次总线间隔调整请求的效果之前,不应该发送另一个总线间隔调整请求。设备的每一次BusIntervalAdjustment请求,不应该超过多于±4096个调整单位。设备可以随着时间的推移发起多次BusIntervalAdjustment请求,来达到总体上多于4096个调整单位。除非设备在过去的125μs内收到过一个ITP,且该ITP包含的Bus Interval Adjustment Control字段的值等于零或该设备的地址,且该设备正处于Address或Configured状态,设备不应该请求总线间隔调整。
一次只有一个设备可以控制总线间隔长度。主机控制器根据本节的描述实现一个先来先服务的策略来处理总线间隔调整请求。在主机控制器开始操作时,它应该发送Bus Interval Adjustment Control字段值为0的ITPs。当主机控制器首次接收到一个总线间隔调整控制请求,它应该将后续ITPs的Bus Interval Adjustment Control字段设置为发送该请求的设备的地址。一旦Bus Interval Adjustment Control字段被设置为非零值,主机应该忽略所有其它设备的总线间隔调整请求。如果起控制作用的设备被断开,主机控制器应该将Bus Interval Adjustment Control字段复位为零。主机控制器可以提供一个方式以供软件重写(override)默认的总线间隔调整控制字段的行为,并选择起控制作用的设备。主机控制器应该在收到总线间隔调整请求之后两个总线间隔内开始应用总线间隔调整。
最小的总线间隔调整值(1个BusIntervalAdjustmentGranularity)要求主机做出平均每4096个总线间隔8个高速比特时间的调整。允许主机在单个总线间隔内做出这个调整,这样,用以生成ITP时序和总线间隔范围的时钟的周期不需要小于8个高速比特时间。主机应该定期做出总线间隔调整。当主机被要求平均每4096个总线间隔做出一个或多个"8个高速比特时间(eight high speed bit time)"的调整时,应该按照如下定义的限制来均匀地分布该调整:
- 包含比其他间隔多一个"8个高速比特时间(eight high speed bit time)"的间隔,被称作"最大调整总线间隔(maximum adjustment bus intervals)"。
- 在任何总线间隔期间完成的"8个高速比特时间(eight high speed bit time)"调整的个数,超过任何其他总线间隔期间完成的"8高速比特时间(eight high speed bit time)"调整的个数不应该多于1。
- 两个连续的"最大调整总线间隔(maximum adjustment bus intervals)"之间的距离(以总线间隔计)不应该多于1个总线间隔。
对于总线间隔调整(bus interval adjustments)的均匀分布和平均调整的要求(even distribution and average adjustment requirements),应该从主机接收到一个总线间隔调整请求的一个总线间隔后(one bus interval after a bus interval adjustment request is received)开始应用,直到主机再次接收到一个后续的有效的总线间隔调整请求(subsequent valid bus interval adjustment request is received)所在的总线间隔。
下面是对一个特定的总线间隔调整请求的有效主机行为的示例。在上电后,主机接收到一个总线间隔调整,要求在总线间隔X-1中减小10个BusIntervalAdjustmentGranularity单位。主机控制器使用一个周期为"8个高速比特时间(eight high speed bit times)"的时钟来驱动一个计数器,来产生时间戳和总线间隔范围(produces timestamps and bus
interval boundaries)。主机在下列总线间隔中,添加一个附加的(extra)"8个高速比特时间(eight high speed bit time)"的时钟tick到其计数器:X+409, X+819, X+1228, X+1638, X+2048,X+2457, X+2867, X+3276, X+3686, X+4096, X+4505,….
8.5.7 PING事务包
这个事务包只能被主机发送。他被主机用来在发起一个等时传输之前,将到一个设备的所有链路转换到U0状态。参考附录C中关于使用这个TP的细节。本节只描述与ACK TP有区别的字段。
设备应该通过在tPingResponse时间(参考表8-33)内,发送PING_RESPONSE TP给主机,来响应PING TP(参考8.5.8节)。注意设备不应该验证EP_NUM和Direction字段,而是简单地将它们拷贝到PING_RESPONSE TP的相关字段中【已勘误】。
设备应该将其链路保持在U0状态,直到它从主机接收到一个后续包,或者直到tPingResponse时间(参考表8-33)超时。
表 8-21. PING TP 格式 (与 ACK TP 有区别的地方)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为0111b用于PING。 |
3 |
1:4 |
Reserved. |
52 |
1:12 |
Reserved. |
8.5.8 PING_RESPONSE 事务包
这个事务包只能由设备发送,来响应主机发送的PING TP。每接收到一个PING TP都应该发送一个PING_RESPONSE TP。参考附录C中关于使用这个TP的细节。本节只描述与ACK TP有区别的字段。
表 8-22. PING_RESPONSE TP 格式 (与 ACK TP 有区别的地方)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
4 |
1:0 |
Subtype. 这个字段应该被设置为1000b用于PING_RESPONSE。 |
3 |
1:4 |
Reserved. |
1 |
1:7 |
Direction (D). 该字段应该被设置为这个PING_RESPONSE TP正为之发送的PING TP的Direction 字段。 |
4 |
1:8 |
Endpoint Number (Ept Num). 该字段应该被设置为这个PING_RESPONSE TP |
52 |
1:12 |
Reserved. |
8.6 数据包
【Data Packet (DP)】
这个包可以被主机或者设备发送。主机用这个包发送数据给设备。设备用这个包返回数据给主机,作为对ACK TP的相应。所有的数据包都由数据包头(Data Packet Header)和数据包负载(Data Packet Payload)组成。本节只描述与ACK TP有区别的字段。
数据包在主机和设备间的直接路径上穿行。注意发送零长数据块的数据包是允许的,但还是需要一个CRC-32。
表 8-23. 数据包格式 (与 ACK TP 有区别的地方)
宽度 (bits) |
偏移 (DW:bit) |
描述 |
5 |
1:0 |
Sequence Number (Seq Num). 该字段用于识别数据包的序列号。注意序列号在31处回绕。 |
1 |
1:5 |
Reserved |
1 |
1:6 |
End Of Burst (EOB)/Last Packet Flag (LPF). 对于非等时端点,该字段被称为EOB;而对于等时端点,该字段被称为LPF 。
对于非等时输入端点,该字段用于标示这是一次突发的最后一个包。当设备准备好继续传输,应该发送一个ERDY TP给主机。注意端点应该重新评估重试的数据包的EOB值。如果设备返回少于上一次接收到的ACK TP中NumP字段指定的包个数,并且最后一个包不是短包,那么突发的最后一个包的EOB字段应该被设置。注意,当设备发送一个短包,尽管它可能会返回比接收到的最后一个ACK TP中的NumP字段要少些的包个数,设备也不必(not required)将这个EOB字段设为1b。只有在设备想要在用这个短包来完成当前传输之后进入流程控制状态时,设备才需要将这个字段设为1b。【已勘误】
对于非等时输出端点和控制端点,该字段应该被设为零。
对于等时端点,该字段用于标示这是当前服务时段(service interval)的最后一个突发的最后一个包。LPF可以由设备和主机设置。当这个数据包的目标和源头是等时端点时,请参考8.12.6节对该字段的用法。 |
4 |
1:8 |
Endpoint Number (Ept Num). 该字段判定设备中是这个数据包的源头(source)或者接收者(recipient)的端点。 |
3 |
1:12 |
Reserved |
1 |
1:15 |
Setup (S). 该字段被主机设置用来标示这个数据包是Setup 数据包。这个字段只能由主机设置。 |
16 |
1:16 |
Data Length. 该字段被用来标示数据包负载中除了数据CRC-32之外的字节数。 |
1 |
2:27 |
Packets Pending (PP). 该字段只能由主机设置。如果该字段被设置,则主机有一个或者多个DPs可用来向该端点/流(endpoint/Stream)传输,其中端点由Endpoint Number 和 Direction |
xx |
4:0 |
Data Block. 这个字段包含数据包负载的数据。这个字段的长度由 |
32 |
4:0 |
CRC-32. 数据CRC是对数据包负载的数据块进行计算得到的。参考7.2.1.2.1的计算这个值的多项式。注意,由于数据块长度可能不是4的整数倍,因此这个字段也不一定在DWORD边界对齐。 |
8.7 等时时戳包【ITP】
ITP的Type字段是01100b (Isochronous Timestamp Packet)。ITPs 被用于从主机传送时间戳信息到所有的活动设备。ITPs不携带寻址或者路由信息,被集线器多播(multicast)到其链路处于U0状态的所有下行端口。设备不应该响应ITP。ITP用来提供主机端的时序信息到设备以达到同步。注意所有的设备或者集线器都可能接收ITP。主机应该当且仅当根端口链路已经在U0状态时在该链路上传送ITP。只有主机应该发起ITP传送。主机不应该为了要传送ITP而将根端口链路带进U0状态。如果根端口链路处于U0状态,主机应该在每个总线间隔的边界的tTimestampWindow内传送一个ITP。主机应该在主机的根端口的链路从轮询状态进入U0状态tIsochronousTimestampStart时间内开始传送ITPs。ITP可以在一个突发的包之间传送。如果一个设备接收到一个链路控制字中的延迟标志(DL)被设置的ITP,其时间戳值可能非常不精确,可以被设备忽略。
表 8-24. 等时时戳包格式
宽度 (bits) |
偏移 (DW:bit) |
描述 |
27 |
0:5 |
Isochronous Timestamp (ITS). 等时时间戳字段被用于标示从传送ITP的主机角度来看的当前时间值。时间戳字段被分成两个子字段: 比特位 13:0 Bus interval counter. 当前1/8毫秒计数器。计数器值当到达0x3FFF时翻转并继续增加。 26:14 Delta. 从当前ITP包的开始到前一个总线间隔边界的时间差值。该值是单位为tIsochTimestampGranularity的数值。使用的值应该指定最接近前一总线间隔边界的时间差值(delta),而不超前该边界(comes closest to the previous bus interval boundary without going before the boundary)。 注意:如果一个包恰好在总线间隔边界开始,则delta 被设置为0。 |
7 |
1:0 |
Bus Interval Adjustment Control. 该字段指定控制总线间隔调整机制的设备的地址。在复位,上电,或者如果设备被断开时,主机应该将该字段设为零。 |
57 |
1:7 |
Reserved. |
在ITP的第一个分帧符号(framing symbol)被传送时测量的ITP的ITS值精确度应该具有主机时钟(用于ITP生成)值的±1个 tIsochTimestampGranularity单位。
8.8 寻址三剑客【Addressing Triple】
数据包和大多数的事务包通过三个字段的复合来提供对特定数据流的访问。它们是Device Address, Endpoint Number和Direction字段。
在复位和上电时,设备的地址默认为0,应该被主机在枚举过程中编程设置为一个在1到127之间的值。设备地址0被保留作为默认地址,不应该被指定为其它用途。
除了必须的端点号设为0的默认控制端点,设备可以支持多达15个IN和15个OUT端点(由Direction字段标示)。
8.9 Route String字段
Route String是下行方向的包中一个20比特的字段,集线器用它来将包路由到指定的下行端口。它由该包将要越过的每一个集线器的下行端口号(每个集线器4比特)拼接而成。集线器用集线器深度(Hub Depth)值乘以4作为偏移量,在 Route String 中定位相应的位来判定下行端口号。集线器深度(Hub Depth)值是在枚举过程中判定,并赋予给每个集线器的。注意这个字段只在主机发出的包中有效,当设备发送时,这个字段被保留。
在图8-24中,Hub@Tier1字段的值是直接连接到主机的一个根端口的集线器的下行端口号,而该端口上又挂接了第二个集线器,等等。
8.9.1 Route String Port 字段
这个Route String中的4比特宽的字段代表被寻址的集线器的端口。
8.9.2 Route String Port 字段宽度
Route String Port字段宽度被固定为4,限制了集线器最多能支持的端口个数为15。
8.9.3 Port Number
Route String Port字段的值标示包被导向的特定的集线器下行端口。当寻址集线器控制器【译注,即集线器本身】时,Route String中该集线器所在的层级对应的Port Number字段应该被设置为0。集线器下行端口从1开始向上顺序增加来寻址。
8.10 事务包的使用
事务包(TPs)被用来报告数据事务的状态,并且可以返回值用以指示数据包的成功接收(reception of data packets),命令被接收或拒绝(command acceptance or rejection),流程控制(flow control),以及暂停情况(halt conditions)。
8.10.1 流程控制情形【Flow Control Conditions】
本节描述当端点返回一个流程控制响应(flow control response)时,主机和设备之间的交互。流程控制是在主机和设备端点之间的端到端级别的交互。只有批量,控制和中断端点可以发送流程控制响应。
一个IN端点在其返回如下的对ACK TP的响应时,应该被认为在流程控制情形下:
- 用NRDY TP响应;注意端点应该等待它接收到上次发送的DP的ACK TP之后,才能发送NRDY TP【已勘误】。
- 发送一个DP,其DPH中的EOB标志被设为1。
一个OUT端点在其返回如下的对DP的响应时,应该被认为在流程控制情形下:
- 用NRDY TP响应。
- 发送一个ACK TP,其NumP字段被设为0。
Packets Pending字段只在被主机设置时有效,且不影响一个端点是否进入流程控制状态。参考第8.11节关于主机和设备TP响应的进一步细节。
当端点在流程控制情形下,应该发送一个ERDY TP来被转回活动状态。进一步,如果端点是IN端点,它应该等到它接收到一个对它发送的上一个DP的ACK TP之后才能发送ERDY TP。当端点不在流程控制状态下时,除非该端点是支持流模式的批量端点,否则它不应该发送ERDY TP。参考第8.12.1.4.2节和第8.12.1.4.3节关于批量端点可以发送ERDY TP的进一步信息。注意主机可能恢复与一个端点的事务-即使该端点在返回一个流程控制响应后,还没有返回一个ERDY TP。
8.10.2 突发事务【Burst Transactions】
超高速USB协议允许主机连续发送数据到设备,或者从设备连续接收数据,只要设备可以接收或者发送数据。设备在无需中间确认包(intermediate acknowledgement packet)的情况下可以发送或者接收的包的个数在该端点的端点伴侣描述符(endpoint companion descriptor)中报告(参考第9.6.7节)。报告端点的maximum burst size多于一个包的端点被认为是支持"突发"事务。
在进行突发传送时,适用于下面的规则:
- 在接收一个确认包之前,一个突发中可以发送的包个数的最大值,被限制为:端点的最大突发的大小【maximum burst size】(参见表9-20定义的bMaxBurst)和上一个被端点或主机接收到的ACK TP或ERDY的NumP字段值的最小值,减去端点或主机在被上一个ACK TP确认过的包之后已经发送的包的个数。注意,每当端点被初始化时,主机可以重新将能够发送/接收的最大DPs的个数初始化为端点最大突发的大小【maximum burst size】【已勘误】。
- 突发传送中,每一个独立的包应该有数据包负载长度为maximum packet size。只有突发的最后一个包可以小于报告的maximum packet size。如果最后一个小一些,那么对于短包的规则适用于在突发末尾的短包(参考8.10.3节)。
- 突发事务只要ACK TP的NumP字段没被设为0并且每个包都有最大包大小的数据负载,就可以继续。
- NumP字段可在任何时候被发送ACK TP的主机或者设备增加,只要设备或者主机想要继续接收数据。唯一的要求是,NumP字段不应该大于设备支持的最大突发个数。但是,对于ISOC IN端点,参考第8.12.6.1节关于如何改变每个突发(each burst)的NumP字段的更多要求。【已勘误】
- 如果一个发送ACK TP的设备或者主机减小NumP字段,那么一次不能超过1个。例如,如果前一次的ACK TP的NumP字段为5,那么下一个用来确认下一次包被收到的ACK TP的NumP字段不应该少于4。对此规则的唯一例外如下:
- 如果设备可以接受数据但是不能接受更多数据,那么它应该发送NumP字段为0的ACK TP;
- 主机应该发送一个NumP字段为0的ACK TP来响应设备发送来的EOB字段被设置的数据包DP或者短包(参见第8.10.3节)。但是,如果主机接收到短包并且主机对同一端点还有传输要发起,那么主机可能反而要发送一个NumP字段为非0的ACK TP。
- 主机可以发送一个ACK TP,将rty位设置,且将NumP字段设置为小于端点能够支持的最大突发大小的任何值(包括0值,用于对设备发送DP时DPP错误做出响应时)(参见第8.11.2节)【已勘误】。
8.10.3 短包 【Short Packets】
超高速维持了USB2.0支持的短包行为。当主机或者设备接收到一个数据包DP其Data Length字段比端点的最大包长度要小时,它应该认为传输已经完成。
对于IN传输的情况,设备在发送一个短包之后应该停止发送数据包。主机应该用将NumP字段设为0的ACK TP来响应短包(除非主机对该相同端点有另一个传输,在这种情形下主机可以按照第8.10.2节所提到的那样设置NumP字段【已勘误】)。主机应该在发起对该端点的另一个传输的时候来调度对于该设备端点的事务。
对于OUT传输的情况,主机在发送一个短包后可以停止发送数据包。主机应该在对该端点的另一个传输被发起之后来调度对于该设备端点的事务。注意这应该是对该端点的新的一次突发的开始。
8.11 TP或者DP的响应
发送和接收设备应该按照表8-25到表8-27所示的细节来返回数据包(DPs)或者事务包(TPs)。不是所有的事务包(TPs)都是被允许的,这依赖于传输类型和TP流向。
8.11.1 设备对请求数据的TP的响应【Device Response to TP Requesting Data】
表 8-25. 设备对于请求数据的TP的响应 (Bulk, Control, 和 Interrupt端点)
接收到 无效的TP |
接收到Deferred 比特被设置的TP |
设备的Tx Endpoint Halt 特性被设置 |
设备准备好传送数据 |
采取的动作 |
Yes |
不关心 |
不关心 |
不关心 |
设备应该忽略TP。 |
No |
Yes |
Yes |
不关心 |
设备应该发送一个ERDY TP。 |
No |
Yes |
No |
No |
设备不应该响应。它应该在准备好恢复时发送一个ERDY TP。 |
No |
Yes |
No |
Yes |
设备应该发送一个ERDY TP指示他已经准备好接收数据。 |
No |
No |
Yes |
不关心 |
发送STALL TP。 |
No |
No |
No |
No |
发送NRDY TP。 |
No |
No |
No |
Yes |
开始传送数据包(使用主机请求的序列号)。 |
注意IN端点应该等待它接收到上次发送的DP的ACK TP之后才能发送STALL TP【已勘误】。
8.11.2 主机对从设备接收到的数据的响应
表8-26显示了主机对于从设备的bulk, control, 和interrupt端点接受到数据的响应。主机只能返回一个ACK TP。如果DPH的Device Address不正确,或者端点号和方向没有引用属于当前配置的端点,或者没有预期的序列号,或者DPH的Data length大于端点的最大包大小【已勘误】,该DPH都会被认为是无效的。在表8-26中,DPP Error可能是由于下列的一个或者多个原因引起:
• CRC 不正确(incorrect)
• DPP 中止(aborted)
• DPP 丢失(missing)
• DPH 的Data length与数据负载的实际长度不匹配
表 8-26. 主机对从设备接收到的数据的响应(Bulk, Control, 和 Interrupt端点)
DPH 有无效值 |
数据包负载错误(Payload Error) |
主机可以接受数据 |
主机返回的TP |
Yes |
不关心 |
不关心 |
丢弃数据且不发送任何TP |
No |
Yes |
不关心 |
丢弃数据并发送一个Retry比特被设置的ACK TP,请求一个或者更多个数据包DPs,Sequence Number 字段设置为被损坏了的数据包的序列号。 |
No |
No |
No |
丢弃数据并发送一个Retry 比特被设置的ACK TP,请求一个或者更多个数据包DPs,Sequence Number 字段设置为主机此前不能接收的数据包的序列号。这个ACK TP的Host Error比特应该被设置为1来指示主机此前不能接受该数据。 |
No |
No |
Yes |
接受数据并发送一个Retry比特被设置的ACK TP,请求一个或者更多个数据包DPs,Sequence Number 字段设置为下一个预期的数据包的序列号。这也是一个对于该数据包成功接收的确认的暗示。 |
8.11.3 设备对从主机接收到的数据的响应
表8-27显示了设备对于从主机的bulk, control, 和interrupt端点接收到数据的响应。如果DPH的Device Address不正确,或者端点号和方向没有引用属于当前配置的端点,或者没有预期的序列号,该DPH都会被认为是无效的。在表8-27中, DPP Error可能是由于下列的一个或者多个原因引起:
• CRC 不正确(incorrect)
• DPP 中止(aborted)
• DPP 丢失(missing)
• DPH 的Data length与数据负载的实际长度不匹配
注意:除了告诉主机设备具有的可用来接收主机正待发送的数据包缓冲区的个数之外,(主机)接收到一个ACK TP还用来告诉主机,具有前一个序列号的数据包DP已经被该设备成功接收到。设备应该对每一个接收到的数据包DP都发送一个ACK TP。
表 8-27. 设备对OUT 事务的响应 (Bulk, Control, 和 Interrupt 端点)
DPH 有无效值 |
DPH 有Deferred比特被设置 |
接受者Halt特性被设置 |
数据包负载错误(Payload Error) |
设备可以接受数据 |
设备返回的TP |
Yes |
不关心 |
不关心 |
不关心 |
不关心 |
丢弃数据 |
No |
Yes |
Yes |
不关心 |
不关心 |
设备应该发送一个ERDY TP |
No |
Yes |
No |
不关心 |
No |
设备不应该响应。它应该在准备好恢复时发送一个ERDY TP。 |
No |
Yes |
No |
不关心 |
Yes |
设备应该发送一个ERDY TP |
No |
Yes |
No |
不关心 |
不关心 |
设备应该发送一个STALL TP |
No |
No |
No |
不关心 |
No |
丢弃数据并发送一个NRDY TP |
No |
No |
No |
Yes |
Yes |
丢弃数据并发送一个ACK TP,该ACK TP包含期望的序列号(以此来暗示这个数据包DP没有被接收到),Retry 比特被设置,以及该设备端点还可以接收的DPs的个数 |
No |
No |
No |
No |
Yes |
发送一个ACK TP,指示期望的下一个序列号(以此来暗示这个数据包DP已经成功被接收到)以及该设备端点还可以接收的DPs的个数 |
8.11.4 设备对于SETUP DP的响应
SETUP DP是特殊数据包DP,Setup字段被设置为1,且指定为寻址任意的控制端点。SETUP是一类特殊的主机到设备的数据传输,允许主机发起设备应该执行的命令。一旦接收到SETUP DP,设备应该按照表8-28所显示的那样来响应。
注意SETUP DPH如果有如下情况,应该被认为是无效的:
- 不正确的Device Address
- 端点号和方向没有引用属于当前配置的端点
- 端点号没有引用控制端点
- 非零序列号
- 数据长度没有设置为8
在表8-28中, DPP Error可能是由于下列的一个或者多个原因引起:
• CRC 不正确(incorrect)
• DPP 中止(aborted)
• DPP 丢失(missing)
• Setup DPH的Data length与数据负载的实际长度不匹配
表 8-28. 设备对于SETUP 事务的响应(只对Control端点)
DPH 有无效值 |
DPH有Deferred比特被设置 |
数据包负载错误(Payload Error) |
设备返回的TP |
Yes |
N/A |
N/A |
丢弃数据包DP |
No |
Yes |
N/A |
设备应该发送一个ERDY TP指示它已经准备好接收SETUP DP |
No |
No |
Yes |
丢弃SETUP DP,并发送一个Sequence Number字段设置为0,Retry比特被设置,且NumP字段被设置为1的ACK TP |
No |
No |
No |
发送一个ACK TP,Sequence Number 字段设置为1(从而指示这个SETUP DP已经成功被接收到),NumP字段中的值指示主机是否设备想要对Data/Status阶段做流程控制(flow control)。参考第8.12.2节的详情。【已勘误】 |
8.12 事务包序列【TP Sequences】
组成事务的包依端点类型的不同而有所不同。有4种端点类型:批量(bulk),控制(control),中断(interrupt),以及等时(isochronous)。
8.12.1 批量事务【Bulk Transactions】
批量事务类型以具有在主机和设备间通过错误检测和重试来保证数据的无差错传输而著称。批量事务使用双相位事务(two-phase transaction),包含事务包(TPs)和数据包(DPs)。在某种流程控制和挂起条件下,数据相位可能被TP所取代。
8.12.1.1 状态机表示法信息
本节显示详细的用于在IN或OUT端点上推进协议(advance the Protocol)所要求的主机和设备状态机。这些(状态机)图不应该被作为要求的实现(required implementation),而是用以指定要求的行为(required behavior)。
图8-25显示了状态机图的要件(legend)。有三线边框的圆圈表示到另一层级状态机的引用。有两线边框的圆圈表示初始状态。单线边框的圆是简单的状态。
钻石形(接头)用来连接几个转换(transitions)到一个共同点。接头允许一个单输入转换到多个输出转换,或多个输入转换和一个单输出转换。包括一个接头的路径上所有转换的条件都必须为真,该路径才能被选取。路径仅仅只是一系列包含一个或多个接头的转换。
转换具有一个标注块,标注块中间有一条线,线上方是转换的条件,线下方是转换的动作。没有线的转换只是一个条件。条件必须为真才能进行该转换。如果转换被执行,转换相关的动作就会被执行。动作和条件所使用的语言是VHDL语言。一个圈包含一个粗体的名字和可选的一个或者多个动作,当进入该状态时就执行这些动作。
使用实线箭头的转换由主机生成。使用虚线箭头的转换由设备生成。使用斑点虚线箭头的转换要么由主机要么由设备生成。
8.12.1.2 Bulk IN 事务【Bulk IN Transactions】
当主机准备好接收批量数据,它就发送一个ACK TP给设备,指示它期望的从设备接收的包的序列号和包个数。Bulk端点将按照8.11.1所定义的那样来响应。
主机应该对每一个它接收到的数据包DP发送一个ACK TP。如果主机的前一个ACK TP显示主机期望设备发送多于一个数据包DP(根据TP的Number of Packets字段的值判断),设备不必等待主机的ACK TP,就可以发送下一个数据包DP。ACK TP隐性确认主机已经成功地接收到具有前一个序列号的数据包DP,同时也向设备指示主机期望的从设备接收的包的序列号和包个数。如果主机在接收任意数据包DPs的过程中检测到了错误,它应该发送一个ACK TP,序列号设置为接收到的错误包中的第一个DP的序列号,并将Retry比特设置上,即便主机请求的这个突发中的后续的包接收没有错误也要如此。设备被要求重新发送Retry比特被设置的ACK TP中所指的序列号对应的数据包DP。
当主机在端点被初始化(通过Set Configuration,Set Interface,或者ClearFeature (ENDPOINT_HALT)命令——参考第9章关于这些命令的详情)之后开始第一次传输时,主机期望第一个数据包DP的序列号被设置为0。该设备端点的第二个数据包DP序列号应该为1;第三个数据包DP序列号为2;以此下去,直到序列号31。在序列号31后的下一个数据包DP使用序列号0。设备上的端点继续保持增加它传送的数据包的序列号,直到它接收到一个Retry比特被设置的ACK TP,指示其需要重新传送早先的一个DP。
如果主机从设备请求多个数据包,而设备在那时没有那么多个数据包可用,设备应该在最后一个数据包的DPH中将End Of Burst标记设置为1。注意,如果发送到主机的数据包的数据负载长度小于该端点的MaxPacketSize,则没有必要设置这个包的End Of Burst 标记。
当设备发送了主机期望的所有数据包,或者发送了一个数据包的数据负载长度小于该端点的MaxPacketSize,则一个传输完成。当主机想要开始一次新的传输时,主机发送一个ACK TP给设备,指示它期望的从设备接收的下一个包的序列号和包个数。例如,如果数据包的数据负载长度小于该端点的MaxPacketSize的包的序列号为2,那么主机就会发送一个ACK TP,其期望的包的序列号为3,来发起下一次传输。
8.12.1.3 Bulk OUT事务【Bulk OUT Transactions】
当主机准备好要发送数据时,就发送一个或者多个数据包(DPs)给设备。如果具有有效值的DPH(有效的设备地址,端点号,以及方向和期望的序列号)被设备接收到,就应该按照第8.11.3节所定义的那样来做出响应。
当主机在端点被初始化(通过Set Configuration,Set Interface,或者ClearFeature (ENDPOINT_HALT)命令——参考第9章关于这些命令的详情)之后开始第一次传输时,主机总是将其与该端点执行的第一个传输的第一个数据包的序列号初始化为0。第二个数据包的序列号设置为1;第三个数据包DP序列号设置为2;以此下去,直到序列号31。在序列号31后的下一个数据包DP使用序列号0。主机继续保持增加它传送的数据包的序列号,直到它接收到一个Retry比特被设置的ACK TP,指示其需要重新传送早先的一个包。
当主机发送了所有的数据包到设备时一个传输就算完成。但是该传输的最后一个数据包的数据负载可能会(也可能不会)等于端点的MaxPacketSize。当主机想要开始一次新的传输时,就应该发送另一个数据包,使用下一个序列号,并用设备中的一个端点作为目标。
8.12.1.4 批量流协议
【Bulk Streaming Protocol】
流协议(Stream Protocol)遵循(adheres to)标准超高速批量协议的语义,因此在支持流协议的超高速批量管道上的包交换和不支持流协议的超高速批量管道上的包交换不可区分(indistinguishable)。流协议(Stream Protocol)通过操作包头中的Stream ID字段来严格进行管理。
注意:使用设备类定义的方法来协调Stream IDs(主机用于选择Endpoint Buffers,而设备用于选择与特定Stream相关联的Function Data)。典型地,这是通过带外机制(out-of-band mechanism)实现的(例如,另一个端点),用来在主机和设备之间传递"Active Stream IDs"的列表。
注意:Stream状态机显示发送一个DP和接收一个ACK TP之间1:1的关系。逻辑上这是真的,但是超高速突发能力(SuperSpeed burst capabilities)允许多达MaxBurst个在主机和设备之间的ACKs,因此可能临时会有"多对一"的关系存在。Bursts在Stream pipe上的管理和他们在普通Bulk pipe上的管理一样。参考第8.10.2节关于Burst Transactions的更多信息。【已勘误】
注意:正如本节所描述的,流协议应用于"管道"的状态,并且作为一个单一实体来描述。实际上,流协议被管道一端的主机和另一端的设备所独立地跟踪。因此在任意时刻,由于主机和设备间的包传播时延,两端可能出现暂时的相位不一致。
图8-28阐释了流协议状态机【Stream Protocol State Machine(SPSM)】的基本状态转换。本节描述SPSM的总体状态转换,因为他们同时适用于IN和OUT端点。关于SPSM对于IN和OUT端点的详细操作在后面的章节描述。
Disabled – 这是管道在被配置后的初始状态,也是在其他任意状态时检测到错误后转换到的状态。在端点缓冲区被指派给管道时,主机应该将SPSM转换到Prime Pipe状态。如果Disabled状态是因为错误而进入的,那么错误条件必须通过软件干预移除后方可退出该状态。注意,从设备来的Stall响应应该将任何SPSM状态都转换进入Disabled状态。如果设备不响应(也就是说timeout),则主机应该发送一个Clear Feature Halt来复位该端点,在这种情况下,所有的SPSMs都应该转换进入Disabled状态。【已勘误,澄清设备不会在timeout时做状态转换,因为它不知道事务是否已经timeout。】【译注:这里其实还暗示了在Clear Feature Halt时,主机和设备端都应该做相应动作,转换进入Disabled状态。类似于USB2中Clear Feature Halt应该将主机和设备端的Data Toggle都恢复到DATA0。这在软件上往往是容易出问题的地方,各个实现可能出现不一致。】
【Prime Pipe –总是由主机发起转换到该状态,并通知设备,一组端点缓冲区(Endpoint Buffer)已经由软件加入或者修改。在从该状态退出后,任何之前被设备认为是Not Ready的Active Stream IDs都应该被认为是已经Ready。
注意:为了减少总线事务,主机控制器将每次进入Idle状态而转换到Prime Pipe状态的次数限制为1。这意味着当在Idle状态时,只会生成一次到Prime Pipe状态的转换,尽管可能多个流(multiple streams)的Endpoint Buffers变得Ready。而由于Prime Pipe状态并不指定哪个(些)Stream(s)已Ready,所有的Active Stream IDs都被Prime Pipe设置成Ready。设备应该负责通过在返回到Idle状态后发送恰当的ERDYs,来测试所有的Active Stream IDs(如上面描述的那样)。注意,设备类定义的限定(constraints)可能被用来限制在任何时间需要进行测试的Active Stream IDs的个数。
Idle – 转换到这一状态,指示没有当前流(Current Stream)(CStream)被选取。在这一状态,SPSM正等待由主机发起的到Prime Pipe或者到Move Data状态的转换;或者由设备发起的到Start Stream状态的转换。主机和设备发起转换的目标,是开始为Stream搬移数据。由主机发起的到Move Data的转换被称为Host Initiated Move Data或者HIMD。所有的Active Stream IDs都被HIMD设为Ready。
Start Stream – 该状态总是由设备当想要在一个选定的Stream上开始数据传输时发起。设备可以在每当它有一个Ready Stream ID时,发起一个到该状态的转换。如果设备选择的Stream被主机接受,则管道进入Move Data状态。如果设备选择的Stream ID被主机拒绝,管道就返回到Idle状态,并且被选择的Stream ID应该被设备临时认为是Not Ready。注意,设备维护一个Active Stream IDs的列表。一个Active Stream ID可能Ready,也可能Not Ready。设备被主机通过带外机制(out-of-band mechanism)告知Active Stream IDs(典型地是通过一个单独的OUT端点)。
Move Data – 在这一状态,流数据(Stream data)被传输。当转换进入该状态时,Current Stream被设置。当流传输(Stream transfer)完成后,或者如果主机或设备由于临时耗尽了它们的数据或缓冲空间而决定要终结流传输(Stream transfer)时, SPSM 转换回到Idle状态。转换到Idle状态同时使得管道的Current Stream (CStream) 变得无效。】【已勘误】
【译注:流状态机在原先设计时基于一个假设,即如果在一次突发(burst)中,如果检测到了错误,则要求所有的重试(retries)都要完成,这个突发才能完成,也就是说,如果NumP = 0,则Rty不允许是1。核心规范在USB3_Errata [June 2010]中已经被修改,当NumP = 0时可以允许Rty是1。现在,这就意味着Rty可以跨多个突发(retries can span bursts)。本译文根据USB3_Errata [June 2010]的描述对流状态机的相应部分做了更正,以反映这一核心规范的修改。在下面的译文中,相关勘误处标记了"勘误:Rty可以跨多个突发"。】
8.12.1.4.1 Stream IDs
一个16比特Stream ID字段被保留在数据包DP头以及ACK, NRDY, 和ERDY TP事务包中,用以在主机和设备之间传递SIDs。流协议所保留的特定的SID值以及其他一些SID表示法如下:
• NoStream – 这个SID指示没有Stream ID与相关的总线包相关联,因此Stream ID字段不应该被当作有效Stream来解释。NoStream SID的值为FFFFh 。
• Prime – 这个SID被用来定义转换进或出Prime Pipe状态。与NoStream一样,没有Stream ID与相关的总线包相关联,因此Stream ID字段不应该被当作有效Stream来解释。Prime SID 的值是FFFEh。
• Stream n – 此处n是一个在1到65533 (FFFDh)之间的值。这个表示法用来引用一个有效的Stream ID。如果使用这个表示法,则表示包头中的Stream ID字段为有效。有效的Stream n SID值在1到65533 (FFFDh) 之间,其中数字值等于n。
• Stream 0 – 这个值是被保留的,不被支持流的管道所使用。Stream 0 SID值是0000h。标准的批量管道要求使用它。
• CStream – 代表与管道相关联的"当前(Current)" Stream ID。CStream由主机和设备共同维护。流协议确保CStream值在主机和设备间一致。有效值是NoStream或者Stream n。
• LCStream – 代表在上一次状态转换之前赋予管道的CStream SID值。LCStream值由主机维护。有效值是Prime, NoStream, 或者Stream n。例如,如果管道在Move Data状态时CStream = Stream n,当管道从Move Data转换到Idle状态,LCStream就设为Stream n,并且CStream被设置为NoStream,因此LCStream就记录了"Last CStream"的值。
Stream n SID的值由主机指定,并且传递给设备(典型地是通过带外(out-of-band),设备类定义的方法实现)。Stream n SID的值应该被设备作为"逻辑值",也就是说,设备不应该根据其值来推断其意义,或者对其进行修改。
注意:下面的批量IN和OUT的流协议描述简化了的状态机,不明确地解释超高速端点允许数据包在无需接收到ACK之前就可以发送数据包这一突发(burst)特性的细节。具体实现应该扩展这些状态机,来管理突发事务(manage bursting)。
【
下面几节(第8.12.1.4.2节到第8.12.1.4.5节) 将Stream状态机根据设备端和主机端的Stream管道而分开成4种情形。第8.12.1.4.2节和第8.12.1.4.3节描述设备端状态机。第8.12.1.4.4节和第8.12.1.4.5节描述主机端状态机。而对管道的每一端,都有单独一节来描述相应的IN和OUT操作。
每个Stream状态机的子章节描述状态机的相关状态。子章节以描述状态的目的和总体特性开始,接着讨论状态的每个退出转换。描述状态的退出转换的段落前有一个唯一的在前一状态图中相关退出转换的"条件(condition)"或"动作(action)"的标签。
注意:在主机和设备之间路径上的U1或U2超时值应该被设置为可以防止对Data Transactions的正常响应而转换到U1或U2。参考第8.13节关于Data Transaction的更多时序信息。
注意:在Stream状态机一节,状态名称是被重载的(overloaded),例如,Idle状态在所有4个状态机描述中都有定义。INMvData Host状态在设备和主机的IN状态机两节都有定义,等等。这些状态是相关的,因为它们可能在Stream管道的两端都出现,但是每个Stream状态机小节都描述一个独立的状态机,因此与状态相关的条件和动作在各节都是清楚明显的(distinct)。
注意:斜体的转换条件应该被解释为注释,而不是要求的条件。例如,图8-1中的从Idle到Start Stream转换的文本"Stream n Active and Ready"。
注意:任何的CStream的数据负载都可能是零长(zero-length)。在Stream管道上对零长(zero-length)DPs的使用(而不是用于Prime Pipe或者拒绝Start Stream操作)是由与端点关联的设备类定义的。
注意:一个IN Data或者Burst Transaction是由一个NumP = 0的ACK TP终结的。这个ACK TP在下面几节被称为"终结ACK(Terminating ACK)"。
】
8.12.1.4.2 设备输入流协议 【Device IN Stream Protocol】
本节定义在IN Bulk端点上,使得设备端的流协议(Stream Protocol)从一个状态转换到另一个状态的超高速包交换(SuperSpeed packet exchanges)。
在下文中,假设Device IN Stream状态转换发生在设备发送与状态机相关的消息的第一个符号的第一个比特给主机时,或者当设备首次解码从主机来的状态机相关的消息时。对于IN管道,主机端的Endpoint Buffers接收来自设备的Function Data。
【勘误:上图中 "Stall or Error" 应该重命名为"Stall or Clear Feature Halt",去除timeout的情形。】
8.12.1.4.2.1 Disabled
在端口被配置后,管道状态处于Disabled状态。
ACK(Prime, NumP>0, PP=0) – 如果接收到Stream ID设置为Prime的ACK TP,则设备应该将管道转换进入Prime Pipe状态。这一转换发生在初始Endpoint Buffers被系统软件指派给管道之后。
ACK(Deferred) – 如果接收到一个Deferred (DF)标志被设置的ACK TP,则设备应该将管道转换进入Deferred Prime Pipe状态。当在等待被指派初始Endpoint Buffers的时候,链路转换进入了U1或U2状态,会收到这个包。
8.12.1.4.2.2 Prime Pipe
Prime Pipe状态通知设备,已经有Endpoint Buffers被指派给一个或多个Streams,但是没有指定是哪些Stream(s)。在这个状态,设备应该将所有的Active Streams设为Ready。在返回Idle状态之后,设备应该发送一个ERDY,来从它的Active Streams列表中启动一个特定的Stream。
NRDY(Prime) – 当进入Prime Pipe状态时, 设备应该生成一个Stream ID设为Prime的NRDY TP,并转换到Idle状态。
8.12.1.4.2.3 Deferred Prime Pipe
Deferred Prime Pipe状态通知设备,已经有Endpoint Buffers被指派给一个或多个Streams,但是在等待时链路已经转换到U1或U2状态。在这个状态,设备应该将所有的Active Streams设为Ready。在返回Idle状态之后,设备应该发送一个ERDY,来从它的Active Streams列表中启动一个特定的Stream。
No Condition – 当进入Deferred Prime Pipe状态时,设备应该立即转换到Idle状态。这是图8-1中唯一的Deferred Prime Pipe状态的退出转换。
8.12.1.4.2.4 Idle
在Idle状态,管道在等待一个Stream选择(Stream selection)(例如,到Start Stream或Move Data的一个转换),或者一个从主机来的通知,告知一个Stream Endpoint Buffer已经为该管道而被添加或修改(即,转换到Prime Pipe)。注意,在初始进入Idle时(从Disabled),只有设备可以发起一个Stream选择(Stream selection)。
ERDY(Stream n, NumP>0) – 为了发起Stream选择(Stream selection),设备生成一个ERDY TP,将其Stream ID设为Stream n,且NumP值>0,并转换到Start Stream状态,其中的Stream n是设备建议的(proposed)Stream ID。设备可以在它想要开始一次Stream transfer时发起这个转换,无论管道是否处于流程控制(flow control)情形。设备维护一个可以为之生成ERDYs的Active and Ready Streams的列表。设备用于Stream选择(Stream selection)的方法超出了本规范的范围,通常是由与管道相关的设备类所定义。注意ERDY NumP字段反映了设备的Stream n可用的Endpoint Data的数量。
ACK(Prime, NumP>0, PP=0) – 如果从主机接收到了Stream ID等于Prime的ACK TP,则设备应该转换到Prime Pipe状态。
ACK(Stream x, NumP>0) – 使用这个转换,主机向设备建议Stream ID Stream x。如果从主机接收到Stream ID不等于Prime的ACK TP,设备应该转换到Move Data状态。主机可以在它想要开始一次Stream transfer时发起这个转换,而这被称为Host Initiated Move Data,或者说HIMD。HIMD指示Endpoint Buffer已经为之改变的特定Stream。由于这一转换,设备应该将Stream x设为Ready。在进入Move Data状态之后,设备可以用NRDY来拒绝该被建议的(proposed)Stream,或者用一个DP来接受该被建议的(proposed)Stream。当转换到Move Data状态的时候,设备将CStream设置成接收到的Stream ID (Stream x)。典型地,Stream x将等于设备上一次生成的ERDY中的Stream ID (Stream n)。如果下面描述的竞争条件(race condition)发生,则Stream x可以不等于Stream n,因为主机在这些条件下会丢弃ERDYs。PP应该等于1。
ACK(Deferred) – 如果接收到Deferred (DF)标志被设置的ACK TP,则设备应该将管道转换进入Deferred Prime Pipe状态。当链路已经转换进入U1或U2状态,且主机已经尝试了一个HIMD时,会接收到这个包。
8.12.1.4.2.5 Start Stream
在Start Stream状态,设备正在等待主机接受或拒绝设备建议的Active and Ready Stream的选择。
ACK(Stream n, NumP>0) – 如果接收到Stream ID等于Stream n的ACK TP,则主机已经接受了设备提出的开始Stream n的建议,而设备应该转换进入Move Data状态。当转换到Move Data状态的时候,设备将CStream设置成接收到的Stream ID (Stream n)。PP应该等于1。
ACK(NoStream, NumP=0, PP=0) – 如果接收到Stream ID等于NoStream的ACK TP,则主机已经拒绝了设备提出的开始Stream n的建议,而设备应该转换进入Idle状态。因为这一转换,设备应该将Stream n设置到Not Ready。如果没有Endpoint Buffers可用,则主机应该拒绝从设备来的建议。
ACK(Prime, NumP>0, PP=0) –如果从主机接收到的Stream ID等于Prime的ACK TP,则发生了竞争条件(race condition)。主机已经进入了Prime Pipe状态,通知设备有一个或者多个Streams的Endpoint Buffers被更新,而同时设备也已试图发起Stream transfer,而且他们相应的消息都通过链路传递到了对方。在这个情形期间,设备处于Start Stream状态,而主机处于Prime Pipe状态。为了解决这个情况,设备应该转换到Prime Pipe状态。
ACK(Stream x, NumP>0) – 如果接收到Stream ID等于Stream x的ACK TP,则发生了竞争条件(race condition)。主机已经进入了Move Data状态,启动在Stream x上的传输,而同时设备也已试图发起在Stream n上的一次传输,而且他们相应的消息都通过链路传递到了对方。在这个情形期间,设备处于Start Stream状态,而主机处于Move Data状态。为了解决这个情况,设备应该转换到Move Data状态。因为这一转换,设备应该将Stream x设置到Ready。当转换到Move Data状态的时候,设备将CStream设置成接收到的Stream ID (Stream x)。PP应该等于1。
ACK(Deferred) – 如果接收到Deferred (DF)标志被设置ACK TP【已勘误,去掉要求Stream ID是Prime这一条件】,则设备应该将管道转换进入Deferred Prime Pipe状态。当在等待主机响应Start Stream请求时,链路被转换进入U1或U2状态时,会接收到这个包。注意这一转换只有在tERDYTimeout过期时才会发生。【译注:处于Start Stream状态的设备可能会接收到Deferred ACK TP,其中的Stream ID可能是Prime,也可能是LCStream(如果是因为HIMD的话)。在这两种情况下,设备都应该返回到Idle状态。】
注意:在Idle和Start Stream状态中的"PP应该等于1"一句,并不要求设备为相关的转换去验证PP,但是,如果设备的确要检查,如果PP不等于1,则它应该将EP停止(halt)。
8.12.1.4.2.6 Move Data
在Device IN Move Data状态,CStream在管道的两端都设为相同值,且管道可以积极搬运数据。在Move Data状态所执行的总线事务的详情以及它的退出条件在Device IN Move Data State Machine中定义。
【勘误:上图中的INMvData Device Terminate到exit的转换的标签ACK(CStream, NumP=0, PP = 0),应该改为ACK(CStream, NumP=0)。这是为了覆盖"主机还有更多缓冲空间可用,而设备已终结了这个突发"的情形。】
【勘误:Rty可以跨多个突发。
去掉从INMvData Host到exit的ACK(Deferred)转换。
去掉从INMvData Device Terminate到exit的ACK(Deferred)转换。
添加从INMvData Device Terminate到INMvData Burst End的ACK(CStream, NumP=0, PP=1, Rty)转换。
因此,上面的状态机图可以用下面的状态机图替换。为对比起见,先保留原图,并将修改后的状态机图附于下面。
】
Device IN Move Data State Machine (DIMDSM)是从上面描述的Start Stream或Idle状态进入的。一旦进入DIMDSM,立即就转换进入INMvData Device状态。DIMDSM允许设备由于耗尽与Stream相关的Function Data而终结Move Data操作,也允许主机因耗尽与Stream相关的Endpoint Buffer空间而终结Move Data操作。
DIMDSM总是退出到Idle状态。Retry (Rty=1) 标志在导致DIMDSM退出的包中绝不该设置。Stream管道在包重试期间保持在Move Data状态。
注意:在Move Data状态期间所交换的所有包的Stream ID值都应该是CStream。如果在DIMDSM期间检测到Stream ID值不是CStream,设备应该halt端点。
注意:如果在初始进入Move Data状态时CStream不是Active的,则设备可以使用设备类定义的NRDY或STALL拒绝该Stream建议。
8.12.1.4.2.7 INMvData Device
这一状态最初是从Start Stream状态或Idle状态进入的。在该状态,设备准备一个DP发给主机,或者拒绝从主机来的HIMD。
DP(CStream, EOB=0) – 如果设备对CStream的Endpoint Data超过Max Packet Size,则设备应该发送一个EOB = 0的DP给主机,并转换进入INMvData Host状态。DPP应该包含CStream的数据。
DP(CStream, EOB=1) – 如果设备对CStream的Endpoint Data少于或等于Max Packet Size,则设备可以(may)发送一个EOB = 1的DP给主机,并转换进入INMvData Device Terminate状态。DPP应该包含CStream的数据。【已勘误】【译注:并不是必须要求要设置EOB,除非设备想要进行流程控制(flow control)。】
NRDY(CStream) – 设备可以通过发送一个Stream ID设为CStream的NRDY来拒绝进一步的CStream transfers,并转换进入Idle状态,退出DIMDSM。设备可以在最初进入到DIMDSM时为拒绝HIMD,也可以在Stream transfer期间由于不可预期的内部情况而想要流程控制(flow control)CStream时, 生成该转换。
8.12.1.4.2.8 INMvData Host
在该状态,设备刚刚发送了一个DP给主机,且还有更多给CStream的Function Data。设备在该状态等待来自主机的对上一DP的确认。
ACK(CStream, NumP>0, PP=1) - 如果设备接收到NumP > 0且PP = 1的ACK TP,则应该转换进入INMvData Device状态。这是主机在当前突发(current burst)还未完成,且它还有为CStream DP的更多Endpoint Buffer空间可用时的响应。注意,如果主机检测到在上一个DP中有错误,则Retry (Rty=1)可以被设置。如果Rty被设置,则设备应该在它下次发送一个DP时使用恰当的Sequence Number返回该DP。如果检测到DP错误,主机可以(may)继续当前突发(current burst),直到所有重试都耗尽,或者收到一个好包。如果在主机不能继续当前突发(current burst)的情况下,主机将会在该端点类型限制内的下一个可用机会时回到该端点。【已勘误,原文档说主机"应该(shall)"继续当前突发,现在更正为"可以(may)"。这简化了主机的行为,并且去除了因为要等待其他端点请求多次重试而使得周期性传输遭受饥饿(starved)的情形。此外,核心规范并没有重试次数的限制(一般来说是3次)。】
ACK(CStream, NumP=0, PP=1) – 如果设备接收到NumP = 0且PP = 1的ACK TP,则应该转换进入INMvData Burst End状态。这是主机在它还有更多的为另一个CStream DP的Endpoint Buffer空间可用,但它又必须终结从设备来的当前突发(current burst)时的响应。注意在从INMvData Host到INMvData Device的转换期间,设备应该看到随着突发趋于完成,NumP也向着0递减。注意,如果主机检测到在从设备来的上一个DP中有错误,则Retry (Rty=1)可以被设置。
ACK(CStream, NumP=0, PP=0) – 如果设备接收到NumP = 0 且 PP = 0的ACK TP,则应该转换进入Idle状态,退出DIMDSM。这是主机在它接受了上一个DP而耗尽其CStream Endpoint Buffer空间时的响应。设备应该因为这个转换而将其CStream设为Not Ready。在从INMvData Host到INMvData Device转换期间,设备应该看到随着Endpoint Buffer被消耗,NumP也向着0递减。
ACK(Deferred) –如果设备接收到Deferred (DF)标志被设置的ACK TP,则应该转换进入Idle状态,退出DIMDSM。当设备在等待主机用一个ACK响应一个DP时链路转换进入U1或U2,会收到这个包。注意这个转换是可能的(possible),但极不易(highly unlikely)。
注意:在INMvData Host状态接收到NumP > 0 且 PP = 0的ACK TP是非法的组合,如果检测到的话,设备应该halt端点。
8.12.1.4.2.9 INMvData Device Terminate
进入这一状态是因为设备已经发送了CStream的最后一个可用DP,即它已经耗尽了其CStream Function Data。设备在该状态等待来自主机的对该Move Data transfer上一DP的确认。
ACK(CStream, NumP=0, No Rty) - 如果设备接收到NumP = 0且Rty = 0的ACK TP,则应该转换进入Idle状态,退出DIMDSM。这是主机确认从设备来的CStream的上一个DP时的正常主机响应(Terminating ACK)。
ACK(CStream, NumP>0, PP=1, Rty) –如果设备接收到Rty = 1的ACK TP,则应该转换进入INMvData Device状态,并重发恰当的包(resend the appropriate DP)。这是主机在检测到从设备来的DP中有错误,而突发尚未完成时的主机响应。
ACK(CStream, NumP=0, PP=1, Rty) –如果设备接收到Rty = 1而NumP = 0的ACK TP,则应该转换进入INMvData Burst End状态,并等待主机发起下一个突发(initiate the next burst)。这是主机在检测到从设备来的DP中有错误,但突发已经完成(burst was complete)时的主机响应。主机应该在下一个突发中继续重试过程(continue the retry process in the next burst)。
8.12.1.4.2.10 INMvData Burst End
进入该状态是因为主机已经终结了一个Stream管道上的一个突发。在该状态设备等待一个ACK TP来表示另一个突发的开始。
ACK(CStream, NumP>0, PP=1) – 如果设备接收到NumP > 0且PP = 1的ACK TP,则应该转换进入INMvData Device状态。注意,如果Rty标志在进入该状态时是被设置的,则在退出该状态时Rty标志也应该被设置。
ACK(Deferred) –如果设备接收到Deferred (DF)标志被设置的ACK TP,则应该转换进入Idle状态,退出DIMDSM。这个转换发生在当设备在等待主机重新开始突发(restart a burst)时链路转换进入U1或U2,而且这个转换随着与其他设备的传输活动增加时会变得越加可能(becomes more likely)。
8.12.1.4.3 设备输出流协议 【Device OUT Stream Protocol】
本节定义在OUT Bulk端点上,使得设备端流协议(Stream Protocol)从一个状态转换到另一个状态的超高速包交换(SuperSpeed packet exchanges)。
在下文中,假设Device OUT Stream状态转换发生在当设备发送与状态机相关的消息的第一个符号的第一个比特给主机时,或者当设备首次解码从主机来的状态机相关的消息时。对与OUT管道,主机端的Endpoint Data发送给设备的Function Buffers。除非特别说明,DP将包含Endpoint Data。
【勘误:上图中 "Stall or Error" 应该重命名为"Stall or Clear Feature Halt",去除timeout的情形。】
【勘误:上图中,从Idle状态到Start Stream End状态之间,应该添加一条弧线(arc),标签为DP(NoStream,PP=0)。在转换进入U0后,设备会立即发送一个ERDY,导致DOSPSM和HOSPSM从Idle状态转换进入Start Stream状态。在转换进入Start Stream状态之后,设备从一个集线器处接收到一个DPH(Deferred),导致DOSPSM转换到Idle状态。在这一刻,DOSPSM和HOSPSM变得不同步(out of sync)。HOSPSM正处于Start Stream状态,就发送一个DP(NoStream, PP=0);然而设备正处于Idle,从而不能处理这个包。】
8.12.1.4.3.1 Disabled
在端口被配置后,管道状态处于Disabled状态。
DP(Prime, PP=0) – 如果成功接收到Stream ID设置为Prime的DP,则设备应该将管道转换进入Prime Pipe状态。DPP应该包含零长(zero-length)数据负载。这一转换发生在初始Endpoint Buffers被系统软件指派给管道之后。注意,如果在DP数据中检测到错误(尽管是零长的),设备应该保持在Disabled状态,并发送ACK(Prime, NumP>0, Rty)包,重试,直到一个DP(Prime)被成功接收到。这种情况没在上图说明。
DPH(Deferred) – 如果接收到一个Deferred (DF)标志被设置的DP,则设备应该将管道转换进入Deferred Prime Pipe状态。在等待被指派初始Endpoint Data的时候,链路转换进入了U1或U2状态,会收到这个包。
8.12.1.4.3.2 Prime Pipe
Prime Pipe状态通知设备,已经有Endpoint Data被指派给一个或多个Streams,但是没有指定是哪些Stream(s)。在返回Idle状态之后,设备应该发送一个ERDY,来从它的Active and Ready Streams列表中启动一个特定的Stream。
NRDY(Prime) – 当进入Prime Pipe状态时, 设备应该生成一个Stream ID 设为Prime的NRDY TP,并立即转换到Idle状态。
8.12.1.4.3.3 Deferred Prime Pipe
Deferred Prime Pipe状态通知设备,已经有Endpoint Data被指派给一个或多个Streams,但是在等待时链路已经转换到U1或U2状态。
No Condition – 当进入Deferred Prime Pipe状态时,设备应该立即转换到Idle状态。
8.12.1.4.3.4 Idle
在Idle状态,管道在等待一个Stream选择(Stream selection)(例如,到Start Stream或Move Data的一个转换),或者一个从主机来的通知,Endpoint Data已经为该管道而被添加或修改(即,转换到Prime Pipe)。注意到在初始进入Idle时,只有设备可以发起一个Stream选择(Stream selection)。
ERDY(Stream n, NumP>0) – 为了发起Stream选择(Stream selection),设备生成一个ERDY TP,将其Stream ID设为Stream n,且NumP值>0,并转换到Start Stream状态,其中的Stream n是设备建议的(proposed)Stream ID。设备可以在它想要开始一次Stream transfer时发起这个转换,无论管道是否处于流程控制(flow control)情形。设备维护一个可以为之生成ERDYs的Active and Ready Streams的列表。设备用于Stream选择(Stream selection)的方法超出了本规范的范围,通常是由与管道相关的设备类所定义。注意ERDY NumP字段反映了设备为Stream n可用的Endpoint Buffer空间的数量。
DP(Prime, PP=0) – 如果从主机成功接收到了Stream ID等于Prime的DP,则设备应该转换到Prime Pipe状态。DPP应该包含零长(zero-length)数据负载。注意,如果在DP数据中检测到错误,设备应该保持在Idle状态,并发送ACK(Prime, NumP>0, Rty)包,重试,直到一个DP(Prime)被成功接收到。DPP应该包含零长(zero-length)数据负载。
DP(Stream x) – 使用这个转换,主机向设备建议Stream ID Stream x。如果从主机接收到的Stream ID不等于Prime的DP,设备应该转换到Move Data状态。主机可以在它想要开始一次Stream transfer时发起这个转换,而这被称为Host Initiated Move Data,或者说HIMD。HIMD指示Endpoint Data已经为之改变的特定Stream。由于这一转换,设备应该将Stream x设为Ready。在进入Move Data状态之后,设备可以用NRDY来拒绝该被建议的(proposed)Stream,或者用一个ACK TP来接受该被建议的(proposed)Stream。当转换到Move Data状态的时候,设备将CStream设置成接收到的Stream ID (Stream x)。DPP应该包含对该Stream的第一个数据包负载。典型地,Stream x将等于设备上一次生成的ERDY中的Stream ID (Stream n)。如果下面描述的竞争条件(race condition)发生,则Stream x可以不等于Stream n,因为主机在这些条件下会丢弃ERDYs。
ACK(Deferred) – 如果接收到Deferred (DF)标志被设置的DPH,则设备应该将管道转换进入Deferred Prime Pipe状态。当链路已经转换进入U1或U2状态,且主机已经尝试了Prime Pipe或Move Data(HIMD)转换时,可能会接收到这个包。
8.12.1.4.3.5 Start Stream
在Start Stream状态,设备正在等待主机接受或拒绝设备建议的Active and Ready Stream的选择。
DP(Stream n) – 如果接收到Stream ID等于Stream n的DP,则主机已经接受了设备提出的开始Stream n的建议且提供了Stream n的数据的第一个包,而设备应该转换进入Move Data状态。当转换到Move Data状态的时候,设备将CStream设置成接收到的Stream ID (Stream n)。DPP应该包含CStream的第一个数据负载。
DP(NoStream, PP=0) – 如果成功接收到Stream ID等于NoStream的DP,则主机已经拒绝了设备提出的开始Stream n的建议,而设备应该转换进入Start Stream End状态。DPP应该包含一个零长(zero-length)数据负载。如果没有给Stream的Endpoint Data,则主机应该拒绝从设备来的建议。因为这一转换,设备应该将Stream n设置到Not Ready。注意,如果在DP数据中检测到错误,设备应该保持在Start Stream状态,并发送ACK(Prime, NumP>0, Rty)包,重试,直到一个DP(NoStream)被成功接收到。这个情形没有在上图中说明。
DP(Prime, PP=0) –如果从主机接收到的Stream ID不等于Prime的DP,则发生了竞争条件(race condition)。主机已经进入了Prime Pipe状态,通知设备有一个或者多个Streams的Endpoint Data被发布(posted),而同时设备也已试图发起Stream transfer,而且他们相应的消息都通过链路传递到了对方。DPP应该包含一个零长(zero-length)数据负载。在这个情形期间,设备处于Start Stream状态,而主机处于Prime Pipe状态。为了解决这个情形,设备应该转换到Prime Pipe状态。注意,如果在DP数据中检测到错误,设备应该转换进入Prime Pipe状态并在那里进行任何重试。
DP(Stream x) – 如果接收到Stream ID不等于Stream n,Prime 或 NoStream(即,等于Stream x)的DP,则发生了竞争条件(race condition)。主机已经进入了Move Data状态,启动在Stream x上的传输,而同时设备也已试图发起在Stream n上的一次传输,而且他们相应的消息都通过链路传递到了对方。在这个情形期间,设备处于Start Stream状态,而主机处于Move Data状态。为了解决这个情形,设备应该转换到Move Data状态。因为这一转换,设备应该将Stream x设置到Ready。当转换到Move Data状态的时候,设备将CStream设置成接收到的Stream ID (Stream x)。DPP应该包含CStream的第一个数据负载。当在Move Data状态时,设备可以接受或者拒绝由主机建议的Stream。
DPH(Deferred) – 如果接收到Deferred (DF)标志被设置的DPH,则则设备应该将管道转换进入Deferred Prime Pipe状态。当在等待主机响应Start Stream请求,链路被转换进入U1或U2状态时,会接收到这个包。注意这一转换只有在tERDYTimeout被超过时才会发生,因此是极不易(highly unlikely)发生的。在这种情形下,设备被期望用ERDY来重试。没有与deferred DPH相关联的DPP。
8.12.1.4.3.6 Start Stream End
在Start Stream End状态,设备已经收到了主机对它建议的Stream选择(Stream selection)的拒绝,且必须对主机发来的DP做出响应。Bulk协议要求对任何已经发送的DP要有一个ACK 或 NRDY。Streams协议指定发送一个NRDY。
NRDY(NoStream) – 设备应该生成一个Stream ID等于NoStream的NRDY,并转换到Idle状态。
8.12.1.4.3.7 Move Data
在Device OUT Move Data状态,CStream在管道的两端都设为相同值,且管道可以积极搬运数据。在Move Data状态所执行的总线事务的详情以及它的退出条件在Device OUT Move Data State Machine中定义。
Device OUT Move Data State Machine (DOMDSM)是从上面描述的Start Stream或Idle状态进入的。DOMDSM允许设备由于耗尽与Stream相关的Function Buffer空间而终结Move Data操作,也允许主机因耗尽与Stream相关的Endpoint Data而终结Move Data操作。
PP=0 – 在进入DOMDSM时,如果主机只有Stream的一个包的Endpoint Data可用,则PP应该在设备接收到的第一个DP中等于0,且它将转换进入OUTMvData Device Terminate状态。
PP = 1 – 在进入DOMDSM时,如果主机有Stream的多于一个包的Endpoint Data可用,则PP应该在设备接收到的第一个DP中等于1,且它将转换进入OUTMvData Device状态。
DOMDSM总是退出到Idle状态。Retry (Rty=1) 标志在导致DOMDSM退出的包中绝不该设置。Stream管道在包重试期间保持在Move Data状态。
注意:在Move Data状态期间所交换的所有包的Stream ID值都应该是CStream。如果在DOMDSM期间检测到Stream ID值不是CStream,设备应该halt端点。
注意:如果在初始进入Move Data状态时CStream不是Active的,则设备可以使用设备类定义的NRDY或STALL拒绝该Stream建议。
8.12.1.4.3.8 OUTMvData Device
这一状态初始是从Start Stream状态或Idle状态进入的。在该状态设备确认主机发送的上一个DP,或者拒绝从主机来的HIMD。
ACK(CStream, NumP>0) – 如果设备对CStream有更多Function Buffer可用,则设备应该发送一个NumP > 0的ACK TP给主机,并转换进入OUTMvData Host状态。注意,如果设备在从主机来的上一个DP中检测到了错误,则Retry (Rty)标志可以被设置。主机可以(may)继续当前突发(current burst),直到所有的重试都耗尽,或者正面确认【positive acknowledgement (Rty=0)】被接收到。如果在主机不能继续当前突发(current burst)的情况下,主机将会在该端点类型限制内的下一个可用机会时回到该端点。【已勘误,原文档说主机"应该(shall)"继续当前突发,现在更正为"可以(may)"。这简化了主机的行为,并且去除了因为要等待其他端点请求多次重试而使得周期性传输遭受饥饿(starved)的情形。此外,核心规范并没有重试次数的限制(一般来说是3次)。】这个转换应该指示此前接收到的CStream的DP的数据负载已经被端点所接受。
ACK(CStream, NumP=0) – 如果设备对CStream没有Function Buffer可用,则设备应该发送一个NumP = 0的ACK TP给主机,退出DOMDSM,并转换进入Idle状态。这一转换允许设备在其Endpoint Buffer空间被耗尽时从Move Data状态退出。这个转换应该指示此前接收到的CStream的DP的数据负载已经被端点所接受。
NRDY(CStream) – 设备可以通过发送一个Stream ID设为CStream的NRDY来拒绝进一步的CStream transfers,并转换进入Idle状态,退出DOMDSM。设备可以在初始进入到DOMDSM时为拒绝HIMD,也可以在Stream transfer期间由于不可预期的内部情况而想要流程控制(flow control)CStream时,生成该转换。这个转换应该指示此前接收到的DP的数据负载已经被丢弃。
8.12.1.4.3.9 OUTMvData Host
在该状态,主机刚刚从设备处接收到此前一个DP的ACK TP,且还有更多给CStream的Endpoint Data。主机在该状态生成一个DP。管道也将在该状态的主机来的突发(bursts)之间等待(wait in this state between bursts from the host)。
DP(CStream, PP=1) – 如果设备接收到PP = 1的DP,则应该转换进入OUTMvData Device状态。DPP应该包含一个CStream数据负载。这是主机在它有为CStream多于Max Packet Size的Endpoint Data可用时的响应。
DP(CStream, PP=0) – 如果设备接收到PP = 0的DP,则应该转换进入OUTMvData Host Terminate状态。DPP应该包含一个CStream数据负载。这是主机在它已经耗尽为CStream的Endpoint Data时的响应。DP的长度将是小于或等于Max Packet Size。
DPH(Deferred) – 如果设备接收到Deferred (DF)标志被设置的DPH,则应该转换进入Idle状态,退出DOMDSM。当设备在等待从主机来的下一个DP时链路转换进入U1或U2,会收到这个包。没有跟deferred DPH相关联的DPP。
8.12.1.4.3.10 OUTMvData Host Terminate
进入这一状态是因为主机已经发送了CStream的最后一个可用DP,即它已经耗尽了其CStream Endpoint Data。设备在该状态
对来自主机的该Move Data transfer的上一个DP进行确认。
ACK(CStream, NumP=0) – 如果设备也耗尽了其Function Buffer空间,则它应该生成一个NumP = 0的ACK TP,并转换进入Idle状态,退出DOMDSM。
ACK(CStream, NumP>0) – 如果设备没有耗尽其Function Buffer空间,则它应该生成一个NumP > 0的ACK TP,并转换进入Idle状态,退出DOMDSM。由于这一转换,设备应该CStream将设为Not Ready。
ACK(CStream, NumP>0, Rty) – 如果设备在上一个DP中检测到错误,则它应该生成一个NumP > 0且Rty = 1的ACK TP,从而主机会重试上一个DP。设备应该接着转换进入OUTMvData Host状态。
NRDY(CStream) – 设备可以通过发送一个将Stream ID设为CStream的NRDY,且转换进入Idle状态,退出DOMDSM,来对上一个CStream transfer进行流程控制(flow control)。设备可以在由于不可预知的内部情况时想要对CStream进行流程控制(flow control)时生成这一转换。
8.12.1.4.4 主机输入流协议【Host IN Stream Protocol】
本节定义在IN Bulk端点上,使得主机端流协议(Stream Protocol)从一个状态转换到另一个状态的超高速包交换(SuperSpeed packet exchanges)。
在下文中,假设Host IN Stream状态转换发生在当主机发送与状态机相关的消息的第一个符号的第一个比特给设备时,或者当主机首次解码从主机来的状态机相关的消息时。对与IN管道,主机端的Endpoint Buffers接收来自设备的Function Data。
【勘误:上图中 "Stall or Error" 应该重命名为"Stall or Clear Feature Halt",去除timeout的情形。】
8.12.1.4.4.1 Disabled
在端口被配置后,管道状态处于Disabled状态,且LCStream被初始化为NoStream。
ACK(Prime, NumP>0, PP=0) – 当初始Endpoint Buffers被系统软件指派给管道时,主机应该发送Stream ID设置为Prime的ACK TP给设备,并将管道转换进入Prime Pipe状态。
8.12.1.4.4.2 Prime Pipe
Prime Pipe状态通知设备,已经有Endpoint Buffers被指派给一个或多个Streams。
NRDY(Prime) – 如果主机接收到一个Stream ID设为Prime的NRDY TP,则它应该转换到Idle状态。这一转换是Prime Pipe操作的正常终结。
ACK(Deferred) – 如果接收到Deferred (DF)标志被设置的ACK TP,则主机应该将管道转换进入Idle状态。当管道在等待指派其初始Endpoint Buffer时,链路已经转换进入U1或U2状态,会接收到这个包。例如,在Disabled状态在已经生成ACK(Prime, NumP>0, PP=0)之后,
ERDY() – 如果接收到ERDY,则发生了竞争条件。在此条件期间,设备处于Start Stream状态,而主机处于Prime Pipe状态。主机已经进入Prime Pipe状态来通知设备已经有一个或多个Streams的Endpoint Buffers被更新了,同时设备已经试图要发起一个Stream transfer,并且它们相应的消息也已经通过链路传递到对方。为了解决这一情况,主机应该保持在Prime Pipe状态,并等待设备发NRDY(Prime)。
8.12.1.4.4.3 Idle
在Idle状态,管道在等待一个Stream选择(Stream selection)(例如,到Start Stream或Move Data的一个转换),或者一个从主机来的通知,一个Stream Endpoint Buffer已经为该管道而被添加或修改(即,转换到Prime Pipe)。注意到在初始进入Idle时(从Disabled),只有设备可以发起一个Stream选择(Stream selection)。
ERDY(Stream n, NumP>0) – 如果接收到ERDY,主机应该转换到Start Stream状态。设备生成一个ERDY来选择一个特定的Stream (Stream n),期望主机在该Stream上开始IN事务。设备可以在它想要开始一次Stream transfer时发起这个转换,无论它是否此前对管道进行了流程控制(flow controlled)。注意ERDY NumP字段反映了设备为Stream n可用的Endpoint Data的数量。ERDY NumP字段的值对主机只有参考意义(informative),且设备用于Stream选择(Stream selection)的方法超出了本规范的范围,通常是由与管道相关的设备类所定义。当转换进入Start Stream状态,主机将LCStream设为Stream n。
ACK(Deferred) – 如果接收到Deferred (DF)标志被设置的ACK TP,主机应该保持在Idle状态。当主机拒绝了从设备来的Start Stream请求时(即,由于一个ACK( NoStream, NumP=0, PP=0))时,链路已经转换进入U1或U2状态,会接收到这个包。这一情况只在tERDYTimeout被超过时发生。
Stream x EP Buffer Change – 这一转换发生在一个或多个主机端的Endpoint Buffers改变时。主机评估(在连接"&"处)软件呈现给主机控制器的Stream的ID(Stream x),并转换进入Prime Pipe状态或Move Data状态。这是一个优化,允许主机直接将Stream管道转换进入Move Data状态,而不是通过Prime Pipe, Start Stream, Move Data序列,并且被称为Host Initiated Move Data,或者HIMD。用于做出这一决定的算法是特定于主机实现的。
&
ACK(Prime, NumP>0, PP=0) – 如果选择了转换进入Prime Pipe,则主机应该生成一个Stream ID = Prime, NumP > 0, 且 PP = 0的ACK TP,并转换到Prime Pipe状态。注意主机设置一个非零的NumP值,从而设备可以用NRDY做出响应。如果NumP = 0,设备可能会认为这是一个Terminating ACK,而不做出响应。典型地,当主机的Endpoint Buffers刚刚被修改过的Stream不是设备上次选择的Stream时,即Stream x != LCStream时,会选择Prime Pipe这一转换。
ACK(Stream x, NumP>0) – 如果选择了转换进入Move Data,则主机应该生成一个Stream ID = Stream x, NumP > 0的ACK TP,并转换到Move Data状态。当进入Move Data状态时,主机将CStream设为Stream x。典型地,当主机的Endpoint Buffers刚刚被修改过的Stream是设备上次选择的Stream时,即Stream x = LCStream时,会选择Move Data这一转换。PP应该等于1,因为主机能够从设备接收另一个DP。这一转换可选地可以在某些主机中被禁止,且有些设备类可能不会处理这一转换(例如,Mass Storage UASP)。
8.12.1.4.4.4 Start Stream
在Start Stream状态,设备已经发送了一个ERDY给主机,建议其发起一个对Stream n的IN transfer,且设备正在等待主机接受或拒绝设备建议的Stream selection。
ACK(Stream n, NumP>0) – 如果主机已经接受了设备提出的开始Stream n的建议,则它应该发送一个Stream ID等于Stream n的ACK TP,并转换进入Move Data状态。当转换到Move Data状态的时候,主机将CStream设置成Stream n。如果有Endpoint Buffers可用来接收从来Stream的Function Data,则主机应该接受设备的Stream proposal。PP应该等于1,因为主机能够从设备接收另一个DP。
ACK(NoStream, NumP=0, PP = 0) – 如果主机已经拒绝了设备提出的开始Stream n的建议,则它应该发送一个Stream ID等于NoStream的ACK TP,并转换进入Idle状态。如果没有有Endpoint Buffers可用来接收从来Stream的Function Data,则主机应该拒绝设备的Stream proposal。
8.12.1.4.4.5 Move Data
在Host IN Move Data状态,CStream在管道的两端都设为相同值,且管道可以积极搬运数据。在Move Data状态所执行的总线事务的详情以及它的退出条件在Host IN Move Data State Machine中定义。
【勘误:上图中的INMvData Device Terminate到退出的转换的动作标签ACK(CStream, NumP=0, PP = 0),应该改为ACK(CStream, NumP=0)。这是为了覆盖到"主机还有更多缓冲空间可用,而设备已终结了这个突发"的情形。】
【勘误:Rty可以跨多个突发。
去掉从INMvData Burst End到exit的ACK(Deferred)转换。
添加从INMvData Device Terminate到INMvData Burst End的ACK(CStream, NumP=0, PP=1, Rty)转换。
因此,上面的状态机图可以用下面的状态机图替换。为对比起见,先保留原图,并将修改后的状态机图附于下面。
】
Host IN Move Data State Machine (HIMDSM)是从上面描述的Start Stream或Idle状态进入的。一旦进入HIMDSM,立即就转换进入INMvData Device状态。HIMDSM允许设备由于耗尽与Stream相关的Function Data而终结Move Data操作,也允许主机因耗尽与Stream相关的Endpoint Buffer空间而终结Move Data操作。
HIMDSM总是退出到Idle状态。Retry (Rty=1) 标志在导致HIMDSM退出的包中绝不该设置。Stream管道在包重试期间保持在Move Data状态。
注意:在Move Data状态期间所交换的所有包的Stream ID值都应该是CStream,除了INMvData Device子状态的ERDY转换。对于已识别的(identified)子状态,如果在HIMDSM期间检测到Stream ID值不是CStream,设备应该halt端点。
注意:如果在初始进入Move Data状态时CStream不是Active的,则设备可以使用设备类定义的NRDY或STALL拒绝该Stream建议。
8.12.1.4.4.6 INMvData Device
这一状态初始是从Start Stream状态或Idle状态进入的。在该状态主机等待从设备来的DP,或者设备拒绝HIMD。
DP(CStream, EOB=0) – 如果主机接收到一个EOB = 0的DP,它应该将DP的数据拷贝到与Stream相关联的Endpoint Buffer中,并转换进入INMvData Host状态。DPP应该包含CStream的数据负载。这一转换发生在设备返回IN数据,且还有更多Function Data要发送时。当转换进入INMvData Host状态时,主机将LCStream设为CStream的值。如果设备接受HIMD,这一动作使用CStream更新LCStream,也即LCStream记录设备感兴趣的上一个Stream。
DP(CStream, EOB=1) – 如果主机接收到一个EOB = 1的DP,它应该将DP的数据拷贝到与Stream相关联的Endpoint Buffer中,并转换进入INMvData Device Terminate状态。DPP应该包含CStream的数据负载。这一转换发生在设备返回IN数据,且没有更多Function Data要发送时。当转换进入INMvData Device Terminate状态时,主机将LCStream设为CStream的值。如果设备接受HIMD,这一动作使用CStream更新LCStream,也即LCStream记录设备感兴趣的上一个Stream。
NRDY(CStream) – 如果主机接收到一个NRDY,它应该退出HIMDSM,并转换进入Idle状态。主机可以在初始进入到HIMDSM时因为设备拒绝了HIMD,也可以在Stream transfer期间由于不可预期的设备内部情况而想要流程控制(flow control)CStream时, 可以生成该转换。
ACK(Deferred) – 如果主机接收到一个Deferred (DF)被设置的ACK TP,则它应该退出HIMDSM,并转换进入Idle状态。当在主机和设备之间的一段链路转换进入U1或U2状态时,会接收到这个包。有2中情况可能发生这一转换:1)主机已经尝试了一个HIMD,以及2)在突发之间(between bursts)。如果在为Stream获取缓冲时有一个较长的主机时延(long host delay), 则情况1很可能(likely)发生。如果在其他设备上有许多端点活动而延迟了突发之间的时间(delaying the time between bursts), 则情况2可能(may)发生。设备将这个转换像Prime Pipe一样对待,将会在当它接收到从集线器转发给它的Deferred ACK时,发送一个ERDY来重启(restart)这个Stream。【已勘误,去掉了一种情况。】
ERDY() – 如果接收到了一个ERDY,则发生了竞争条件。在此情况期间,设备处于Start Stream状态,而主机处于Move Data状态。主机由于一个HIMD而进入了Move Data状态,同时设备已经试图发起一个Stream transfer,且它们相关的消息也已经通过链路传送到对方。为了解决这一情况,主机应该保持在INMvData Device状态,等待从设备发来一个DP或者NRDY。
8.12.1.4.4.7 INMvData Host
在该状态,主机已经接收到一个从设备来的DP,且设备还有更多给CStream的Function Data。主机在将接收到的数据拷贝与该Stream相关联的Endpoint Buffer空间后,响应一个对上一DP的确认。
ACK(CStream, NumP>0, PP=1) – 如果有更多的给该Stream的Endpoint Buffer空间可用,且主机在继续到设备的当前突发(current burst),则主机应该生成一个NumP > 0且PP = 1的ACK TP,并转换进入INMvData Device状态。如果主机检测到设备来的上一个DP中有错误,则Rty标志应该被设置。主机可以(may)继续INMvData Host到INMvData Device的循环,直到所有的重试都耗尽,或者从设备收到一个好包。
ACK(CStream, NumP=0, PP=1) – 如果有更多的给该Stream的Endpoint Buffer空间可用,但是主机必须终止到设备的当前突发(current burst),则主机应该生成一个NumP = 0 且 PP = 1的ACK TP,并转换进入INMvData Burst End状态。如果主机检测到从设备来的上一个DP有错误,则Rty标志应该被设置。
ACK(CStream, NumP=0, PP=0) – 如果主机在接收到的上一个DP中没有检测到错误,且已经耗尽了Stream的Endpoint Buffer空间,则这主机应该生成一个NumP = 0 且 PP = 0的ACK TP,并转换进入Idle状态,退出HIMDSM。该转换通知设备主机已经耗尽了Stream的Endpoint Buffer空间。这一转换通知设备,主机已经耗尽该Stream的Endpoint Buffer空间。
8.12.1.4.4.8 INMvData Burst End
进入该状态是因为主机已经终结了该Stream管道上的一个突发。当主机准备好开始另一个突发时它就会退出该状态。如果这个状态是还在重试时【retrying (Rty =1)】进入的,那么当退出该状态时主机应该在端点类型的限制内继续重试过程。
ACK(CStream, NumP>0, PP=1) – 当主机准备好对设备开始在CStream上的另一个突发时,主机应该生成一个NumP > 0 且 PP = 1的ACK TP,并转换进入INMvData Device状态。注意,如果在进入该状态时Rty标志是被设置的,则在退出时也应该被设置。
8.12.1.4.4.9 INMvData Device Terminate
在该状态,主机已经接收到从设备来的对该Move Data操作的最后一个DP,因为设备已经耗尽了它对CStream的可用Function Data。主机在将接收到的数据拷贝到与该Stream相关联的Endpoint Buffer空间后,响应一个确认,并退出HIMDSM。如果从设备接收到的DP是坏的,则在端点类型的限制内,重试可以被执行。
ACK(CStream, NumP=0, No Rty) – 如果从设备接收到的DP是好包,则主机生成一个NumP = 0且Rty = 0的ACK TP,并转换进入Idle状态,退出HIMDSM。【已勘误,去掉了PP=0这个参数值】【译注:这里,覆盖了"主机还有更多缓冲空间可用,而设备已终结了这个突发"的情形。】
ACK(CStream, NumP>0, PP=1, Rty) – 如果从设备接收到DP是坏包,且当前突发(current burst)尚未完成,则主机应该生成一个NumP > 0, PP = 1 且 Rty = 1的ACK TP,并转换进入INMvData Device状态。主机可以(may)继续INMvData Device Terminate到INMvData Device的循环,直到所有的重试都耗尽,或者收到一个好包。
ACK(CStream, NumP=0, PP=1, Rty) – 如果从设备接收到DP是坏包,且当前突发(current burst)已经完成,则主机应该生成一个NumP = 0, PP = 1 且 Rty = 1的ACK TP,并转换进入INMvData Burst End状态。主机应该在下一个突发中继续重试过程。
8.12.1.4.5 主机输出流协议【Host OUT Stream Protocol】
本节定义在OUT Bulk端点上,使得主机端流协议(Stream Protocol)从一个状态转换到另一个状态的超高速包交换(SuperSpeed packet exchanges)。
在下文中,假设Host OUT Stream状态转换发生在当主机发送与状态机相关的消息的第一个符号的第一个比特给设备时,或者当主机首次解码从设备来的状态机相关的消息时。对与OUT管道,设备端的Function Buffers接收来自主机端的Endpoint Data。
【勘误:上图中 "Stall or Error" 应该重命名为"Stall or Clear Feature Halt",去除timeout的情形。】
8.12.1.4.5.1 Disabled
在端口被配置后,管道状态处于Disabled状态,且LCStream被初始化为NoStream。
DP(Prime, PP=0) – 当初始Endpoint Data被系统软件指派给管道时,主机应该发送Stream ID设置为Prime的零长DP(zero-length DP)给设备,并将管道转换进入Prime Pipe状态。DPP应该包含零长数据负载(zero-length data payload)。
8.12.1.4.5.2 Prime Pipe
Prime Pipe状态通知设备,已经有Endpoint Buffers被指派给一个或多个Streams。注意,这一状态是当主机从Disabled状态或者Idle状态传送一个DP(Prime)时进入的。如果设备在该DP数据中检测到错误,则设备应该发送ACK(Prime, NumP>0, Rty)包,重试,直到成功接收到DP(Prime)。主机可以(may)重传DP(Prime),并保持在Prime Pipe状态,直到设备成功接收到DP(Prime)并返回一个NRDY(Prime),或者直到管道的重试被耗尽从而主机停止(halts)该管道。【已勘误,原文档说主机"应该(shall)"继续当前事务,现在更正为"可以(may)"。这简化了主机的行为,并且去除了因为要等待其他端点请求多次重试而使得周期性传输遭受饥饿(starved)的情形。此外,核心规范并没有重试次数的限制(一般来说是3次)。】这一情况没在上图中显示。
NRDY(Prime) – 如果主机接收到一个Stream ID 设为Prime的NRDY TP,它应该转换到Idle状态。这一转换是Prime Pipe操作的正常终结。
DPH(Deferred) – 如果接收到Deferred (DF)标志被置位的DPH,则主机应该转换到Idle状态。当管道在等待其被指派其初始Endpoint Buffer时,如果链路转换进入了U1或U2状态,会收到该包。例如,在Disabled状态时,生成DP(Prime, PP=0)之后。没有DPP与deferred DPH相关联。
ERDY() – 如果接收到ERDY,则发生了竞争情况。在此情形下,设备处于Start Stream状态,而主机处于Prime Pipe状态。主机进入状态,通知设备一个或多个Streams的Endpoint Buffers已经被更新,同时设备也尝试发起一个Stream transfer,且他们相关的消息也已经通过链路传递给对方。为了解决这一情况,主机应该保持在Prime Pipe状态,并等待从设备发来一个NRDY。
8.12.1.4.5.3 Idle
在Idle状态,管道在等待一个Stream选择(Stream selection)(例如,到Start Stream或Move Data的一个转换),或者一个从主机来的通知,Stream Endpoint Data已经为该管道而被添加或修改(即,转换到Prime Pipe)。注意到在初始进入Idle时(从Disabled),只有设备可以发起一个Stream选择(Stream selection)。
ERDY(Stream n, NumP>0) – 如果接收到ERDY,主机应该转换到Start Stream状态。设备生成一个ERDY来选择一个特定的Stream (Stream n),期望主机在该Stream上开始OUT事务。设备可以在它想要开始一次Stream transfer时发起这个转换,无论它是否此前对管道进行了流程控制(flow controlled)。注意ERDY NumP字段反映了设备为Stream n可用的Endpoint Buffer空间的数量设备用于Stream选择(Stream selection)的方法超出了本规范的范围,通常是由与管道相关的设备类所定义。当转换进入Start Stream状态,主机将LCStream设为Stream n。
Stream x EP Buffer Change – 这一转换发生在主机端的一个或多个Streams的Endpoint Data被提交时(posted)。主机评估(在连接"&"处)软件呈现给主机控制器的Stream的ID(Stream x),并转换进入Prime Pipe状态或Move Data状态。这是一个优化,允许主机直接将Stream管道转换进入Move Data状态,而不是通过Prime Pipe, Start Stream, Move Data序列,并且被称为Host Initiated Move Data,或者HIMD。用于做出这一决定的算法是特定于主机实现的。
&
DP(Prime, PP=0) – 如果选择了转换进入Prime Pipe,则主机应该生成一个Stream ID = Prime,且 PP = 0的DP,并转换到Prime Pipe状态。DPP应该包含零长数据负载(zero-length data payload)。典型地,当主机的Endpoint Data刚刚被修改过的Stream不是设备上次选择的Stream时,即Stream x != LCStream时,会选择Prime Pipe这一转换。
DP(Stream x) – 如果选择了转换进入Move Data,则主机应该生成一个Stream ID = Stream x的DP,并转换到Move Data状态。当进入Move Data状态时,主机将CStream设为Stream x。DPP应该包含CStream的第一个数据负载。典型地,当主机的Endpoint Data刚刚被修改过的Stream是设备上次选择的Stream时,即Stream x = LCStream时,会选择Move Data这一转换。如果主机具有超过Max Packet Size的Endpoint Data对该Stream可用,则PP = 1,否则PP = 0。该转换可以可选地被某些主机禁用,且某些设备类可能不会出来该转换(例如,Mass Storage UASP)。
8.12.1.4.5.4 Start Stream
在Start Stream状态,设备已经发送了一个ERDY,建议主机发起一个对Stream n的OUT transfer,且设备正在等待主机接受或拒绝该Stream选择(Stream selection)。
DP(Stream n) – 如果主机已经接受了设备提出的开始Stream n的建议,则它应该发送一个Stream ID等于Stream n的DP,并转换进入Move Data状态。当转换到Move Data状态的时候,主机应该将CStream设置成Stream n。DPP应该包含CStream的第一个数据负载。主机应该在对Stream有Endpoint Data可用时接受设备的Stream建议(Stream proposal)。
DP(NoStream, PP=0) – 如果主机已经拒绝了设备提出的开始Stream n的建议,则它应该发送一个Stream ID等于NoStream的DP,并转换进入Start Stream End状态。DPP应该包含一个零长(zero-length)数据负载。如果没有给Stream的Endpoint Data,则主机应该拒绝从设备来的建议。
8.12.1.4.5.5 Start Stream End
在Start Stream End状态,主机已经拒绝了设备提出的Stream ID的建议,因为对Stream n没有Endpoint Data可用。注意,这一状态是当主机从Start Stream状态发送一个DP(NoStream)时进入的。如果设备在该DP数据中检测到错误,则设备应该发送ACK(NoStream, NumP>0, Rty)包,重试,直到成功接收到DP(NoStream)。主机可以(may)重传DP(NoStream),并应该保持在Start Stream End状态,直到设备成功接收到DP(NoStream)并返回NRDY(NoStream),或者直到管道的重试被耗尽从而主机停止(halts)该管道。【已勘误,原文档说主机"应该(shall)"继续当前事务,现在更正为"可以(may)"。这简化了主机的行为,并且去除了因为要等待其他端点请求多次重试而使得周期性传输遭受饥饿(starved)的情形。此外,核心规范并没有重试次数的限制(一般来说是3次)。】这一情况没在上图中显示。
NRDY(NoStream) – 如果接收到一个Stream ID等于NoStream的NRDY,则主机应该转换到Idle状态。
DPH(Deferred) – 如果接收到Deferred (DF)标志被置位的DPH,则主机应该转换到Idle状态。当等待主机对Start Stream的响应时,如果链路转换进入了U1或U2状态,会收到该包。注意,这一转换只有在tERDYTimeout被超过时可能发生。没有DPP与deferred DPH相关联。
8.12.1.4.5.6 Move Data
在Host OUT Move Data状态,CStream在管道的两端都设为相同值,且管道可以积极搬运数据。在Move Data状态所执行的总线事务的详情以及它的退出条件在Host OUT Move Data State Machine中定义。
【勘误:上图中,应该在从OUTMvData Host Terminate状态出来的下列弧线(arc)的标签上添加LCStream = CStream:标有ACK(CStream,NumP=0)弧线,标有ACK(CStream,NumP>0,No Rty)的弧线,标有ACK(CStream,NumP>0,Rty)的弧线。这是为了在由于一个Host Initiated Move Data通过PP=0的DP而发生时,使得LCStream仍然能够得到更新。】
Host OUT Move Data State Machine (DOMDSM)是从上面描述的Start Stream或Idle状态进入的。进入HOMDSM将立即转换进入OUTMvData Device状态。HOMDSM允许设备由于耗尽与Stream相关的Endpoint Data而终结Move Data操作,也允许主机因耗尽与Stream相关的Function Buffer而终结Move Data操作。
PP=0 – 在进入HOMDSM时,如果主机只有Stream的一个包的Endpoint Data可用,则PP应该在设备接收到的第一个DP中等于0,且它将转换进入OUTMvData Device Terminate状态。
PP = 1 – 在进入HOMDSM时,如果主机有Stream的多于一个包的Endpoint Data可用,则PP应该在设备接收到的第一个DP中等于1,且它将转换进入OUTMvData Device状态。
HOMDSM总是退出到Idle状态。Retry (Rty=1) 标志在导致HOMDSM退出的包中绝不该设置。Stream管道在包重试期间保持在Move Data状态。
注意:在Move Data状态期间所交换,除了OUTMvData Device状态下的ERDY转换,所有包的Stream ID值都应该是CStream。如果在HOMDSM期间检测到Stream ID值不是CStream,设备应该halt端点。
8.12.1.4.5.7 OUTMvData Device
这一状态初始是从Start Stream状态或Idle状态进入的。在该状态主机等待设备发送一个ACK TP,或者从设备来的对HIMD的拒绝。
ACK(CStream, NumP>0) – 如果主机接收到一个NumP > 0的ACK TP,则它应该转换进入OUTMvData Host状态。这一转换在当设备对该Stream有更多可用的Function Buffer空间时发生。如果设备在从主机来的最后一个DP中检测到错误,则Retry (Rty)标志应该被设置。如果需要重试,则主机可以(may)继续当前突发(current burst)直到所有的重试都耗尽,或者传送了一个好包。如果在主机不能继续当前突发(current burst)的情况下,主机将会在该端点类型限制内的下一个可用机会时回到该端点。【已勘误,原文档说主机"应该(shall)"继续当前突发,现在更正为"可以(may)"。这简化了主机的行为,并且去除了因为要等待其他端点请求多次重试而使得周期性传输遭受饥饿(starved)的情形。此外,核心规范并没有重试次数的限制(一般来说是3次)。】主机应该设置LCStream = CStream。如果设备接受一个HIMD,则这一动作用Stream x的值来更新LCStream,即,LCStream记录了设备上一次感兴趣的Stream。
ACK(CStream, NumP=0) – 如果主机接收到一个NumP = 0的ACK TP,则它应该转换进入Idle状态,退出HOMDSM。这一转换在当设备对该Stream没有更多可用的Function Buffer空间时发生,即,它药终结该Move Data操作,因为上一个DP耗尽了其Function Buffer空间。主机应该设置LCStream = CStream。如果设备接受一个HIMD,则这一动作用Stream x的值来更新LCStream,即,LCStream记录了设备上一次感兴趣的Stream。
NRDY(CStream) – 如果主机接收到NRDY,则它应该转换到Idle状态,退出HOMDSM。这一转换可能在当最初进入HOMDSM时就由于设备拒绝该HIMD而发生,或者在一个Stream transfer期间由于不期望的设备内部情况而导致设备想要流程控制(flow control)该CStream时而发生。
DPH(Deferred) – 如果主机接收到Deferred (DF) 标志被设置的DPH,则它应该转换到Idle状态,退出HOMDSM。当链路已经转换进入U1或者U2状态且主机已经尝试了一个HIMD,或者在OUT管道的突发之间(between bursts),如果在其他设备(other devices)上有许多端点活动且到这个设备(other devices)的路径上的Ux Timeouts被设置为较短的值时,可能会接收到这个包。当发生该转换时,主机将在Idle状态等待从设备发来一个ERDY来重启该Stream。没有DPP与deferred DPH相关联。
ERDY() – 如果接收到ERDY,则发生了竞争情况。在此情形下,设备处于Start Stream状态,而主机处于Move Data状态。主机由于HIMD的结果而进入Move Data状态,同时设备也尝试发起一个Stream transfer,且他们相关的消息也已经通过链路传递给对方。为了解决这一情况,主机应该保持在OUTMvData Device状态,并等待从设备发来一个ACK或者NRDY。
8.12.1.4.5.8 OUTMvData Host
在该状态,主机已经从设备处接收到一个ACK TP,且设备还有更多给CStream的Function Buffer空间可用。主机在该状态生成一个DP,包含与该Stream相关联的Endpoint Data。管道也将在该状态的主机来的突发(bursts)之间等待(wait in this state between bursts from the host)。注意,DP重试过程可能跨越多个突发(DP retry process may span bursts)。
DP(CStream, PP=1) – 如果具有为该Stream的更多Endpoint Data可用,且主机正在继续到设备的当前突发(current burst),则主机应该生成一个PP = 1的DP,并转换到OUTMvData Device状态。DPP应该包含一个CStream的数据负载。如果在从设备来的上一个ACK中的Rty标志被设置了,则主机应该重发恰当的DP,直到所有的重试都被耗尽,或者一个好DP为设备所确认(接收到好包)。
DP(CStream, PP=0) – 如果发送这个DP耗尽了该Stream的可用Endpoint Data,则主机应该生成一个PP = 0的DP,并转换到OUTMvData Host Terminate状态。DPP应该包含一个CStream的数据负载。这个转换通知设备主机已经耗尽了该Stream的可用Endpoint Data。
8.12.1.4.5.9 OUTMvData Host Terminate
在该状态,主机已经耗尽了其CStream的可用Endpoint Data,且发送了该Stream的最后一个DP。主机在等待对这个Stream的最后一个DP进行确认。
ACK(CStream, NumP=0) – 如果主机接收到一个NumP = 0 且 Rty = 0的ACK TP,则主机应该转换进入Idle状态,退出HOMDSM。这一转换发生在设备成功接收到上一个DP,且主机和设备同时都耗尽了他们的相应Endpoint Data和Function Buffer空间。
ACK(CStream, NumP>0, No Rty) – 如果主机接收到一个NumP > 0, PP = 0, 且 Rty = 0的ACK TP,则主机应该转换进入Idle状态,退出HOMDSM。这一转换发生在设备已经成功接收到上一个DP,且主机耗尽了其对CStream的Endpoint Data,但是设备仍然还有更多的Function Buffer空间可用时。
ACK(CStream, NumP>0, Rty) –如果主机接收到一个NumP > 0 且 Rty = 1的ACK TP,则主机应该转换进入OUTMvData Host状态并重新发送恰当的DP。这一转换发生在设备接收到的上一个包是坏包,从而需要Retry时。主机应该继续OUTMvData Host Terminate到OUTMvData Host的循环,直到所有的重试都被耗尽,或者一个好DP为设备所确认(接收到好包)。
NRDY(CStream) – 如果主机接收到一个NRDY,则主机应该转换进入Idle状态,退出HOMDSM。这一转换可能发生在一个Stream transfer期间,由于不期望的设备内部情况而导致设备想要流程控制(flow control)该CStream时而发生。
DPH(Deferred) – 如果主机接收到Deferred (DF) 标志被设置的DPH,则它应该转换到Idle状态,退出HOMDSM。如果在最后一个DP被主机发送之前,链路已经转换进入U1或者U2状态,会接收到这个包。没有DPP与deferred DPH相关联。
8.12.1.4.6 批量输入流协议 【Bulk IN Stream Protocol】
【译注:本节为勘误之前原始文档第8.12.1.4.2节译文。勘误改动较大,但仅仅是为了阐述得更清晰,实际协议流程与原文一致,且原文被xHCI规范引用,故译文在勘误之后保留了原文的译文且新立章节,供参考。】
本节定义在输入方向批量端点上,使得流协议从一个状态转换到另一个状态的SuperSpeed包交换。
对于输入管道,主机端的端点缓冲区(Endpoint Buffers)接收从设备发来的功能数据(Function Data)。
在端点被配置之后,管道进入Disabled状态。主机应该通过发送Stream ID字段设置为Prime的ACK TP来将管道转换到Prime Pipe状态。这一转换在端点缓冲区被系统软件指派给管道之后发生。
设备应该通过发送Stream ID 字段设置为Prime的NRDY TP来促使管道从Prime Pipe状态退出,并转换到Idle状态。
注意:如果中间的集线器推后了ACK TP,主机和设备应该就像设备已经发送了一个NRDY TP那样来工作。也就是说,主机应该在接收到推后的响应(Deferred Response)时转换到Idle状态。设备应该在接收到推后的ACK TP(Deferred ACK TP)时转换到Prime Pipe状态,并接着马上转换到Idle状态,就像它已经发送了Stream ID字段设置为Prime的NRDY TP。
在Idle状态,管道在等待流选择(Stream selection)(例如,转换到Start Stream 或者 Move Data),或者从主机获得通知,告知已经对该管道添加了或者修改了一个端点缓冲区(转换到Prime Pipe)。在Idle状态,由主机发起的流选择(Stream selection)被Stream ID设置为Stream n并且NumP值> 0的ACK TP所标识。这个包应该将ISPSM从Idle状态转换到Move Data状态。如果上一个转换是从Start Stream 或者 Move Data过来,那么主机应该发起从Idle到Move Data的转换,基于两个可能的情形:1)如果指定给管道的端点缓冲区(Endpoint Buffer)此前服务于LCStream,并且上一次ISPSM转换并不是因为NRDY(Stream n) 从Move Data退出;或者 2)如果端点缓冲区被指定给一个新的流(也就是,新制定的SID不等于LCStream)。在Idle状态, 由设备发起的流选择(Stream selection)被Stream ID设置为Stream n并且NumP值> 0的ERDY TP所标识。这个包应该将ISPSM从Idle状态转换到Start Stream状态。不论设备是否处于流程控制条件下,当它希望开始一次流传输时,设备就应该发起这一转换。
在Start Stream状态,管道在等待主机接受或者拒绝由设备提议的流选择(Stream selection)。主机应该通过发送具有如下设置的ACK TP,来指示对设备发起的流选择(Stream selection)的认可:Stream ID = Stream n 并且 NumP > 0。这个包应该将ISPSM从Start Stream状态转换到Move Data状态。主机应该通过发送具有如下设置的ACK TP,来指示对设备发起的流选择(Stream selection)的拒绝:Stream ID = NoStream, NumP = 0, 并且Packet Pending (PP) = 0。这个包应该将ISPSM从Start Stream状态转换到Idle状态。如果没有端点缓冲区可用时,主机应该拒绝设备选择的SID。
ISPSM在主机和设备上独立地执行。在主机发送一个ACK(Prime,PP=0)到设备,并进入Prime Pipe状态的同时,如果设备发送了一个ERDY给主机,并进入Start Stream状态的话,就产生了条件竞争(race condition)。为了从这个条件下恢复,如果设备在Start Stream状态接收到一个ACK(Prime,PP=0),它应该转换到Prime Pipe Ack状态,并且发送一个NRDY(Prime)给主机,来完成主机从Prime Pipe到Idle的转换,以及设备从Prime Pipe Ack到Idle的转换。
在Move Data状态,CStream在主机和设备两端都被设置,并且管道正在积极地搬运数据到主机。在Move Data状态中执行的总线事务的详情以及其退出条件,在下面定义的IN Move Data State Machine中被定义。
如上所述,输入搬移数据状态机【IN Move Data State Machine (IMDSM)】从Start Stream 或者 Idle 状态进入。进入IMDSM后立刻转换到INMvData Device状态。IMDSM 生成的所有包的Stream ID字段都应该是Stream n。每当进入INMvData Device状态,设备执行如下动作来使IMDSM推进:
if (设备功能数据字节数 > 最大包大小)
设备应该生成EOB字段= 0的数据包DP,这样就促使管道转移到INMvData Host状态。
else if (设备功能数据字节数 = 最大包大小)
设备应该生成EOB字段= 1的数据包DP,这样就促使管道转移到INMvData Device Terminate状态。
else (设备功能数据字节数 < 最大包大小)
设备应该生成一个短包数据包DP,这样就促使管道转移到INMvData Device Terminate状态。
可选地,设备可能生成一个Stream ID设置为Stream n的NRDY TP,这样就终结该流,并将管道退出IMDSM而转移到Idle状态。设备可能使用该转换来拒绝主机发起的数据搬移请求(Host Initiated Move Data)。
注意:如果中间的集线器推后了ACK TP,主机和设备应该就像设备已经发送了一个NRDY TP那样来工作。也就是说,主机应该在接收到推后的响应(Deferred Response)时转换到Idle状态。设备应该在接收到推后的ACK TP(Deferred ACK TP)时退出IMDSM并转换到Idle状态,就像它已经发送了Stream ID字段设置为Stream n的NRDY TP。如果设备接受主机发起的Stream ID,它应该发送一个Stream ID字段设置为Stream n的ERDY。如果设备拒绝主机发起的Stream ID,它应该呆在Idle状态并等待下一个要么从主机要么从设备来的流选择(Stream selection)。
INMvData Host状态由于设备有更多数据要发送而进入,因此主机执行如下动作来使IMDSM推进:
if (在本次突发中可以再调度令一个数据包DP)
if (主机有更多的端点缓冲区空间可用)
生成NumP > 0的ACK TP,这样就促使管道转换到INMvData Device状态。
else (主机已经用完端点缓冲区空间)
生成NumP = 0 且 PP = 0的完结ACK TP,这样就促使管道退出IMDSM并转换到Idle状态。
else (收到本次突发的最后一个数据包DP)
终结本次突发。
if (主机有更多的端点缓冲区空间可用)
通知设备本次突发完成(NumP = 0),且CStream的下一次突发应该由主机调度(PP = 1)。生成NumP = 0 且 PP = 1的ACK TP,并促使管道转换到INMvData Burst End状态。
else (主机已经用完端点缓冲区空间)
生成NumP = 0 且 PP = 0的完结ACK TP,这样就促使管道退出IMDSM并转换到Idle状态。
在INMvData Burst End状态,主机应该生成NumP = 0 且 PP = 1的ACK TP,来发起下一次突发(burst),并并促使管道转换到INMvData Device状态。
上述描述IMDSM的伪代码假设接收到的数据包DP是有效的。如果其无效,应该生成ACK TP,将管道转换到INMvData Device状态。ACK TP中的序列号(Sequence Number)不应该改变(推进),但是,retry可能递减被传输的NumP值。如果NumP = 0且主机还有端点缓冲区可用,PP应该被设为1;否则,PP被设为0。
INMvData Device Terminate状态由于设备没有更多的功能数据发送,因此主机应该生成NumP = 0 且 PP = 0的终结ACK TP,从而促使管道退出IMDSM并转换到Idle状态。如果主机检测到设备发送的上一个数据包DP的错误,它应该用Retry ACK TP (Steam n, NumP>0, Rty)来响应,并且IMDSM应该转换到INMvData Device状态。
注意:如果一个数据包DP错误在INMvData Host状态被检测到,主机应该生成一个NumP > 0 且 Rty = 1的ACK TP,从而促使管道转换到INMvData Device状态并重新发送该包。
8.12.1.4.7 批量输出流协议 【Bulk OUT Stream Protocol】
【译注:本节为勘误之前原始文档第8.12.1.4.3节译文。勘误改动较大,但仅仅是为了阐述得更清晰,实际协议流程与原文一致,且原文被xHCI规范引用,故译文在勘误之后保留了原文的译文且新立章节,供参考。】
本节定义在输出方向批量端点上,使得流协议从一个状态转换到另一个状态的SuperSpeed包交换。
对于输出管道,主机端的端点数据(Endpoint Data)被传输到设备发的功能数据缓冲(Function Buffers)。除非另有指出,数据包DP将包括端点数据(Endpoint Data)。
在端点被配置之后,管道进入Disabled状态。主机应该通过发送Stream ID字段设置为Prime的ACK TP来将管道转换到Prime Pipe状态。这一转换在端点缓冲区被系统软件指派给管道之后发生。
设备应该通过发送Stream ID 字段设置为Prime的NRDY TP来促使管道从Prime Pipe状态退出,并转换到Idle状态。
在端点被配置之后,管道进入Disabled状态。主机应该通过发送Stream ID字段设置为Prime的ACK TP来将管道转换到Prime Pipe状态。这一转换在端点缓冲区被系统软件指派给管道之后发生。
设备应该通过发送Stream ID字段设置为Prime的NRDY TP来促使管道从Prime Pipe状态退出,并转换到Idle状态。
注意:如果中间的集线器推后了数据包DP,主机和设备应该就像设备发送了一个NRDY TP那样来工作。也就是说,主机应该在接收到推后的响应(Deferred Response)时转换到Idle状态。设备应该在接收到推后的数据包头(Deferred DPH)时转换到Prime Pipe状态,并接着马上转换到Idle状态,就像它已经发送了Stream ID字段设置为Prime的NRDY TP。
在Idle状态,管道在等待流选择(Stream selection)(例如,转换到Start Stream 或者 Move Data),或者从主机获得通知,告知已经对该管道添加了或者修改了端点数据(Endpoint Data)(转换到Prime Pipe)。在Idle状态,由主机发起的流选择(Stream selection)被Stream ID设置为Stream n的数据包DP所标识。PP的值取决于主机是否有一个(PP = 0)或者多个(PP = 1)数据包要发送。这个包应该将OSPSM从Idle状态转换到Move Data状态。如果上一个转换是从Start Stream 或者 Move Data过来,那么主机应该发起从Idle到Move Data的转换,基于两个可能的情形:1)如果指定给管道的端点缓冲区(Endpoint Buffer)此前服务于LCStream,并且上一次OSPSM转换并不是因为NRDY(Stream n) 从Move Data退出;或者 2)如果端点缓冲区被指定给一个新的流。在Idle状态, 由设备发起的流选择(Stream selection)被Stream ID设置为Stream n并且NumP值> 0的ERDY TP所标识。这个包应该将OSPSM从Idle状态转换到Start Stream状态。不论设备是否处于流程控制条件下,当它希望开始一次流传输时,设备就应该发起这一转换。
在Start Stream状态,管道在等待主机接受或者拒绝由设备提议的流选择(Stream selection)。主机应该通过发送具有如下设置的数据包DP,来指示对设备发起的流选择(Stream selection)的认可:Stream ID = Stream n。PP的值取决于主机是否有一个(PP = 0)或者多个(PP = 1)数据包要发送。这个包应该将OSPSM从Start Stream状态转换到Move Data状态。主机应该通过发送具有如下设置的数据包DP,来指示对设备发起的流选择(Stream selection)的拒绝:Length = 0, Stream ID = NoStream 且 PP = 0。这个包应该将OSPSM从Start Stream状态转换到Start Stream End状态。如果没有端点数据缓冲区可用时,主机应该拒绝设备选择的SID。
OSPSM在主机和设备上独立地执行。在主机发送一个DP(Prime,PP=0)到设备,并进入Prime Pipe状态的同时,如果设备发送了一个ERDY给主机,并进入Start Stream状态的话,就产生了条件竞争(race condition)。为了从这个条件下恢复,如果设备在Start Stream状态接收到一个DP(Prime,PP=0),它应该转换到Prime Pipe Ack状态,并且发送一个NRDY(Prime)给主机,来完成主机从Prime Pipe到Idle的转换,以及设备从Prime Pipe Ack到Idle的转换。
Start Stream End状态是一个当(流)选择被拒绝时,从Start Stream状态退出的中间状态。设备应该总是通过发送Stream ID = NoStream的NRDY TP,强制转换到Idle状态。这一转换履行了设备必须响应主机发来的数据包的要求。
在Move Data状态,CStream在主机和设备两端都被设置,并且管道正在积极地搬运数据到设备。在Move Data状态中执行的总线事务的详情以及其退出条件,在下面定义的OUT Move Data State Machine中被定义。
如上所述,输出搬移数据状态机【OUT Move Data State Machine (OMDSM)】从Start Stream 或者 Idle 状态进入。进入IMDSM后立刻转换到INMvData Device状态。OMDSM生成的所有包的Stream ID字段都应该是Stream n。
一旦进入OMDSM,就对接收到的数据包DP的PP字段求值。PP = 1将OMDSM转换到OUTMvData Device状态。PP = 0将OMDSM转换到OUTMvData Host Terminate状态。
每当进入OUTMvData Device状态,设备执行如下动作来使OMDSM推进:
if (设备功能缓冲区空间 >= 主机端点数据大小【注1】)
设备应该生成NumP字段> 0的数据包ACK TP,这样就促使管道转移到OUTMvData Host状态。
else if (设备功能缓冲区空间 = 主机端点数据大小)
设备应该生成NumP字段= 1的数据包终结ACK TP,这样就促使管道退出OMDSM,并转移到Idle状态。
【注1:主机端点数据大小通过设备类定义机制与设备沟通】
可选地,设备可能生成一个Stream ID设置为Stream n的NRDY TP,这样就终结该流,并将管道退出OMDSM而转移到Idle状态。设备可能使用该转换来拒绝主机发起的数据搬移请求(Host Initiated Move Data)。
注意:如果中间的集线器推后了数据包DP,主机和设备应该就像设备发送了一个NRDY TP那样来工作。也就是说,主机应该在接收到推后的响应(Deferred Response)时转换到Idle状态。设备应该在接收到推后的数据包DP(Deferred DP)时退出OMDSM并转换到Idle状态,就像它已经发送了Stream ID字段设置为Stream n的NRDY TP。如果设备接受主机发起的Stream ID,它应该发送一个Stream ID字段设置为Stream n的ERDY。如果设备拒绝主机发起的Stream ID,它应该呆在Idle状态并等待下一个要么从主机要么从设备来的流选择(Stream selection)。
OUTMvData Host状态由于设备有更多功能缓冲区(Function Buffer)空间可用来接收数据,因此主机执行如下动作来使OMDSM推进:
if (主机端点数据大小 > 最大包大小)
生成PP = 1的数据包DP,这样就促使管道转移到OUTMvData Device状态。
else (主机端点数据大小 <= 最大包大小)
生成PP = 0的数据包DP,这样就促使管道转移到OUTMvData Host Terminate状态。
上述描述OMDSM的伪代码不依赖于接收到的ACK TP是否指示是重试(retry)。具有Retry的ACK TP应该影响被传送的数据包DP的序列号(Sequence Number),并促使端点数据(Endpoint Data)被重传(retransmitted)。
OUTMvData Host Terminate状态由于主机没有更多的端点数据(Endpoint Data)发送(PP = 0),因此设备应该生成NumP = 0的终结ACK TP,这样就促使管道退出OMDSM并转换到Idle状态。如果设备检测到主机发送的上一个数据包DP的错误,它应该用Retry ACK TP (Steam n, NumP>0, Rty=1)来响应,并且OMDSM应该转换到OUTMvData Host状态。
注意:如果一个数据包DP错误在OUTMvData Device状态被检测到,设备应该生成一个NumP > 0 且 Rty = 1的ACK TP,从而促使管道转换到OUTMvData Host状态并重新发送该包。
8.12.2 控制传输 【Control Transfers】
控制传输至少有两个事务阶段:Setup 和 Status。控制传输可能可选地在Setup 和 Status之间有一个Data阶段。Data阶段的方向由位于Setup包的第一个字节的bmRequestType字段来指示。在Setup阶段,SETUP事务被用来传输信息到设备的控制端点。SETUP事务在格式上与Bulk OUT事务类似,但是其DPH的Setup字段被设为1,且其Data Length字段被设为8。此外,Setup包总是使用数据序列号0。接收Setup包的设备应该按照8.11.4定义的那样来响应。不论控制传输的阶段和方向如何,在主机和设备的任意控制端点之间交换的任何TP或者DP中的Direction字段都应该设为0。【已勘误】注意,如果设备已经成功接收到了SETUP包,如果端点想要对这个控制传输进行流程控制,端点可以返回NumP字段设为0的ACK TP来响应对该端点的SETUP包。设备必须发送一个ERDY来恢复这个控制传输,开始其Data或者Status阶段。注意,主机可以恢复到任意端点的事务——即便该端点在返回流程控制响应之后还没有返回一个ERDY TP。【已勘误,主机不一定要(don't have to)等待一个ERDY才能与被流控的端点交谈】。
控制传输的Data阶段,如果存在的话,包含一个或者多个IN或者OUT事务,并遵循与批量传输相同的协议规则,除了控制传输的Direction字段应该总是设为0。【已勘误】Data阶段总是以序列号设为0开始。在Data阶段的所有事务都必须是相同方向(也就是说,全部输入或者全部输出)。在数据阶段最多能发送的数据长度以及方向在Setup阶段指定。如果数据量超过数据包大小,数据被分成多个以最大包大小传送的数据包来发送。所有剩下的数据在最后的数据包中作为收尾发送。
注意所有的控制端点只支持burst为1,因此主机一次只能与控制端点发送或者接收1个包。
控制传输的Status阶段是整个序列中的最后一个事务。状态阶段事务由SubType设为STATUS的事物包TP来指示。作为对Deferred比特被设为0的STATUS TP的响应,设备应该发送一个NRDY, STALL, 或者ACK TP。如果设备发送一个NRDY TP,主机应该在发送另一个STATUS TP给设备之前,应该等待该控制端点发送一个ERDY TP。然而,主机可以恢复到任意端点的事务——即便该端点在返回流程控制响应之后还没有返回一个ERDY TP。【已勘误,主机不一定要(don't have to)等待一个ERDY才能与被流控的端点交谈】。 如果STATUS TP
中的Deferred比特被设置(为1),那么设备应该发送一个ERDY TP来告知已经准备好完成控制传输的状态阶段的主机。
图8-33和8-34显示事务顺序,数据序列号值,以及控制读和写序列的数据包类型。
【勘误:上图中的所有IN(ACK TP),都应该改为ACK TP。】
当一次控制传输的数据阶段或者状态阶段中控制端点发送了一个STALL TP,那么所有后续的对该端点的访问都应该返回STALL TP,直到收到一个SETUP DP。当端点收到一个后续SETUP DP时,端点应该返回一个ACK TP。对于控制端点,如果对于SETUP 事务返回了ACK TP,那么主机就期望其已经自动从导致STALL的条件中恢复,并且端点可以正常操作。
8.12.2.1 报告状态结果
【Reporting Status Results】
在Status阶段,设备向主机报告该次传输前面的Setup和Data阶段的结果(outcome)。可能返回3种可能结果:
• 命令序列完成成功。
• 命令序列完成失败。
• 设备还在忙于完成命令。
状态报告总是device-to-host方向。表8-29总结了各项要求的响应类型。所有的控制传输都在作为对STATUS TP事务的响应返回给主机的事务包中返回状态。
表 8-29. 状态阶段响应 【Status Stage Responses】
状态响应 |
设备发送的事务包 |
请求完成 |
ACK TP |
请求有错 |
STALL TP |
设备忙 |
NRDY TP |
主机应该发送一个STATUS TP到控制端点来启动Status阶段。管道的握手响应指示当前状态。NRDY TP指示设备正处理该命令并且设备应该在其完成命令时发送ERDY TP。ACK TP指示设备已经完成命令并且已经准备好接受新的命令。STALL TP指示设备出错,阻碍了设备完成该命令。
设备的控制端点发送的ACK TP的NumP字段应该被设为0。但是这不被当作控制端点的流程控制条件。
如果在Data阶段,控制端点被发送了或者被请求返回了多于在Setup阶段所指示的数据,就应该返回STALL TP。如果控制端点在Data阶段返回了STALL TP,这次从制传输就不应该再有Status阶段。
8.12.2.2 可变长数据阶段
【Variable-length Data Stage】
控制管道可以有可变长的数据阶段,在此情况下主机请求了比指定的数据结构包含得多的数据。当所有的数据结构都返回给主机后,设备通过返回一个数据负载少于最大包大小的数据包DP来指示数据阶段结束。
注意如果返回给主机的数据结构少于主机请求的数量,且恰好是最大包大小的整数倍,那么控制端点应该发送一个零长数据包DP来终结该数据阶段。
8.12.2.3 控制管道返回的STALL TPs 【STALL TPs Returned by Control Pipes】
控制管道具有特有的能力,由于控制传输的问题可以返回STALL TP。如果设备不能完成命令,在控制传输的数据和/或状态阶段返回STALL TP。与功能性STALL不同,协议性STALL并不代表设备出错。协议性STALL情形保持到接收到下一个SETUP DP,并且设备应该对于该管道的所有的IN或者OUT事务都返回STALL TP,直到接收到SETUP DP。总之,协议性STALL指示请求或者其参数不能被理解,因此提供了一种机制来扩展USB请求。
设备不支持在控制管道上的功能性STALL。
8.12.3 总线间隔以及服务间隔 【Bus Interval and Service Interval】
对于所有的周期性(中断和等时)端点,端点必须被服务的间隔被叫做"服务间隔"。在本规范中,"总线间隔"被用来指代一个125 μs时隙。
8.12.4 中断事务【Interrupt Transactions】
中断传输类型被用于不经常且具有有限的服务期的数据传输。该类型支持有保证的有限时延的可靠数据传输。只要数据可用,该类型提供有保证的固定数据率。如果在被传送的数据中检测到错误,主机并不要求在相同的服务间隔内重传该事务。但是,如果设备临时不能发送或者接收数据(也就是说,以NRDY TP响应),主机只应该在从设备接收到一个ERDY TP后恢复对该端点的事务。中断事务非常类似批量事务——但只限于每个服务间隔内3个数据包。只要设备能接受数据(对于OUT端点)或者返回数据(对于IN端点),主机应该以协同一致的服务间隔,连续执行对端点的事务。主机被要求对在服务间隔内成功接收到的每一个数据包DP发送一个ACK TP,即使这是该服务间隔的最后一个数据包DP。最后一个ACK TP应该确认最后一个数据包DP,且其Number of Packets字段应该被设为0。如果在当前服务间隔内对中断端点执行事务时发生错误,主机没有被要求必须在当前的服务间隔内重试该事务,但是主机最迟应该在下一个服务间隔内重试该事务。
8.12.4.1 中断输入事务
【Interrupt IN Transactions】
当主机想要开始一次到端点的Interrupt IN事务时,就发送一个具有所期望的序列号以及期望从端点接收到多少个包的ACK TP到端点。如果设备能够发送数据来响应主机的ACK TP,就可以在相同服务间隔内发送被请求个数的数据包上来。主机应该对每一个数据包DP响应一个ACK TP,指示对数据的成功接收;或者如果数据包负载(DPP)被损坏,应该发送一个ACK TP来请求重新发送数据包DP。
注意,在端点被初始化后(通过Set Configuration或者Set Interface或者ClearFeature(ENDPOINT_HALT)命令——参考第9章关于这些命令的详情),当主机开始对特定端点的首次传输时,主机期望第一个数据包的序列号被设为0。
中断端点应该如8.11.1所描述的那样来响应从主机接收到的事务包s。只要设备返回数据来响应发送ACK TPs的主机,且传输还没完成,主机就应该继续在每一个服务间隔内向该设备的端点发送ACK TPs。
当任意如下条件之一满足,主机就应该停止执行到设备端点的事务:
- 端点以NRDY 或者 STALL TP响应。
- 本次传输的所有数据都已成功接收到。
- 端点在发送给主机的最后一个数据包中设置了EOB标志。
当端点在接收到主机的ACK TP后,又不能以发送数据来响应,就应该发送一个NRDY(或者在由于是端点或者设备内部错误的情况下,发送STALL)TP给主机。主机在之后的服务间隔内就不应该执行更多的到端点的事务。如果在此前的服务间隔内该端点曾以流程控制响应,主机只有在其从端点接收到一个ERDY TP之后,方可恢复到端点的中断事务。这就通知了主机端点已经准备好再次传输数据。一旦主机接收到ERDY TP,就应该在不迟于两倍于端点描述符的bInterval 字段的时间内发送一个IN请求(通过ACK TP)到端点。中断端点应该通过返回一个DP(序列号比上一次成功发送的数据多1),或者,假如不能发送数据,就返回一个NRDY 或者一个STALL TP。
如果设备接收到一个推迟的中断IN TP,且设备需要发送中断IN数据,设备应该发送一个ERDY TP来响应,并保持链路在U0状态,直到从主机接收到后续的中断事务,或者到tPingTimeout(参考表8-33)超时。
正如Bulk事务的情形,序列号对于中断端点每次发送的包是连续增加的。当序列号达到31,就回绕至0。
注意:在图8-39中,主机在同一个服务间隔内重试接收到的有错误的数据包。并不是强制要如此,也可以再下一个服务间隔内重试该事务。
8.12.4.2 终端输出事务
【Interrupt OUT Transactions】
当主机想要开始一次到端点的Interrupt OUT事务时,就以期望的序列号发送第一个DP。如果端点支持大于1的突发大小(burst size),主机就可以在相同服务间隔内发送多个数据包到端点。如果端点能够接收主机发来的数据,就发送一个ACK TP来确认对数据的成功接收。
注意,在端点被初始化后(通过Set Configuration或者Set Interface或者ClearFeature(ENDPOINT_HALT)命令——参考第9章关于这些命令的详情),当主机开始对端点的首次传输时,主机总是将第一个数据包的序列号设为0。
只要设备返回ACK TPs来响应发送数据包的主机,且传输还没完成,主机就应该继续在每一个服务间隔内向该设备的端点发送数据。设备应该确认对数据包的成功接收,或者请求主机重传,如果数据包被损坏的话。
中断端点应该如8.11.3节所述来响应主机发送的OUT数据。
当端点在接收到主机的数据后,又暂时不能接受数据,就应该发送一个NRDY(或者在由于是端点或者设备内部错误的情况下,发送STALL)TP给主机。主机在之后的服务间隔内就不应该执行更多的到端点的事务。如果在此前的服务间隔内该端点曾以流程控制响应,主机只有在其从端点接收到一个ERDY TP之后,方可恢复到端点的中断事务。这就通知了主机端点已经准备好再次接收数据。一旦主机接收到ERDY TP,就应该在不迟于两倍于端点描述符的bInterval 字段的时间内发送数据包到端点。
如果设备接收到一个推迟的中断OUT DPH,且设备需要接收中断OUT数据,设备应该发送一个ERDY TP来响应,并保持链路在U0状态,直到从主机接收到后续的中断事务,或者到tPingTimeout(参考表8-33)超时。
正如Bulk事务的情形,序列号对于主机每次发送的包是连续增加的。当序列号达到31,就回绕至0。
注意:在图8-43中,主机在同一个服务间隔内重试设备接收到的有错误的数据包。并不是强制要如此,也可以再下一个服务间隔内重试该事务。
8.12.5 主机时序信息 【Host Timing Information】
USB 3.0主机控制器在SuperSpeed USB链路上不定期广播帧开始(SOF)包到所有的设备。主机时序信息只在根端口链路处于U0状态,在总线间隔附近,通过等时时戳包(ITP)被主机发送。集线器转发等时时戳包到所有的链路处于U0状态的下行口。主机应该给予一个非扩频时钟来提供等时时戳包。如果必须要等时时戳包来使设备可操作,设备就有责任在总线间隔附近将链路保持在U0状态。除非必须要等时时戳包来使设备操作,设备绝不应该仅仅为了接收等时时戳包而将链路保持于U0状态。
注意:如果设备的链路在总线间隔附近处于U0状态,设备就会接收到等时时戳包。这就意味着没有等时端点的设备,或者无需同步的设备可能会丢弃等时时戳包,而不会有负面的副作用。如果设备具有用来判定何时将链路置于低功耗状态的不活动定时器,则在接收到等时时戳包时,设备可以选择不重置其不活动定时器。
时序信息被放在等时时戳包中,在总线间隔附近发送,并传递当前的总线间隔,以及本时戳包的开始到前一次总线间隔之间的时间。等时端点要求125 * 2^n
μs的服务间隔,其中n是0到15(包括)之间的整数。
等时时戳包(ITPs)传递时序信息,以便所有的等时端点都接收到相同的间隔边界。在所有时候,主机都应该保持对所有的端点的服务间隔边界对齐,除非主机链路进入了U3状态。在主机的根端口的链路从U3状态退出后发送的等时时戳包(ITPs)可能与在主机的根端口的链路进入U3状态前的等时时戳包(ITPs)边界对齐。在主机的根端口的链路从U3状态退出进入U0后,主机应该在tIsochronousTimestampStart时间内开始传送等时时戳包(ITPs)。图8-45显示了一个示例,一个活动的等时IN端点和一个活动的等时OUT端点连接在同一个USB 3.0主机控制器下面。等时IN端点的服务间隔是X,等时OUT端点的服务间隔是2X。注意主机在适当的服务间隔内的任意位置可以随意调度等时IN(通过ACK TP)或者等时OUT数据。设备将会通过检测Bus Interval Counter的低比特位(least significant bits)的翻转(rollover)来检测服务间隔(service interval)的开始。具体需要监控(monitored)多少比特位的翻转是由bInterval定义的。例如,如果服务间隔(service interval)等于2个Bus Intervals,则服务间隔(service interval)的开始是由Bus Interval Counter的最低位转换到'0'定义的。如果服务间隔(service interval)等于4个Bus Intervals,则服务间隔(service interval)的开始由Bus Interval Counter的最低两位转换到'0'定义的,以此类推。如果bInterval是1,则设备会在Bus Interval Counter的最低位改变时,检测到服务间隔(service interval)的开始。【已勘误】设备不应该假设事务在每一个服务间隔的相同的位置发生。主机应该保证事务不会跨越服务边界那样来调度事务。
8.12.6 等时事务 【Isochronous Transactions】
IN等时事务被显示在图8-46,OUT等时事务被显示在图8-47。对于输入(INs),主机发送一个ACK TP,紧随其后是端点对输入请求(INs)传送数据的数据相位。对于输出(OUTs),主机在当前服务间隔内有数据发送时,只是简单地发送数据。等时事务不支持重试能力。
每个服务间隔只有一个数据包的超高速等时事务总是使用序列号0。对于一个服务间隔包含多个数据包的超高速等时事务,序列号对于每一个数据包都增加1。在任意的服务间隔中发送的第一个数据包的序列号总是0。主机应该能在每个服务间隔内发送多达48个数据包(DP)。在每个服务间隔中的第一个DP的序列号应该设为0开始。第二个DP的序列号应该设为1;第三个DP的序列号应该设为2;以此下去,直到序列号31。序列号31的下一个DP使用序列号0。具有等时端点的超高速设备应该能够发送或者接收由短端点或者端点伴侣描述符指示的数据包个数(序列号为0 – N)。
服务间隔中的最后一个包在发送时应该将lpf字段设为1,并且可以小于或等于MaxPacketSize字节。在服务间隔中的除最后一个包之外的每个包,都应该在发送时将lpf字段设为0,而且应该等于MaxPacketSize字节。【已勘误】如果主机在服务间隔内没有数据发送给等时OUT,那么主机在该间隔内不发送任何东西。如果有等时IN端点的设备收到等时IN ACK TP时,没有数据需要发送,设备应该发送一个零长数据包。图8-48和图8-49显示了对于端点的等时IN和OUT事务的示例,每个服务间隔请求2000字节带宽(也就是说,每个服务间隔可以发送或接收不多于两个数据包)。
如果由于错误条件导致主机在指定的间隔内不能发送等时数据,主机丢弃数据并通知主机软件发生了该错误。如果由于错误条件导致主机在指定的间隔内不能发送等时ACK TP,主机也要通知主机软件发生了该错误。
8.12.6.1 主机执行等时事务的灵活性
【Host Flexibility in Performing Isochronous Transactions】
主机被赋予了一定的灵活性来在服务间隔内执行等时服务。主机可以用一个等时突发事务传输到(或者从)端点的所有的数据包(DPs),或者可以将传输分成更小的突发,以2个,4个,或者8个数据包(DPs)紧跟该服务间隔最后剩余数据包(DPs)构成的等时突发。主机不能以任意其他方式执行等时事务。对于具有乘数值大于1的等时端点,这些规则对与每一个乘数值相关联的突发事务都单独适用。设备应该支持由这些规则允许的所有可能的主机突发事务。例如,如果等时IN端点请求一次突发最多11个包,而且主机在该服务间隔内有11个包可以从端点接收,主机就有5种可能的方式来执行事务。
- 请求1次突发11个包
- 请求1次突发8个包,接着1次突发3个包
- 请求2次突发4个包,接着1次突发3个包
- 请求5次突发2个包,接着1次突发1个包
- 请求11次突发1个包【已勘误,添加了这个例子,因为现在ISO传输可以支持1次突发一个包(burst of 1)】
将上面的例子进一步,如果等时IN端点请求一次突发最多11个包,且Mult为2(本质上请求3次,每次突发11个包),并且在服务间隔期间主机有缓冲来从设备端点接收33个包,则主机可以使用上面提到的选项的任意组合来从端点传输3组,每组11个包的突发。
主机不能在服务间隔内重置序列号。主机应该只在服务间隔的最后一个突发的最后一个包中设置LPF标记。
8.12.6.2 设备对于等时IN事务的响应
【Device Response to Isochronous IN Transactions】
表8-30列出了设备对于ACK TP可能的响应。如果Device Address不正确,或者端点号和方向没有引用当前配置的端点,或者其序列号不正确,或者其中的deferred位被设置了,则一个ACK TP会被认为是无效的。
表8-30. 设备对于等时IN事务的响应
接收到的ACK TP 无效 |
设备可以发送数据 |
执行的动作 |
Yes |
不关心 |
不返回响应 |
No |
No |
返回序列号为0的数据包 |
No |
Yes |
返回N个数据包,序列号从0到N-1。除了最后一个包之外,每个包都应该是MaxPacketSize字节。最后一个包可以小于或等于MaxPacketSize字节。最后一个包应该将LPF标记设置上。 |
8.12.6.3 主机处理等时IN事务
【Host Processing of Isochronous IN Transactions】
表8-31列出主机从IN事务处理数据。主机从不对接收到的等时IN数据返回响应。在表8-31中,数据包DP错误可能是一个或者多个如下的原因:
- CRC-32不正确(incorrect)
- DPP中止(aborted)
- DPP丢失(missing)
- DPH的数据长度与实际数据负载长度不匹配
如果主机接收到一个损坏的数据,就丢弃当前服务间隔的剩余数据,并通知主机软件发生了该错误。
表 8-31. 主机响应IN事务
数据包错误 |
主机可以接收数据 |
主机数据处理 |
Yes |
N/A |
丢弃数据 |
No |
No(这对于兼容的主机实现是永远不应该发生的) |
丢弃数据 |
No-数据包有期望的序列号 |
Yes |
接受数据 |
No-数据包没有期望的序列号 |
Yes |
丢弃数据 |
8.12.6.4 设备对于等时OUT数据包的响应
【Device Response to an Isochronous OUT Data Packet】
表8-32列出设备从OUT数据包处理数据。设备从不返回TP来响应。在表8-32中,数据包DP错误可能是一个或者多个如下的原因:
- CRC-32不正确(incorrect)
- DPP中止(aborted)
- DPP丢失(missing)
- DPH的数据长度与实际数据负载长度不匹配
- DPH中的Deferred位被设置
表8-32. 设备对于等时OUT数据包的响应
数据包错误 |
期望的序列号 |
设备可以接收数据 |
设备数据处理 |
Yes |
不关心 |
不关心 |
丢弃数据 |
No |
Yes |
Yes |
接受数据 |
No |
Yes |
No |
数据被丢弃 |
No |
No |
No |
数据被丢弃。设备可以丢弃当前服务间隔内任意额外的数据 |
No |
No |
Yes |
数据被丢弃。设备可以丢弃当前服务间隔内任意额外的数据 |
8.13 时序参数
【Timing Parameters】
表8-33列出了在接收到各种各样的包时,设备需要遵从的最小和(或)最大时间值。该表也列出了设备可以在延迟忍耐消息(Latency Tolerance messages)中设置的默认和最小时间值,以及在从接收到某些事物包(TPs)到其可以发起进入U1或者U2之间的最小时间值。此外,该表还列出了设备在进行突发时必须遵循的数据包(DPs)之间的最长时间。
注意所有的txxxResponse(例如,tNRDYResponse)和tMaxBurstInterval时间值都是设备在没有别的其它东西发送给上行链路时必须满足的时序要求。
表 8-33. 时序参数
名字(Name) |
描述(Description) |
最小(Min) |
最大(Max) |
单位(Units) |
tPortConfiguration |
从端口进入U0到它完成交换LMPs之间的最大时间。对于tiebreaker的情形(参见表8-7),两个端口都应该复位它们的定时器并在每个LMP交换时都重启它们,直到tiebreaker被解决。【已勘误】 |
20 |
μs |
|
tPingTimeout |
设备接收到一个ping之后,到其可以发起或者接受U1或者U2请求之间的超时值。该参数的测量要以设备的所有等时端点的所有服务间隔的最大值为依据。【已勘误】 |
2 |
服务间隔 |
|
tPingResponse |
设备接收到上一个ping的分帧符号(framing symbol)以及ping_response的第一个分帧符号(framing symbol)之间的时间。 |
400 |
ns |
|
tBELTDefault |
默认的最大努力延迟忍耐(best effort latency tolerance) |
1 |
ms |
|
tBELTmin |
在延迟忍耐消息(Latency Tolerance Message)中允许的最小的最大努力延迟忍耐(best effort latency tolerance) |
125 |
μs |
|
tNRDYorSTALLResponse |
设备接收到上一个ACK TP 或者 DPP或者STATUS TP的分帧符号(framing symbol)以及NRDY或者STALL响应的第一个分帧符号(framing symbol)之间的时间。 【已勘误】 |
400 |
ns |
|
tDPResponse |
设备接收到上一个ACK TP的分帧符号(framing symbol)以及DP响应的第一个分帧符号(framing symbol)之间的时间。 |
400 |
ns |
|
tACKResponse |
设备接收到上一个DPP或者STATUS TP的分帧符号(framing symbol)以及ACK响应的第一个分帧符号(framing symbol)之间的时间。【已勘误】 |
400 |
ns |
|
tHostACKResponse |
主机接收到上一个DPP的分帧符号(framing symbol)以及ACK响应的第一个分帧符号(framing symbol)之间的时间。 |
3 |
ns |
|
tERDYTimeout |
设备发送ERDY到主机之后,到其因没有得到服务,而可以发起或者接受U1或者U2请求之间的超时值。【已勘误】 |
500 |
ms |
|
tNotification |
(从发送上一个功能唤醒通知开始)如果设备还没有被访问过,设备应该发送功能唤醒通知(function wake notification)的比率(rate)。 |
2500 |
ms |
|
tMaxBurstInterval |
设备或者主机在进行突发时数据包(DPs)之间的时间。如果设备不能满足最大时间要求,那么就应该在其发送的最后一个数据包(DP)中设置EOB标志。 |
100 |
ns |
|
tTimestampWindow |
如果根端口的链路处于U0状态,主机应该从总线间隔边界开始到总线间隔边界之后的tTimestampWindow之间传送等时时间戳。 |
0 |
8 |
μs |
tIsochTimestampGranularity |
等时时间戳的粒度 |
8 |
8 |
USB 2.0 High-Speed 比特时间 |
BusIntervalAdjustmentGranularity |
对于设备请求的总线间隔改变的调整单位。 |
4.0690104 【注1】 |
ps |
|
tIsochronousTimestampStart |
从主机在根端口链路从轮询状态进入U0状态,或者从主机的根端口的链路从U3状态退出进入U0,到主机应该开始传送等时时间戳的时间。 |
250 |
μs |
|
tBELTRepeat |
设备被允许发送多于两个延迟忍耐消息事务包(LTM TPs)的时间段 |
1 |
ms |
|
tMinLTMStateChange |
外围设备在完成使能或者禁止LTM_Enable 特性请求之后,必须要发送延迟忍耐消息通知(LTM notification)的时间 |
10 |
ms |
|
tHostTransactionTimeout |
对于控制,批量,和中断事务,定义为在主机认为该事务已经失败而halt该端点之前,没有收到对主机发送出去的上一个DP或ACK TP的响应的时间。 对于等时IN事务,定义为没有收到对主机发送的ACK TP的响应的时间。每当主机接收到ACK TP所请求的每个包时,就初始化并重启定时器。如果出现超时,则主机在当前服务间隔内就不应该再对该端点执行更多事务。主机不允许halt该端点,而应该在下一个服务间隔内重启到该端点的事务。不应该执行重试。 |
32 |
5032 |
μs |
【注1:
(tIsochTimestampGranularity/4096)】
USB 3.0规范中译本 第8章 协议层的更多相关文章
- USB 3.0规范中译本 第7章 链路层
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 链路层具有维持链路连接性的责任,从而确保在两个链路伙伴之间的成功数据传输.基于包(packets)和链路命令 ...
- USB 3.0规范中译本 第10章 集线器,主机下行口以及设备上行口规范
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章描述USB 3.0 集线器的体系结构要求.本章还描述主机下行口和集线器下行口之间功能性的不同之处,以及设 ...
- USB 3.0规范中译本第9章 设备框架
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 设备框架可以被分成三层: 最底层是总线接口层,传送和接收包. 中间层处理在总线接口和设备的各种端点之间路由数 ...
- USB 3.0规范中译本 第5章 机械结构
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章定义USB 3.0连接器和线缆组件的form, fit 和 function.包括以下方面: • 连接器 ...
- USB 3.0规范中译本 第4章 超高速数据流模型
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章展示数据和信息如何在超高速上通过的一种高层次的描述.请阅读协议层一章关于低层次协议的细节.本章提供设备架 ...
- USB 3.0规范中译本 第3章 USB 3.0体系结构概览
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章呈现USB 3.0体系结构和关键概念的概览.USB 3.0与前面版本的USB类似,因为它是线缆总线,支持 ...
- USB 3.0规范中译本 第2章 术语及缩略语
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章列出并定义本规范通篇将使用的术语及缩略语. 术语/略缩语 定义 ACK(确认包) 表示积极肯定的握手包. ...
- USB 3.0规范中译本 第1章 引言
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 1.1 动机(Motivation) Universal Serial Bus (USB) 的原始动机来自于 ...
- USB 3.0规范中译本 第6章 物理层
本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 6.1 物理层概览 物理层定义超高速总线的信号技术.本章定义超高速物理层的电气要求. 本节定义超高速组件之间 ...
随机推荐
- SQL分页的几种方式
1.使用Row_number() over(order by columnName)函数来作为标示分页(下面的例子都是以last_seen来排序的,要求取顺序为20-30行的数据) SELECT Us ...
- SpringCloud核心教程 | 第一篇: 使用Intellij中的Spring Initializr来快速构建Spring Cloud工程
spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环 ...
- 题目1205:N阶楼梯上楼问题(2008年华中科技大学计算机保研机试真题:递推求解)
题目1205:N阶楼梯上楼问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2447 解决:927 题目描写叙述: N阶楼梯上楼问题:一次能够走两阶或一阶,问有多少种上楼方式. (要求 ...
- cocos2d-x 3.0 游戏关卡滑动 弹动 不会出现黑边效果
#pragma once #include "cocos2d.h" #include "ShopScene.h" using namespace cocos2d ...
- amazeui学习笔记--css(基本样式2)--基础设置Base
amazeui学习笔记--css(基本样式2)--基础设置Base 一.总结 1.盒子模型:外margin,内padding,这里的内外指的边框 2.border-box:Amaze UI 将所有元素 ...
- 我的Go语言学习之旅三:Go语言中的for循环
这个但是为难我了,我一直是走在WEB前的程序猿,各种循环用起来得心应手.突然间发现到了Go这里竟然行不通了,查阅后才发现,原来Go的for是这样写的. for i:=0;i<10;i++{ fm ...
- Android 使用XML隐藏ActionBar中遇错的解决的方法
今天我在使用Menifest.xml让程序隐藏标题栏是一直出错.主要内容是: You need to use a theme.AppCompat theme(descendant) with this ...
- easyui datagrid editor checkbox 单击事件
Easyui datagrid treegrid中能够为行追加checkbox元素.比如: $('#tt').treegrid({ url:'get_data.php', idField:'id', ...
- 使用BeautifulSoup爬取“0daydown”站点的信息(2)——字符编码问题解决
上篇中的程序实现了抓取0daydown最新的10页信息.输出是直接输出到控制台里面.再次改进代码时我准备把它们写入到一个TXT文档中.这是问题就出来了. 最初我的代码例如以下: #-*- coding ...
- 嵌入式Qt-4.8.6显示中文并且改变字体大小和应用自己制作的字体库
问题: QT4.8.6在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器中的字号与开发板中的字号一致. 详解: 1>如何让QT支 ...