USB2.0规范

时间:2022-04-16 06:44:29

  USB是一种支持热插拔的高速串行传输总线,它使用差分信号来传输数据,最高速度可达480Mb/S。

  USB支持“总线供电”和“自供电”两种供电模式。在总线供电模式下,设备最多可以获得500mA的电流。USB2.0 被设计称为向下兼容的模式,当有全速(USB 1.1)或者低速(USB 1.0)设备连接到高速(USB 2.0)主机时,主机可以退化工作在全速或者低速的模式。一条USB总线上,可达到的最高传输速度等级由该总线上最慢的“设备”决定,该设备包括主机、HUB以及USB功能设备。

  USB体系包括“主机”、“设备”以及“物理连接”三个部分。其中主机是一个提供USB接口及接口管理能力的硬件、软件及固件的复合体,可以是PC,也可以是OTG设备。一个USB系统中仅有一个USB主机;设备包括USB功能设备和USB HUB,最多支持127个设备;物理连接即指的是USB的传输线。在USB 2.0系统中,要求使用屏蔽的双绞线。

  一个USB HOST最多可以同时支持128个地址,地址0作为默认地址,只在设备枚举期间临时使用,而不能被分配给任何一个设备,因此一个USB HOST最多可以同时支持127个地址,如果一个设备只占用一个地址,那么可最多支持127个USB设备。在实际的USB体系中,如果要连接127个USB设备,必须要使用USB HUB,而USB HUB也是需要占用地址的,所以实际可支持的USB功能设备的数量将小于127。

USB体系采用分层的星型拓扑来连接所有USB设备,如下图所示:
USB2.0规范
 
 
 
以HOST-ROOT HUB为起点,最多支持7层(Tier),也就是说任何一个USB系统中最多可以允许5个USB HUB级联。一个复合设备(Compound Device)将同时占据两层或更多的层。

ROOT HUB是一个特殊的USB HUB,它集成在主机控制器里,不占用地址。ROOT HUB不但实现了普通USB HUB的功能,还包括其他一些功能,具体在增强型主机控制器的规范中有详细的介绍。

“复合设备(Compound Device)”可以占用多个地址。所谓复合设备其实就是把多个功能设备通过内置的USB HUB组合而成的设备,比如带录音话筒的USB摄像头等。
 
 

  USB采用轮询的广播机制传输数据,所有的传输都由主机发起,任何时刻整个USB体系内仅允许同一个数据包的传输,即不同物理传输线上看到的数据包都是同一被广播的数据包。

USB采用“令牌包”-“数据包”-“握手包”的传输机制,在令牌包中指定数据包去向或者来源的设备地址和端点(Endpoint),从而保证了只有一个设备对被广播的数据包/令牌包作出响应。握手包表示了传输的成功与否。

  数据包:USB总线上数据传输的最小单位,包括SYNC、数据及EOP三个部分。其中数据的格式针对不同的包有不同的格式。但都以8位的PID开始。PID指定了数据包的类型(共16种)。令牌包即指PID为IN/OUT/SETUP的包。

  端点(Endpoint):是USB设备中的可以进行数据收发的最小单元,支持单向或者双向的数据传输。设备支持端点的数量是有限制的,除默认端点外低速设备最多支持2组端点(2个输入,2个输出),高速和全速设备最多支持15组端点。

  管道(Pipe)是主机和设备端点之间数据传输的模型,共有两种类型的管道:无格式的流管道(Stream Pipe)和有格式的信息管道(Message Pipe)。任何USB设备一旦上电就存在一个信息管道,即默认的控制管道,USB主机通过该管道来获取设备的描述、配置、状态,并对设备进行配置。

