端点
端点是一个USB设备唯一可以确认的部分,他是主机和设备之间的通信流的重点。每一个USB逻辑设备都包含了一个相当独立的进行操作的端点的集合。软件只能够通过一个或者多个端点与一个USB设备通信。在设备接入的时候,每一个逻辑设备都有一个由系统分配的唯一的地址。而一个设备上的任意一个端点都有一个由设备而定(设计时)唯一的标识和端点号。利用设备的地址和端点号就可以唯一的指定任意一个端点。
端点可以决定端点和客户软件之间通信所需要的传输服务类型。一个端点可以由一下的几个内容来描述:
- 总线访问频率/延时要求
- 带宽要求。
- 端点号。
- 差错控制要求。
- 端点可以接收或者传递的最大分组包。
- 端点的传送类型。
- 对于同步传输而言,还要包括端点和主机之间的数据传输方向。
一个端点只有在对其进行配置以后才能够被使用。包括端点0在内的所有端点,都作为设备配置过程中的普通部分来对其进行配置。
管道
一个USB管道是设备上的一个端点和主机上的软件的联合体。管道表示经过一个存储器缓冲区和一个设备上的端点,可以在主机上的软件之间传送数据的能力。管道类型分为:流管道和消息管道。但是USB并不对通过一个管道传递的数据内容进行翻译,即使是消息管道要求根据USB的规定对数据进行打包,USB也不会翻译这些数据内容。另外,管道还需要确定一下的三个参数:
- 对USB总线访问和带宽使用的声明。
- 传输的类型。
- 所对应的端点的特征,如方向和最大数据负载尺寸等。其中数据负载是指总线操作当中,一个数据分组的数据域当中所携带的分组。
一个客户软件通常是通过向一个管道发出IRP来要求传送数据,发出IRP之后客户软件就等待或者是得到指示。IRP定义的细节由具体的操作系统而定。当与一个IRP相对应的总线操作完成以后,无论其是成功还是由于出错而结束,这个客户软甲都会被告知IRP已经处理完成。
为通过总线来传输数据,一个IRP可能需要多个数据负载。对于一个需要多个数据负载的IRP来说,其分组的数据域应该具有最大的尺寸。直到最后一个数据载荷中包含该IRP中的剩余的部分。
控制传输
控制传输允许对一个设备的不同部分进行访问,他用于支持客户软件和功能模块之间的配置/命令/状态等类型的通信流。一个控制传输由以下的几个部分构成;
- 总线建立操作,负责将请求信息由主机送到功能模块;
- 零个或者是多个数据处理操作,传输方向由建立操作指定。
- 状态处理操作,用于功能模块向主机返回状态信息。
当一个端点成功的完成了请求操作的处理时,状态处理操作就返回成功状态。控制传输只能由消息管道来实现。控制传输的数据流必须按照一定的数据结构来进行。一个功能模块及其软件不能够请求某个访问频率或者是带宽。USB系统软件将对一个设备所要求的控制传输的总线访问和带宽加以限制。
控制传输最少具有两个处理阶段:创建和状态。一个控制传输可以选择在创建和状态阶段之间再包含一个数据阶段。在创建阶段,一个创建处理操作用于向一个功能设备的控制端点传送信息。创建处理操作所具有的格式与一个out处理相似。但是他使用的是SETUP而不是OUT PID。一个创建处理操作总是对其数据域使用一个DATA0 PID。接受一个创建处理操作的功能设备必须接受创建处理数据并使用一个ACK握手分组来响应,或者是如果这个数据被破坏了,它必须要丢弃该数据并且不返回任何握手分组。
如果一个控制传输内有数据阶段的话,那么这个数据阶段就包含了一个或者是多个IN或OUT处理。并且要遵循和批量传输一样的协议原则。在数据阶段所有的处理操作都必须具有同样的方向,即全部是IN或全部是OUT。在数据阶段传输的数据量及其方向都是在创建阶段加以说明了的。若数据量超过了预先确定的数据分组的大小,那么数据就会在多个装载了最大分组大小的处理操作内传送(IN或OUT).任何剩余的数据都将作为剩余量而在最后一个处理操作内发送。
一个控制传输中的状态阶段是该序列中的最后一个操作。一个状态阶段由相对于前一个阶段数据流方向的变化来描述,并且总是使用一个DATA1 PID。例如,若一个数据阶段包含有OUT,那么状态就是一个单一的IN处理操作。若一个控制序列没有数据阶段,那么它就包括一个创建阶段,再跟上一个包含了一个IN处理的状态阶段。下图说明了处理顺序、数据序列比特值和用于控制读和写序列的数据PID类型。序列的比特号在括号内给出:
- 报告状态结果:状态阶段向主机报告该传输中前一个创建和数据阶段的输出。可能的返回有三种:命令序列成功完成/ 命令序列未能完成/ 功能设备正在忙着完成命令。
报告状态总是具有从功能设备到主机的方向。下图对每一种结果所要求的响应类型作了总结:
控制写传输在该传输中的数据阶段返回状态信息。在前一个数据阶段内主机发送了一个长度为0的数据之后,控制读传输将在握手阶段返回状态信息。
对于控制读,主机向控制端点发送一个零长度的数据分组。端点作出握手响应说明状态阶段的结束。NAK说明该功能设备仍处在处理命令,而主机应该继续状态阶段。ACK说明该功能设备已经完成了这一命令,并为接收一个新的命令做好了准备。而STALL则说明该功能设备出现了一个阻碍其完成命令的错误。
对于控制写而言,功能设备不是用一个握手,就是用一个0长度的数据分组来响应,以指出其状态。一个NAK说明该功能设备仍然在处理命令,而主机应该延续状态阶段。返回一个0长度分组则说明命令已经完成,而STALL则说明该功能设备出现了错误。在数据阶段返回一个0长度数据分组的控制写传输,会使主机向该功能设备返回一个ACK握手分组。
在一个数据或者是状态阶段,如果向一个命令端点发送了或者是要求一个命令端点返回多于在创建阶段所指明的数据,它就应该返回一个STALL。如果一个控制端点在数据阶段返回了STALL,那么该控制传输就没有状态阶段。
5.7.3 控制传输
用于实现一个一个中断管道的某一个端点要说明它将要传输的最大数据负载。全速率设备<=64字节,低速率设备<=8字节。这个最大值将用于数据分组,既这个尺寸限制只对分组中的数据域有限制。并不包括其他的协议要求的信息。
在设备的配置操作中,USB系统软件将决定一个中断管道可以利用的最大数据负载尺寸。USB软件不会像对待控制管道一样,为一个中断管道调整其可用的总线时间。在USB子系统的配置过程中,一个中断管道要么可以支持,要么不可以支持。一个客户端软件可以通过用于要求多个总线处理操作的中断传输的一个IRP来接收数据,而不需要每一个IRP都有完整的IRP指示。通过申明一个可以存储所需大小的缓冲区可以达到这一目的。缓冲区的大小是MaxPacketSize规定值的倍数再加上一定的的剩余量。若一个中断传输端点要传输的数据量小鱼客户软件的预计值,那么主控制器将会收到一个数据负载小鱼最大值的数据。这一个分组将会使得主机废除当前的IRP而转向下一个IRP。
5.8 批量传输
申请一个批量传输类型的管道需要提供下列条件:
- 根据可用带宽对USB进行访问。
- 如果由于总现上的错误而出现偶然的传输失败,需要重试。
- 保证对数据的传输,但是不对带宽或者是时延提供保证。
批量管道之中的数据流不具有USB规定的数据结构。批量管道是一个流管道,一个管道只能传输一个方向的数据。
批量传输的数据顺序:批量处理操作的数据触发比特仅仅在处理操作完成时进行触发,利用数据触发比特可以在出现差错之后撤销处理操作时,保护发送器和接收器之间的同步关系。在由一个适当的控制传输对某一个端点进行配置的时候,批量处理操作被初始化为DATA0,主机同样会以DATA0开始第一个批量处理操作。
一个端点不能指出一个批量管道所要求的总线访问频率,USB将负责平衡所有的批量管道和某些未处理的IRP的总线访问请求。经过总线进行批量传输具有比进行批量传输更高的优先权。
为了让处理操作通过总线,传输管理包括几个不同对象进行操作的实体:
- 客户软件:通过调用/回调(callBack)来向USBD接口请求IRP,使用/产生某个来自或是送往一个功能端点的功能数据。
- USB驱动程序(USBD):通过适当的HCD的调用/回调,对客户IRP中来自或者是送往设备端点的数据交换。
在客户软件为其功能模块请求了一个传输并且该请求得到了服务之后,客户软件会得到IRP已经完成的通知,如果传输中包含了向主机传输数据的功能,客户软件就会访问与某个完成了的IRP相对应的数据缓冲区的数据。
HCD负责在操作过程跟踪IRP,并且保证不超过USB带宽和帧时间的最大原因,当为一个管道建立IRP时,HCD会将它们添加到处理操作列表。如果一个IRP完成了,HCD会通知发出请求的客户软件,该IRP已经完成。如果这个IRP包含从功能模块到客户软件的数据传输,那么数据将会被放置在客户软件指定的数据缓冲区中。
USB 驱动程序
在一个接入总线的配置操作和正常的传输中,USBD通常要对总线访问进行两次斡旋,档一个设备插入并对其进行配置的时候,需要USBD来保证总线上可以容纳所要求的设备的配置操作。USBD从用来说明所需要的设备配置操作的配置软件中接收配置请求,其内容包括端点、传输类型、传输周期、数据大小等。根据可用的带宽和总线上对于请求类型的容纳能力,USBD将接受或者拒接一个配置请求。若它接受了该请求,USBD将会为发出请求的设备创建一个所需要类型的管道。该管道具有这种传输类型所定义的适当的限制。一旦对一个设备进行了配置,客户软件就可以为在它和它的功能端点之间传输数据而请求IRP。
计算功能模块/软件中的缓冲区的大小
客户软件和功能模块都需要为那些在总线上等待的未处理的数据处理操作提供缓冲区。对于非同步管道而言,缓冲区空间只需要足够容纳下一个数据分组。若对于某一个端点有多个处理操作请求等待处理,就必须要为每一个待处理操作提供缓冲处理。一个功能模块可能需要能够用来绝对精确的计算最小缓冲时间的方法,这是因为USB规范并未对功能模块及其客户软件的交互进行规定。
9.3 USB设备请求
所有的USB设备都会对设备缺省管道上来自于主机的请求作出响应,这些请求是利用控制传输而产生的。请求和请求参数则是在建立分组中传送到设备的。主机将会负责建立在下列域中传送的数值。每一个建立分组都有8个字节,如下如所示:
该请求在Vxworks中对应的已定义好的代码部分如下:
10.1.2 数据流
主控制器负责在主机和USB设备之间传输数据流。这些数据流将被作为一个连续的字节流来对待。每一个设备都实现了一个过着是多个接口,一个客户利用这些接口来同设备通信。每一个接口都包括0个或更多的管道,这些管道可以在客户和设备上的某个端点之间分别传输数据。USBD会在主机软件的明确要求之下创建接口和管道。当发出配置请求的时候,主控制器根据主机软件所提供的参数来提供服务。
根据将要传输的数据的传递要求,一个管道有几种特性。这些特性包括:数据传输所要传输的速率,是以稳定的数率或是以变化的数率来提供数据,在传输之前数据可以被延迟多久和所传输的数据丢失是否会是灾难性的。
10.3.1 设备配置
不同的操作系统环境使用不同的软件元件和不同的事件序列来进行设备配置。USB系统不会假定某个操作系统所使用的方法。但是,任一USB系统的实现都必须要遵循一些基本的要求。USB系统采用了一个称为集线器驱动程序的一个USBD的专门的用户,由它作为一个用于向某个集线器添加设备和从某个集线器拆除设备的处理中心。一旦集线器驱动程序接到了这样的指示,它就会以某一个操作系统所特定的方式,利用另外的主机软件和其他USBD客户来识别和配置设备。对于每一个设备而言,必须要在三种类型的配置操作完成以后,它才能为使用做好准备:
- 设备配置:包括建立设备的所有USB参数和使用该设备可见的主机资源。这些工作是通过在设备上设置配置而完成的。不用对设备全部重新配置,也可以允许像使用交替的设置这样的有限的配置变化存在。一旦一个设备被配置以后,从他(设备)的观点而言它已经为使用做好了准备。
- USB配置:为了实际建立一个准备有一个客户来使用的USBD管道,客户还必须要说明另外的USB信息,而这些信息对于设备来说是不可见的。这一信息称为管道原则,描述客户会如何使用管道。它包括了客户利用一个IRP所能传输肚饿最大数据量,客户可以使用的最大服务时间间隔和客户的指示标识等项。
- 功能配置:一旦配置类型1和2完成之后,从USB的观点来看管道已经完全为使用做好了准备。但是,在客户可以实际使用管道之前,可能还需要额外的由供应商或者是设备类型而定义的建立操作。这一配置是在设备和客户之间所进行的独立操作,并没有被USBD对其进行标准化。
配置软件首先读取设备描述符,然后会要求对每一个可能的配置加以说明。它可能使用所提供的信息来装载一个客户,例如一个设备驱动程序,最初要由它来和设备进行联系。配置软件也许还要加上来自于该设备驱动程序的输入,将为该设备选择一个配置方案。启动一个设备的配置操作会建立该设备上的所有端点,并返回一个用于USBD客户的数据传输的接口集。每一个接口都是单个客户所拥有的管道的集合。最初的配置操作会使用接口的缺省设置和每一个端点的缺省带宽。另外,当选择最初的配置方案时,一个USBD实现可以允许客户说明可以替换的接口。USB系统可以保证有可用的资源来支持该端点,并且如果是这样的话,就会为其分配所需要的带宽。
现在,设备配置已经完成,但是所创建的管道并没有为使用而做好准备。当客户利用设置一个原则来说明它是如何同管道进行交互的方法来初始化每一个管道时,USB配置操作就可以完成了。说明的信息中有客户的最大服务时间间隔和指示信息。作为设置一个策略后的结果,USB系统所采取的操作之一就是确定所要求的缓冲区工作空间比客户所提供的数据缓冲区空间要大多少。所要求的缓冲区尺寸根据客户所选择的使用方式和USB系统的每一个传输要求为基础。
当IRP完成以后,客户可以成功的收到指示,或者是出现差错。客户也可以独立地唤醒USB标志信息来检测未被处理的IRP的状态。客户也可以选择诸如为一个接口启动一个可交替的设置或者是改变为某个管道所分配的带宽等等配置修改操作。为了实现这些改变,管道或接口必须分别处于空闲状态。
10.3.4 公共数据定义
为了允许客户可以尽可能直接地从其设备接收请求结果,就要求将处理数量和设备同客户之间所要求的复制操作减至最低。为了简化这一过程,IRP的某些控制方面得到了标准化,从而使得客户所提供的信息可以由堆栈中的不同层次来直接使用。用于对着一个数据的特殊格式依赖于操作系统中USBDI的实现。实际上某些数据单元对客户而言根本就不可见,但却是作为客户请求的结果而产生的。接下来的数据单元为一个请求定义了有关的信息:
- 对与这个请求相对应的管道的标识。标识一个管道也包括对用于这一请求的传输类型等信息的说明。
- 对某个客户的指示标识。
- 用于传输或者是接收的数据缓冲区的位置或是长度。
- 提供该请求的完整状态。根据要求,简要状态和详细的有关于每个处理的状态都应该提供。
- 工作空间的位置和长度。这与实现方式有关。
用于将请求传送给USBD的实际机制与操作系统有关。但是,除了上述对必须可以使用的与请求相关的信息所提出的要求之外,还有对如何来处理这些请求的要求。另外,USBD提供了一种机制来为一个缺省管道选择一个不会被中断、由供应商或者是类型而定的请求集。对于这样一个不会被中断的请求集,其他任何请求,包括标准、类型或者是供应商请求都不会被插入到操作流中。若这一请求集中的任一请求失败,那么整个请求集都会被重试。
10.5 通用串行总线驱动程序(USBD)
USBD的客户可以向设备发出命令,或者是向管道传输数据流或从管道那里接收数据流。USBD为客户提供了两组软件机制:命令机制和管道机制。
命令机制允许客户对USBD操作进行配置和控制,也允许对一个USB设备进行配置和通常的控制。更为特殊的是,命令机制提供了对设备缺省管道的所有访问。(缺省管道经常被用来实现由命令机制来进行中继的用户请求的某些部分,但是它却不能被用户直接访问。)
管道机制允许一个USBD客户来管理某个设备数据和控制传输。管道机制不允许一个客户直接对设备的缺省管道进行寻址。
- 缺省管道:USBD负责分配和管理适当的缓冲操作,用来支持缺省管道上的传输,而这些操作同设置一个设备的地址一样,对于用户而言是不可见的。对于那些用户可以直接见到的传输而言,例如发送供应商和类型命令或者是读取一个设备描述符,该用户必须提供所需要的缓冲作用。
- 客户管道。任何一个不为USBD所拥有和管理的管道都可以由一个USBD客户来拥有和管理。从IUSBD的观点而言,管道只会为单个客户所拥有。实际上,当使用该管道的时候,只要用户可以像一个协调的组织一样运转,一个合作用户组就可以管理该管道。
用户负责在其可以获得的服务时间内,提供为该管道的数据传输速率服务所需的缓存操作。对工作空间内的其它缓存要求则由USB系统来说明。
10.5.4 利用USBD机制来管理USB
配置操作是以每个设备为基础而进行的,USBD在配置软件的指挥之下进行设备的配置操作。
初始设备配置:当一个集线器通过其状态变化管道报告一个新的USB设备已经接入时,设备的配置过程就开始了。配置管理服务允许配置软件从设备中所列出的配置集合中挑选出一个USB设备配置方式。在启动设备配置之前,USBD将核实,在配置过程中向所有的端点提供的数据传输速率不超过根据当前的进度表所确定的USB能力。
修改一个设备配置:配置管理服务允许配置软件从设备所列出的配置集合中挑选出另外一个配置方案来取代一个USB设备配置。若在新配置过程中向所有端点提供的数据传输速率同根据当前的进度表所确定的USB能力相适应,该操作就能够完成,若新的配置被丢弃,则会保留前一个配置。