USB设备连接到HOST时,HOST必须通过默认的控制管道对其进行枚举,完成获得其设备描述、进行地址分配、获得其配置描述、进行配置等操作方可正常使用。USB设备的即插即用特性即依赖于此。

  枚举:是USB体系中一个很重要的活动,由一系列标准请求组成(若设备属于某个子类,还包含该子类定义的特殊请求)。通过枚举HOST可以获得设备的基本描述信息,如支持的USB版本、PID、VID、设备分类(Class)、供电方式、最大消耗电流、配置数量、各种类型端点的数量及传输能力(最大包长度)。HOST根据PID和VID加载设备驱动程序,并对设备进行合适的配置。只有经过枚举的设备才能正常使用。对于总线供电设备,在枚举完成前最多可从总线获取100mA的电流。

USB体系定义了四种类型的传输,它们是:

  控制传输:主要用于在设备连接时对设备进行枚举以及其他因设备而已的特定操作。

  中断传输:用于对延迟要求严格、小量数据的可靠传输,如键盘、游戏手柄等。

  批量传输:用于对延迟要求宽松,大量数据的可靠传输,如U盘等。

  同步传输:用于对可靠性要求不高的实时数据传输,如摄像头、USB音响等。

注意:中断传输并不意味这传输过程中,设备会先中断HOST,继而通知HOST启动传输。中断传输也是HOST发起的传输,采用轮询的方式询问设备是否有数据发送,若有则传输数据,否则NAK主机。

  USB设备通过管道和HOST通信,在默认控制管道上接受并处理以下三种类型的请求:

  1.  标准请求:一共有11个标准请求,如得到设备描述、设置地址、得到配置描述等。所有USB设备均应支持这些请求。HOST通过标准请求来识别和配置设备。

  2. 类(class)请求:USB还定义了若干个子类,如HUB类、大容量存储器类等。不同的类又定义了若干类请求,该类设备应该支持这些类请求。设备所属类在设备描述符中可以得到。

  3. 厂商请求:这部分请求并不是USB规范定义的,而是设备生产商为了实现一定的功能而自己定义的请求。

 USB HUB提供了一种低成本、低复杂度的USB接口扩展方法。HUB的上行PORT面向HOST,下行PORT面向设备(HUB或功能设备)。在下行PORT上,HUB提供了设备连接检测和设备移除检测的能力,并给各下行PORT供电。HUB可以单独使能各下行PORT,不同PORT可以工作在不同的速度等级(高速/全速/低速)。

  HUB由HUB重发器(HUB Repeater)、转发器(Transaction Translator)以及HUB控制器(HUB Controller)三部分组成。HUB Repeater是上行PORT和下行PORT之间的一个协议控制的开关,它负责高速数据包的重生与分发。HUB控制器负责和HOST的通信,HOST通过HUB类请求和HUB控制器通讯,获得关于HUB本身和下行PORT的HUB描述符,进行HUB和下行PORT的监控和管理。转发器提供了从高速和全速/低速通讯的转换能力,通过HUB可以在高速HOST和全速/低速设备之间进行匹配。HUB在硬件上支持Reset、Resume、Suspend。

  重生与分发:指的是HUB Repeater需要识别从上行(下行)PORT上接收到的数据,并分发到下行(上行)PORT。所谓分发主要是指从上行PORT接收到的数据包需要向所有使能的高速下行PORT发送,即广播。

  USB HOST在USB体系中负责设备连接/移除的检测、HOST和设备之间控制流和数据流的管理、传输状态的收集、总线电源的供给。

  USB体系在实现时采用分层的结构,如下图所示:
USB2.0规范

  在HSOT端,应用软件(Client SW)不能直接访问USB总线,而必须通过USB系统软件和USB主机控制器来访问USB总线,在USB总线上和USB设备进行通讯。从逻辑上可以分为功能层、设备层和总线接口层三个层次。其中功能层完成功能级的描述、定义和行为;设备级则完成从功能级到传输级的转换,把一次功能级的行为转换为一次一次的基本传输;USB总线接口层则处理总线上的Bit流,完成数据传输的物理层实现和总线管理。途中黑色箭头代表真实的数据流,灰色箭头代表逻辑上的通讯。

  物理上,USB设备通过分层的星型总线连接到HOST,但在逻辑上HUB是透明的,各USB设备和HOST直接连接,和HOST上的应用软件形成一对一的关系。如下图所示:

USB2.0规范
各应用软件-功能设备对之间的通讯相互独立,应用软件通过USB设备驱动程序(USBD)发起IRQ请求,请求数据传输。主机控制器驱动程序(HCD)接收IRQ请求,并解析成为USB传输和传输事务(Transaction),并对USB系统中的所有传输事务进行任务排定(因为可能同时有多个应用软件发起IRQ请求)。主机控制器(Host Controller)执行排定的传输任务,在同一条共享的USB总线上进行数据包的传输。如下图所示。
USB2.0规范

USB系统中数据的传输,宏观的看来是在HOST和USB功能设备之间进行;微观的看是在应用软件的Buffer和USB功能设备的端点之间进行。一般来说端点都有Buffer,可以认为USB通讯就是应用软件Buffer和设备端点Buffer之间的数据交换,交换的通道称为管道。应用软件通过和设备之间的数据交换来完成设备的控制和数据传输。通常需要多个管道来完成数据交换,因为同一管道只支持一种类型的数据传输。用在一起来对设备进行控制的若干管道称为设备的接口,这就是端点、管道和接口的关系。

一个USB设备可以包括若干个端点,不同的端点以端点编号方向区分。不同端点可以支持不同的传输类型、访问间隔以及最大数据包大小。除端点0外,所有的端点只支持一个方向的数据传输。端点0是一个特殊的端点,它支持双向的控制传输。管道和端点关联,和关联的端点有相同的属性,如支持的传输类型、最大包长度、传输方向等。

四种传输类型

  1. 控制传输:

控制传输是一种可靠的双向传输,一次控制传输可分为三个阶段。第一阶段为从HOST到Device的SETUP事务传输,这个阶段指定了此次控制传输的请求类型;第二阶段为数据阶段,也有些请求没有数据阶段;第三阶段为状态阶段,通过一次IN/OUT传输表明请求是否成功完成。

控制传输通过控制管道在应用软件和Device的控制端点之间进行,控制传输过程中传输的数据是有格式定义的,USB设备或主机可根据格式定义解析获得的数据含义。其他三种传输类型都没有格式定义。

控制传输对于最大包长度有固定的要求。对于高速设备该值为64Byte;对于低速设备该值为8;全速设备可以是8或16或32或64。

最大包长度表征了一个端点单次接收/发送数据的能力,实际上反应的是该端点对应的Buffer的大小。Buffer越大,单次可接收/发送的数据包越大,反之亦反。当通过一个端点进行数据传输时,若数据的大小超过该端点的最大包长度时,需要将数据分成若干个数据包传输,并且要求除最后一个包外,所有的包长度均等于该最大包长度。这也就是说如果一个端点收到/发送了一个长度小于最大包长度的包,即意味着数据传输结束。

控制传输在访问总线时也受到一些限制,如:

l         高速端点的控制传输不能占用超过20%的微帧,全速和低速的则不能超过10%。

l         在一帧内如果有多余的未用时间,并且没有同步和中断传输,可以用来进行控制传输。

  2. 中断传输:

中断传输是一种轮询的传输方式,是一种单向的传输,HOST通过固定的间隔对中断端点进行查询,若有数据传输或可以接收数据则返回数据或发送数据,否则返回NAK,表示尚未准备好。

中断传输的延迟有保证,但并非实时传输,它是一种延迟有限的可靠传输,支持错误重传。

对于高速/全速/低速端点,最大包长度分别可以达到1024/64/8 Bytes。

高速中断传输不得占用超过80%的微帧时间,全速和低速不得超过90%。

中断端点的轮询间隔由在端点描述符中定义,全速端点的轮询间隔可以是1~255mS,低速端点为10~255mS,高速端点为(2interval-1)*125uS,其中interval取1到16之间的值。

除高速高带宽中断端点外,一个微帧内仅允许一次中断事务传输,高速高带宽端点最多可以在一个微帧内进行三次中断事务传输,传输高达3072字节的数据。

所谓单向传输,并不是说该传输只支持一个方向的传输,而是指在某个端点上该传输仅支持一个方向,或输出,或输入。如果需要在两个方向上进行某种单向传输,需要占用两个端点,分别配置成不同的方向,可以拥有相同的端点编号。

  3. 批量传输:

批量传输是一种可靠的单向传输,但延迟没有保证,它尽量利用可以利用的带宽来完成传输,适合数据量比较大的传输。

低速USB设备不支持批量传输,高速批量端点的最大包长度为512,全速批量端点的最大包长度可以为8、16、32、64。

批量传输在访问USB总线时,相对其他传输类型具有最低的优先级,USB HOST总是优先安排其他类型的传输,当总线带宽有富余时才安排批量传输。

高速的批量端点必须支持PING操作,向主机报告端点的状态,NYET表示否定应答,没有准备好接收下一个数据包,ACK表示肯定应答,已经准备好接收下一个数据包。

  4.同步传输:

同步传输是一种实时的、不可靠的传输,不支持错误重发机制。只有高速和全速端点支持同步传输,高速同步端点的最大包长度为1024,低速的为1023。

除高速高带宽同步端点外,一个微帧内仅允许一次同步事务传输,高速高带宽端点最多可以在一个微帧内进行三次同步事务传输,传输高达3072字节的数据。

全速同步传输不得占用超过80%的帧时间,高速同步传输不得占用超过90%的微帧时间。

同步端点的访问也和中断端点一样,有固定的时间间隔限制。

在主机控制器和USB HUB之间还有另外一种传输——分离传输(Split Transaction),它仅在主机控制器和HUB之间执行,通过分离传输,可以允许全速/低速设备连接到高速主机。分离传输对于USB设备来说是透明的、不可见的。

  5.分离传输:顾名思义就是把一次完整的事务传输分成两个事务传输来完成。其出发点是高速传输和全速/低速传输的速度不相等,如果使用一次完整的事务来传输,势必会造成比较长的等待时间,从而降低了高速USB总线的利用率。通过将一次传输分成两此,将令牌(和数据)的传输与响应数据(和握手)的传输分开,这样就可以在中间插入其他高速传输,从而提高总线的利用率。
  不同的传输类型在物理上并没有太大的区别,只是在传输机制、主机安排传输任务、可占用USB带宽的限制以及最大包长度有一定的差异。
到公司入职后,安排的第一件事情是学习PATA/SATA的规范,看了两天,后来说USB的项目比较紧一些,于是转向USB规范的学习。收到邮件后,里边有三个文档,一个是《Universal Serial Bus Specification》,一个是《Universal Host Controller Interface Design Guide》,还有一个是《Enhanced Host Controlelr Interface for Universal Serial Bus》。
      花了三个星期的时间,前面两个星期的效率还可以,看起来比较认真,理解的也相对清楚些,到后来是在是有些看不下去了,以至于想吐的地步,但不管怎么样,总算是基本看完了。
现在做做总结:
首先是《Universal Host Controller Interface Design Guide》,也就是USB2.0的规范。
这篇文献从USB2.0的背景开始,对USB2.0技术的各个方面进行详细的描述和定义。我主要阅读了第4章及其以后的部分。
真要总结起来,恐怕不是这一篇日志就能总结得了的,我也不准备那样,毕竟周立功已经把中文版的书都出版了,且不管翻译的怎么样。下面我就把零碎记录的一些东西录下来吧,顺便想到什么也写下来,当然谈不上系统了。
USB系统在物理连接上是分层的星型拓扑结构,而在逻辑上,所有的USB设备都直接连接到HOST Controller。不管中间接了几个HUB。USB最多支持7层,127个设备。也就是说在一个USB系统中,最多可以有5个HUB级联。
在USB规范中,对传输线和HUB的延迟都有比较严格的定义。
USB总线上数据内容的含义是由USB体系解析的,USB的硬件不负责内容的解析。
USB总线上共有两种数据,一种是流数据(Stream),一种是信息数据(Message)
USB体系可分为三层:
             HOST端------------------------Device端
客户软件(USB应用软件)     功能接口(Interface)
         USB系统软件                   端点(默认端点和其他端点集)
       USB主机控制器                 USB总线接口
端点(Endpoint)是USB通讯模型的终端
多个端点组成接口(interface)
0端点是一个特别的端点,任何USB设备均有0端点,也称为默认端点,主要用于USB设备的配置、命令等。
USB应用软件通过接口访问USB设备,接口又由端点组成,USB通讯在USB主机控制器的控制下按照USB规范定义的格式和方式进行。
USB总线上的数据逐帧传送,高速USB总线上的帧称为微帧(microFrame),周期为125uS,全速以及低速USB总线上的帧周期为1mS。不论高速、全速还是低速总线,帧序号以1mS为单位递增,即连续8个微帧的帧号是一样的。
每个帧(微帧)可以包含多个数据传输,例如可以由若干和同步传输、若干个中断传输以及批量传输构成。
控制传输在端点0进行,主要完成设备的配置、命令发送等。
控制传输由三个步骤组成:令牌+数据+握手,也可能没有数据,而只包括令牌和握手两个阶段。
不论有没有数据,最后均由一个方向和前一阶段相反的握手传输结束,如。
token out (set up) + Data0(out) + IN handshake;
token in(set up) + IN handshake;
token in(set up) + Data1(in) + out handshake(data length = 0);
同步传输是一种实时性极强的传输,没有重传机制,所以是不可靠的。在每一(微)帧的传输任务排定时,同步传输具有最高的优先级。
中断传输是一种延迟有限的传输,具备重传机制,是一种可靠的传输。传输任务排定时优先级低于同步传输,但高于其他两种传输。高速-高带宽端点可以在每个(微)帧中最多进行3次中断传输。
批量传输是一种延迟不确定的传输,这种传输尽量利用带宽进行传输,可以实现较高的速率,比较适合传送大的数据。也是一种可靠的传输。
USB分层结构中,客户软件通过设备驱动程序访问USB设备,设备驱动程序则通过HCD(主机控制器驱动)访问USB总线,完成数据的传输。
USB总线上,数据的传输按照little endian进行,即一个字节中最低有效位在前,最高有效位在后。
Packet是USB总线上数据传输的最小单位。
每个Packet均由sync同步域开始。(KJKJKK for L/F speed (15个KJ)KJKJKJ...KJKK for high-speed)
Packet的格式由USB规范定义,格式如下:
USB2.0规范
USB响应
USB的响应共包括ACK、NAK、NYET、STALL几种。
ACK表示肯定的应答,数据已经被接收,并准备好接收下一个数据包。
NAK表示否定的应答,当前数据包未被接收,希望重传。
NYET表示当前的数据已经被接收,但尚未准备好接收下一个数据包,期待PING测试。
STALL则表示错误或端点被设置STALL。
 USB采用little edian字节顺序,在总线上先传输一个字节的最低有效位,最后传输最高有效位,采用NRZI编码,若遇到连续的6个1要求进行为填充,即插入一个0。
      所有的USB包都由SYNC开始,高速包的SYNC宽度为32bit,全速/低速包的SYNC段度为8bit。实际接收到的SYNC产度由于USB HUB的关系,可能会小于该值。
      USB数据包的格式如下所示:

USB2.0规范

PID表征了数据包的类型,分为令牌(Token)、数据(Data)、握手(Handshacke)以及特殊包4大类,共16种类型的PID。具体定义见英文协议第196页。
      对于令牌包来说,PID之后是7位的地址和4位的端点号。令牌包没有数®据域,以5位的CRC校验和结束。SOF是一类特殊的令牌包,PID后跟的是11位的帧编号。
      对于数据包来说,PID之后直接跟数据域,数据域的长度为N字节,数据域后以16位的CRC校验和结束。
      握手包仅有PID域,没有数据也没有校验和。

分离传输会用到一类特殊的包,Start-Split和Complete-Split包,格式如下:

USB2.0规范

在Start-Split和Complete-Split包中主要指定了此次分离传输所在的HUB的地址和下行端口编号以及端点类型(控制、中断、批量、同步)。以及此次传输中数据包在整个数据中的位置(第一个包、中间的包、末尾的包)。
      握手包包括ACK,NAK,STALL以及NYET四种,其中ACK表示肯定的应答,成功的数据传输;NAK表示否定的应答,失败的数据传输,要求重新传输;STALL表示功能错误或端点被设置了STALL属性;NYET表示尚未准备好,要求等待。
      数据在USB总线上的传输以包为单位,包只能在帧内传输。高速USB总线的帧周期为125uS,全速以及低速USB总线的帧周期为1mS。帧的起始由一个特定的包(SOF包)表示,帧尾为EOF。EOF不是一个包,而是一种电平状态,EOF期间不允许有数据传输。

注意:虽然高速USB总线和全速/低速USB总线的帧周期不一样,当时SOF包中帧编号的增加速度是一样的,因为在高速USB系统中,SOF包中帧编号实际上取得是计数器的高11位,最低三位作为微帧编号没有使用,因此其帧编号的增加周期也为1mS。

USB Firmware的流程(USB固件程序解析)

应一位朋友的邀请,准备把USB Firmware的流程写一写。
首先声明:这都是我这个菜鸟的一点认识,如果有不准确的地方,请大家多多包涵。
通常来说USB设备(这里只分析USB设备,而不针对USB HOST,USB OTG和USB HUB)内部都有一片USB的芯片和一个MCU,有些当然有些厂商提供的USB芯片已经集成了MCU在里边,如Cypress的CY68013就是这样的。这里考虑MCU和USB芯片分开的情况吧,集成的也类似,大家可以自己去分析。USB芯片完成USB底层的事物,接收的时候:将接收到的USB串行数据识别出来,解包后存放在内部的缓存中,然后通过中断的方式告知MCU收到数据包了,MCU通过和USB芯片的并行或串行接口读回接收到的数据并进行相应的分析和处理;发送数据的时候,MCU将需要发送的数据通过和USB芯片的接口写入到USB芯片内部的缓存,写入完成后,一般来说USB芯片会在接收到来自HOST的IN令牌包时,将缓存中的数据送到USB总线上去。当发送完成后,通常USB芯片也可以通过中断的方式告知MCU。
从这里看出,USB芯片只是完成数据的解包和打包,并不对数据进行任何分析和处理,数据包的分析和处理都是由MCU完成的。具体来说是由运行在MCU中的程序,也就是通常所说的USB Firmware或者说USB固件程序完成的。
首先来分析一次简单的从HOST到Device的数据传输,即OUT型的传输,假设传输类型为BULK。
USB传输只能由HOST发起,HOST需要向Device发送一个OUT令牌包。在这个包里指定了接受数据的设备地址、端点。然后将数据包发送到USB总线上。不是目的接收器件的USB设备不会响应该数据包,目的接收设备如果能接收该数据包,则以ACK握手包响应,如果不能接收该数据包,则以NAK握手包响应。
在上述过程中,USB芯片会在接收完数据包后中断MCU,然后MCU读取缓存在USB芯片中的数据包,再决定回复ACK,或者是NAK。
以上只是一次简单的BULK OUT传输,对于BULK IN传输,HOST先发送一个IN的令牌包,USB芯片接收到该令牌包后会中断MCU,MCU如果有数据发回HOST,则将数据写入USB芯片内对应断点的缓存,然后USB芯片会自动将数据发送至USB总线。并等待接收来自HOST的握手包。
对于BLUK、Interrupt以及同步传输,传输过程都类似,整个传输过程由令牌包、数据包以及握手包组成。
对于控制传输,一次传输由三个阶段组成,即Setup阶段、可选的数据阶段以及状态阶段。
其中Setup阶段为一次OUT型的传输,HOST将8个字节的SETUP数据包发送给设备。这8个字节指定了这次控制传输的请求类型。Device会根据这8个字节做出相应的Action。
第二个阶段为数据阶段,有些控制传输没有这个阶段,如Set Address请求。
数据阶段,HOST将数据通过OUT型传输发送给Device,或者通过IN型传输向Device请求数据。
第三个阶段为状态阶段,即得到这次控制传输的状态,确认这次传输是否正常完成。HOST或者Device以一个长度为0的空数据包表示肯定的应答。
USB Firmware中大部分程序都在处理控制传输,具体来说是11种标准请求以及针对具体设备的类请求,如Mass Storage 类的请求,还有些厂商自定义的请求。
USB Firmware的设计和调试首先应从一次基本的传输开始。要能正常的完成一次传输,尤其是控制传输,否则连设备的枚举都不能完成,也就是说设备不能被计算机正确识别。
下接(二)
 

USB Firmware的流程(二)topone发表于2008-7-21 20:59:00

USB设备上电以后,固件程序就开始运行,首先要做的第一件事情自然是初始化,包括设备自身逻辑的初始化和USB芯片的初始化。
一般来说,USB固件均被设计成为前后台的方式,前台程序为一个大的死循环,后台则为中断处理函数。当USB芯片产生中断信号时,微处理器进入到中断处理程序,并读取USB芯片的中断标记,判断中断的类型(如传输错误、收到Setup包、收到令牌包、传输完成等),然后设置相应的标志位。存储该标志位的变量应该是一个全局变量。前台程序中,固件不断的检测标志位,判断是否有中断事件发生,如果有的话则进入到相应的时间处理函数中。
前面已经说过,USB固件程序大部分都是在处理来自HOST的请求,也就是HOST发来的SETUP数据包。当前台程序检测到SETUP事件时,会先从USB芯片的缓存中读回8个字节的SETUP包,然后根据USB规范中定义的结构,对数据包尽心解析,然后进行到相应的请求处理函数。基本可以总结成为如下的结构。
========后台============  =============前台==================
中断处理函数(ISR)                                   循环{
        读USB芯片的中断寄存器                                【设备事务】
        清USB芯片中断                                               如果有USB中断标志被置位
        判断中断类型                                                      {中断事件处理
        置中断标志                                                                   读SETUP包
=======================                                         解析SETUP包
                                                                                               调用相应的请求处理函数
                                                                                        }
                                                                                   }
                                                        ===================================
在请求函数处理函数中,固件程序或将相应的描述符写入到USB芯片的断点缓冲,然后发送到HOST,或者通过从USB芯片的断点缓存中读回HOST发来的数据。下面来说明一次典型的getdescriptor请求。
HOST发送SETUP令牌包--------->引起USB芯片中断MCU,中断事件为SETUP,MCU被中断,并设置中断标志
HOST发送SETUP数据包--------->USB芯片接收数据包,并存放在断点缓存中,并自动以ACK响应主机
                                                           固件中,MCU检测到中断事件,且类型为SETUP事件,进入到SETUP事件处理函数,读回SETUP数据包,并解析之,将设备描述符填入到USB芯片的缓存,等待数据发送完成。
HOST发送IN令牌包----------------->如果此时MCU已经完成数据的填充,则USB芯片将数据发回HOST,否则以NAK响应。
循环上一步骤,直至数据被发送完成。
HOST收到描述符,并以ACK响应USB设备------->此时USB芯片中断MCU,MCU将从此中断得知传输完成。MCU设置USB芯片,在收到下一个IN令牌包时自动回复一个长度为0的数据包。
HOST发送IN令牌包---------------->USB芯片自动回复一个长度为0的数据包。
HOST收到数据包,并回ACK。 -----------------> USB请求完成
                                                         
上面【设备事务】指的是USB设备自身的事务,如AD采样数据的读取、处理等。
以上即为USB固件程序的基本框架,完整的固件程序要处理的中断事务很多,但是基本的处理过程都是相似的。各USB子类设备,如大容量存储器、HID设备还有各自的请求类请需要处理。