C6748_USB(1)-USB协议

时间:2024-03-02 10:05:45

内容参考:https://wenku.baidu.com/view/d9a5b9c06137ee06eff918b5.html                  https://blog.csdn.net/songze_lee/article/details/77658094

推荐网址:http://www.doc88.com/p-241590778604.html

1 USB接口总线

1.1 USB接口

    USB(Universal Serial Bus)全称通用串口总线,USB为解决即插即用PnP(Plug and Play)需求而诞生,支持热插拔。热插拔。它能让你在不断电的情况下,插拔USB设备。如果要支持热插拔,必须在VBUS、DP、DM三根线上,加上过压、过流保护,在未上电时DP和DM要保持高阻态。另外,要利用金手指长短来控制上电顺序,插入时首先让电源线接通,让电源稳定之后,再接通信号线,拔出时顺序正好相反。这样有效防护接口被损坏。

    USB协议版本有USB1.0、USB1.1、USB2.0、USB3.1等,USB2.0目前比较常用,以下以2.0为主介绍。由于USB是主从模式的结构(所有的通信都由主机发起,设备不能发起),故设备与设备之间、主机与主机之间不能互连,为解决这个问题,扩大USB的应用范围,出现了USB OTG,全拼 ON The Go。USB OTG 同一个设备,在不同的场合下可行在主机和从机之间切换。USB家族成员如下图所示:

  • USB Host,即USB主机,一般是PC机。
  • USB Device,即USB设备,有USB键盘、U盘等,而USB Hub集线器是一种特殊的USB设备。
  • USB OTG,OTG即On-The-Go,同时具备USB主机和USB设备的功能,数码相机就带有OTG的功能

    USB体系包括"主机"、"设备"、"物理连接"三个部分,其中主机是一个提供USB接口及接口管理能力的硬件、软件的复合体,可以是PC,也可以是OTG设备。一个USB系统中仅有一个USB主机;设备包括USB功能设备和USB集线器,最多支持127个设备,这是因为协议规定了每个USB设备具有一个7bit的地址(取值范围0~127,而地址0是保留给未初始化的设备使用的);物理连接指的是USB的传输线使用屏蔽的双绞线。

    标准的USB连接器有A型、B型、Mini A/B型和Micro-A/B型,每个型号又分为插头和插座。标准的USB2.0连接线都是四线,但MINI USB使用5条线,增加了一条ID线(主从识别)。

     

 

1.2 USB特点

    USB1.0和USB1.1支持1.5Mb/s的低速模式和12Mb/bs的全速模式。在USB2.0以上支持480Mb/s的高速模式。其中在USB的低速和全速模式下,采用的是电压传输方式,高速模式采用的是电流传输模式。应用如下:

1.2.1  usb2.0、usb3.0、usb3.1、type-c 接口含义与区别

  • usb3.0 比2.0的传输速率快,充电快,能向下兼容2.0
  • usb3.1 通常是指 usb3.1 gen2,比3.0的传输速率更快、充电更快,同兼容
  • type-c 通常是指 usb3.1的一种接口形状,总共三大类,c就是第三大类

usb2.0

  • 理论传输速率480Mbps,即60MB/s
  • 四引脚
  • 供电最高允许标准5V/0.5A
  • USB 2.0基于半双工二线制总线,两根线的差分信号来传输数据,只能提供单向数据流传输

usb3.0

  • 理论传输速率5.0Gbps
  • 采用了8/10b的编码方式,将8位的数据编码成10位来发送,即500MB/s
    • 关于8/10b编码方式看这里:https://baike.baidu.com/item/8B/10B/9125856、https://zh.wikipedia.org/wiki/8b/10b
  • 9引脚,其中4个引脚的位置与usb2.0位置相同,也是其可以兼容usb2.0的原因
    • 注意,这里说的兼容只是说能物理兼容插进去,传输速度肯定还是2.0的效果
    • 里面的5根线路中2根用来发送数据,另2根用来接收数据,还有1根是地线。也就是说,USB 3.0可以同步全速地进行读写操作
  • 供电最高允许标准5V/0.9A
  • USB 3.0采用了TxRx四线制差分信号线,类似于PCIe总线,故而支持双向并发数据流传输,为全双工传输。

usb3.1

  usb3.1并不像2.0、3.0那样是即使技术标准也是实际的插口,usb3.1只是一个标准,不代表实际的插口

  包括两种技术标准:usb3.1 gen1,usb3.1 gen2

  和三种接口标准:Type-A(Standard-A)、Type-B(Micro-B)以及Type-C

先介绍两种技术标准:

  • usb3.1 gen1:技术标准基本与usb3.0相同,没有很大提升(可以当做就是3.0)
  • usb3.1 gen2:才是真正的usb3.1。我们通常说的usb3.1,就是指的usb3.1 gen2。下面介绍的都是gen2的技术标准:  
  • 理论传输速率增加到10.0Gbps
    • 使用128b/132b编码,在132bit数据中,只需使用4bit做为检查码,编码损耗相比于usb3.0的20%(2/10)下降为约3%(4/132),大约为1.21GB/s
    • 供电最高允许标准20V/5A
    • 新增USB A/V 3.1 影音传输规范
    • 标签从3.0的"SuperSpeed"更新为"SuperSpeed+"

三种接口标准:

  从左到右依次是type-a、b、c

  • type-a:与普通usb接口外设形状相
  • type-b:外部设备多采用,比如打印机,显示器等,和一些android手机
    • type-b有两种细分形状:Mini USB 和 Micro USB,这两种都有各自的 A 和 B 形状(比较乱),主要用外设形状解决了防误插(与传统的长方形不同,为近似梯形或边缘缺角,方便识别正反)
  • type-c:"采用了 usb3.1 gen2 技术标准的 type-c 型接口",技术指标和usb3.1 gen2相同。同时还有一个优势:不会插反!(上下两排线,引脚设计中心对称)

注:

    type-c实现usb3.1不是强制规范,没有规定说用type-c口一定就是usb3.1,也没有规定说用usb3.1一定要用type-c

1.3 USB设备供电方式

    USB设备有两种供电方式 :

  • 自供电设备:设备从外部电源获取工作电压
  • 总线供电设备:设备从VBUS(5v) 取电

    对总线供电设备,区分低功耗和高功耗USB设备

  • 低功耗总线供电设备:最大功耗不超过100mA
  • 高功耗总线供电设备: 枚举时最大功耗不超过100mA,枚举完成配置结束后功耗不超过500mA

    设备在枚举过程中,通过设备的配置描述符向主机报告它的供电配置(自供电/总线供电)以及它的功耗要求

 

1.4 USB总线信号

USB使用的是差分传输模式,两个数据线D+和D-

差分信号1:D+ > VOH(min) (2.8V) 且D- < VOL(max)(0.3V)

差分信号0:D- > VOH and D+ < VOL

1.4.1 J态、K态、SEO态

    USB协议中是是用J、K、SEO状态来表示总线状态的(J状态:(LS-低速:差分0;FS-全速:差分1) K状态:(LS:差分1;FS:差分0),具体的状态如下: 

(1)低速设备:

  • J态: D+ ="0",D- ="1"
  • K态: D+ ="1",D- ="0"
  • SE0态:D+ ="0",D- ="0"

从J到K或者从K到J,信号翻转,说明发送的是信号0

从J到J或者从K到K,信号保持不变,说明发送的是信号1。这就是差分信号0/1的发送。

(2)高速设备的J和K相反:

  • 低速下: D+为"0",D-为"1"是为"J"状态,"K"状态相反;
  • 全速/高速下:D+为"1",D-为"0"是为"J"状态,"K"状态相反;

1.4.2 空闲状态(IDLE态)

  • 低速下空闲状态为"K"状态;
  • 全速下空闲状态为"J"状态;
  • 高速下空闲状态为"SE0"状态;

1.4.3 reset和suspend(挂起)状态

  • 对于全速操作,SE0表示为复位和EOP,持续时间大于2.5us表示总线复位;
  • 对于高速操作,SE0维持3ms~3.125ms,设备进入全速状态,全速后100us~875us内采样,如果继续维持SE0,则设备总线复位,开始高速握手;若变为"J"状态,则进入挂起状态"suspend"。

1.4.4 高速握手条件

  • 设备处于挂起状态,若出现SE0则立即开始高速握手;
  • 设备处于全速,SE0持续2.5us,则开始高速握手;
  • 设别处于高速,SE0持续3.0ms,且继续持续,则开始高速握手。

1.4.5 信号状态电平

  • Reset信号:主机在要和设备通信之前会发送Reset信号来把设备配置到默认的未配置状态。即SE0状态(D+ 和D- 都是低电平)保持10ms以上。
  • Idle状态:J状态数据发、送前后总线的状态
  • Suspend状态:3ms以上的J状态
  • SYNC: 3个KJ状态切换,后跟随2位时间的K状态(看到的波形变化是总线上发送0000 0001经过NRZI编码后的波形)
  • Resume信号:20ms的K状态+低速EOP

    主机在挂起设备后可通过翻转数据线上的极性并保持20ms来唤醒设备,并以低速EOP信号结尾,带远程唤醒功能的设备还可自己发起该唤醒信号;前提是设备已进入idle状态至少5ms,然后发出唤醒K信号,维持1ms到15ms并由主机在1ms内接管来继续驱动唤醒信号

  • SOP:从IDLE状态切换到K状态
  • EOP:持续2位时间的SE0信号,后跟随1位时间的J状态

1.5 差分信号技术的特点

    传统的传输方式大多采用"正信号"或者"负信号",二进制表达机制,这些信号利用单线传输。用不同的信号电平范围来分别表示1或者0,他们之间有一个临界值,如果在数据传输过程中受到强干扰,高低电平突破临界值,那么会造成数据传输出错。差分信号技术最大的特是:必须使用两条线路才能表达一个比特位,用两条线路传输信号的压差作为判断1还是0的依据。这种做法的优点是具有极强的抗干扰性。对于外界的强烈干扰,两条线路对应的电平会出现同样的变化,这样保证了电压差值时钟相对稳定,因此数据的准确性不会因为干扰噪声而有所降低。

1.6 USB插入检测和速度检测

    主机通过在设备D+或D-上的1.5K上拉电阻来检测设备的连接和断开事件,并由此判别低速和全速设备。当没有USB来连接时,由于主控器的D+和D-上的下拉电阻使得这条数据线上的电压是近地的,当连接设备时,通过检测设备上的D+和D-的电压,在D+/D-上出现大小为(Vcc*15/(15+1.5))直流高电平电压,而其他线保持接地时,就可以知道全速/低速设备了。

  USB高速设备首先被识别成全速设备,然后通过集线器和设备两者的确认,再切换到高速模式下。在高速模式下,十点六传输模式,这是要将D+上的上拉电阻断开。

一个简单的实验:用一个10K的上拉电阻接在USB的+5V和D+(或者D-)上,Windoes也会提示发现新硬件,但无法找到驱动程序,这是因为D+或D-被拉高,集线器认为有设备插入了,它就报告给了主机;但主机获取数据却没有响应,就会得到一个无法识别的USB设备,这是设备管理器显示一个未知的USB设备,并且其VID和PID都为0(枚举不成功)。

USB连接和断开连接:

  • 设备连上主机时(连接)

    当主机检测到某一个数据线电平拉高并保持了一段时间,就认为有设备连上来了

主机必需在驱动SE0状态以复位设备之前,立刻采样总线状态来判断设备的速度

  • 没有设备连上主机时(断开)

    D+和D-数据线上的下拉电阻起作用,使得二者都在低电平;主机端看来就是个SE0状态;同样地,当数据线上的SE0状态持续一段时间了,就被主机认为是断开状态

1.7 数据编解码和位填充

USB采用NRZI(非归零编码)对发送的数据包进行编码

    输入数据0, 编码成"电平翻转"

    输入数据1, 编码成"电平不变"

编码出来的序列,高电平:J状态;低电平:K状态

  USB信号线中无单独的时钟信号线,时钟信号是通过调制和差分数据一同被传送出去,时钟信号被转换成NRZI码。每一个数据包中附有同步信号以使的接收方可还原出时钟信号。

  NRZI没有自同步特性,在USB中,每个数据包的最开始处都有一个同步域(SYNC),其值为00000001,在经过NRZI编码后,就是一串方波,接收方可能过这个同步头来计算发送方的频率,以便用这个频率来继续采样数据信号。由于USB所采用的NRZI编码中,每当逻辑0时就会进行电平翻转,那么接收方可通过这个不断翻转的信号来调整同步的频率,保证数据的正确传输。

  但这仍然存在问题,一旦电平长时间保持不变时,我们无法知道到时发送的是100个逻辑1,还是1000个逻辑1,即使传输的是100个逻辑1,但接收方与发送方的频率相差了100分之1,那么也还是存在可能把数据采集成为99或者101。而USB中采用了Bit-Stuffing位填充处理,即在连续发送6个1后面会插入1个0,强制使发送信号进行翻转,从而让接收方调整频率,同步接收。而接收方在接收时只要接收到连续的6个1后,直接将后面的0删除即可恢复数据的原貌。

  经过位填充的数据,由串行接口引擎(SIE)将数据串行化和NRZI编码后,发送到USB的差分线上,在接收端,刚好是一个相反的过程,由SIE将数据并行化(反串行化),恢复出原来的数据。通常,我们使用的现成的USB芯片,如位填充,串行化、反串行化、CRC校验等处理过程,芯片内部的硬件已经帮我们做好,因此不必关心这些细节。

  注意USB模块虽然需要一个单独的48MHz的时钟信号,但是它应该不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟

 

1.8 主机与设备之间的通信模型

    上图展示了USB主机和USB设备之间的数据传输过程。在设备端,USB设备将非USB格式的数据进行打包处理,转换成USB格式的数据包,然后传递到链路层,经过硬件处理、传递到物理层,由物理层通过PHY以数据流的形式传输到主机。

    

2. USB传输

    USB进行一次数据传输遵循的"协议"简单来说就是:

(1)主机给从机发送数据:

①首先,主机发第1个packet给从机,声明数据传送方向,数据传输地址,数据传输类型。

②其次,主机发第2个至第n个packet载有实际数据

③最后,从机返回一个packet是一个ACK包,报告数据传输的结果,比如接受出错或成功等信息,这样主机就可以借此了解到这次传输情况,从而有可能来作出相应措施如决定是否重发。

(2)从机给主机发送数据:

①首先,从机发第1个packet给主机,声明数据传送方向,数据传输地址,数据传输类型。

②其次,从机收到主机送来的第一个packet后,再发第2个至第n个packet载有实际数据.

③最后,主机返回一个packet是一个ACK包,报告数据传输的结果,比如接受出错或成功等信息,这样从机就可以借此了解到这次传输情况,从而有可能来作出相应措施如决定是否重发。

    USB数据是由二进制数字串构成的,首先数字串构成域(有七种),域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、等时传输、批量传输和控制传输)

    USB主机在USB设备和USB主机之间发起的传输过程,称为事务。每次事务以2到3个数据包的形式进行USB总线传输。每个数据包包含2到3个步骤:

  • USB主机控制器向USB设备发出命令
  • USB控制器和USB设备之间传递读写请求,其方向取决于第一部分的命令是读还是写
  • 握手信号。

    USB主机控制器向USB设备发送事务类型请求,通过分组标识符(PID)来进行识别

    传输又分为四种类型:批量传输、等时(同步)传输、中断传输、控制传输。

注意:USB传输数据先发数据低位再发高位数据

2.1 包

2.1.1 包的组成

    包(Packet)是USB系统信息传输的基本单元,所有数据都是经过打包后在总线上传输的。数据在 USB总线上的传输以包为单位,包只能在帧内传输。高速USB 总线的帧周期为125us,全速以及低速 USB 总线的帧周期为 1ms。

    帧的起始由一个特定的包(SOF 包)表示,帧尾为 EOFEOF不是一个包,而是一种电平状态,EOF期间不允许有数据传输。

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

    USB的包(Packet)包括五个部分组成,即同步字段(SYNC)、包标识符段(PID)、数据字段、循环冗余校验字段(SRC)和包结尾字段(EOP),包的基本格式为(注意包中的数据都是原始数据,没有经过NRZI编码):

包的内容:

    包是USB总线上数据传输的最小单位,不能被打断或干扰,否则会引发错误。若干个数据包组成一次事务传输,一次事务传输也不能打断,属于一次事务传输的几个包必须连续,不能跨帧完成。一次传输由一次到多次事务传输构成,可以跨帧完成

1)SYNC字段:同步域,由8位组成,作为每个数据包的前导,用来产生同步作用,使USB设备与总线的包传输率同步,对于低速和全速设备,它的数值固定为00000001.该数据通过NRZI编码后,就是一串0101010的方波,而发送方波的频率,就是发送数据的波特率。对于高速设备,同步域使用的是31个0,后面跟随1个1.

2)PID字段用来表示数据封包的类型。包标识符的校验字段是通过对类型字段的每个位反码产生的,PID字符如下图所示:

    这里只用(PID0~4),PID4~7是PID0~4的取反,用来校验PID

    PID1~0:01 令牌包、11 数据包、10 握手包、00 特殊包

  其中PID传送的前两位(PID<0:1>指出了其属于哪个组),这说明了PID的编码分布

3)数据字段:用来携带主机和设备之间传递的信息,其内容和长度根据包标识符、传输类型的不同而各不同。在USB包中,数据字段可以包括设备地址、端点号、帧序列号以及数据等内容。在总线传输中总是先传输字节的最低位,最后传输字节的最高位。

  • 设备地址(ADDR)数据域:ADDR数据域由7位组成,代表了设备在主机上的地址,地址000 0000被命名为零地址,是任何一个设备第一次连接到主机时,在被主机配置、枚举前的默认地址,可用来寻址多达127个外围设备。
  • 端点(ENDP)数据域.:ENDP数据域由4位组成。通过4个位最多可寻址出16个端点。这个ENDP数据域仅用在IN、OUT与SETUP令牌信息包中。对于慢速设备可支持端点0以及端点1作为终端传输模式,而全速设备则可以拥有16个输入端点(IN)与16个输出端点(OUT)共32个端点。
  • 帧序列号(FRAM)域:帧号字段用于指出当前帧的帧号,它仅在每帧/小帧开始的SOF令牌包中被发送,其数据位长度为11位,每传输一帧,主机就将其内容加1,最大数值为0X7FF,当帧序列号达到最大数时将自动从0开始循环。
  • 数据域:长度为0到1023字节(实时传输),它仅存在于DATA信息包中,根据不同的传输类型,拥有不同的字节大小,但必须为整个字节的长度。

4)CRC字段:由不同数目的位组成。根据不同的信息包的类型,CRC数据域由不同数目的位所组成。其中重要的数据信息包采用CRC16的数据域(16个位),其余的信息包类型采用CRC5的数据域(5个位)。其中的循环冗余码校验CRC,是一种错误检测技术。由于数据在传输时,有时候会发生错误,因此CRC可根据数据算出一个校验值,然后依此判断数据的正确性。CRC只校验PID之后的数据,不包括PID本身,因为PID本身通过四个取反位校验。

5)EOP段:即发送方在包的结尾发出包结尾信号。USB主机根据EOP判断数据包的结束。全速/低速设备的EOP是一个大约为2个数据位宽度的单端0(SE0)信号,高速设备用故意的位填充错误来表示,用CRC判断,CRC校验正确,则为位填充错误EOP,否则为传输错误。

2.1.2 常用包的类型

    Packet分四大类: 令牌 (Token) 、Packet 帧首 (Start of Frame) 、Packet 数据 (Data) 、Packet 握手 (Handshake) Packet

①令牌包(Token Packet):

    在USB系统中,只有主机才能发出令牌包。令牌包定义了数据传输的类型,它是事务处理的第一个阶段,用来启动一次USB传输。令牌包中较为重要的是SRTUP、IN和OUT这三个令牌包。他们用来在根集线器和设备端点之间建立数据传输。

  • 输出(OUT)令牌包:用来通知设备将要输出一个数据包
  • 输入(IN)令牌包:用来通知设备返回一个数据包
  • 建立(SETUP)令牌包:只用在控制传输中,和输出令牌包作用一样,也是通知设备将要输出一个数据包,两者区别在于:

    SETUP令牌包后只使用DATA0数据包,且只能发送到设备的控制端点,并且设备必须要接收,而OUT令牌包没有这些限制。其格式如下:

例子:

②SOF Packet

    SOF包由Host发送给Device,在每帧(或微帧)开始时发送,以广播的形式发送,所有USB全速设备和高速设备都可以接收到SOF包。

    1) 对于full-speed总线,每隔1.00 ms ±0.0005 ms发送一次;

    2) 对于high-speed总线,每隔125 μs ±0.0625 μs发送一次;

  SOF包以相对于每帧的开始精确计算的时间间隔发送SOF记号和伴随的帧数,包括集线器的所有全速/高速设备都可以接收到SOF包。SOF包不会使得接收功能部件产生返回包,因此,不能保证向任何给定的设备发送SOF都能被接收到。当设备探测到SOF的PID时,会被告知发生了SOF。

例子:

0xA5:1010 0101:对应上面PID表可知是帧起始包

③Data Packet

    数据包含有4个域:SYNC、PID、DATA和CRC16。有四种类型的数据包:DATA0, DATA1, DATA2,and MDATA,且由PID来区分。DATA0和DATA1被定义为支持数据切换同步(data toggle synchronization)。在USB1.1协议中,只有两种数据包:DATA0和DATA1,USB2.0中增加了DATA2和MDATA,主要用于高速分裂事务和高速高带宽同步传输中。

    DATA数据域的位值是根据USB设备的传输速度及传输类型而定的,且须以8字节为基本单位。也就是传输的数据不足8字节的。或是传输到最后所剩余的也不足8字节的,仍需传输8字节的数据域。格式如下:

  主机和设备都会维护自己的一个数据包类型切换机制:当数据成功发送或者接收时,数据包类型会进行切换。当检测到对方所使用的数据包类型不对时(未切换),USB系统会认为这发生了一个错误,并试图从错误中恢复。数据包类型不匹配主要发生在握手包被损坏的情况,当一端已经正确接收到数据并返回确认信号时,确认信号却在传输过程中被损坏。此时另一端就无法知道刚刚发送的数据是否已经成功,由于未接到返回确认信号,则只好保持自己的数据包类型不变,这时就要通过对方下一次的数据包类型判断传输是否成功。如果对方下一次使用的数据包类型和自己的不一致,则可以确定自己刚刚已经成功发送(因为对方已经做了数据切换,只有正确接收才会如此);如果下一次对方发送的数据和自己一致。则说明刚刚发送的数据包没有成功。

例子:

④Handshake Packet 

    握手信息包是最简单的信息包类型。在这个握手信息包中仅包含一个PID数据域而已,其格式如下:

  握手包主要用来报告数据事务的状态,还能表示数据成功接收、命令的接收或拒绝、流控制和停止条件,只有支持流控制的事务类型才能返回握手信号

  主机和设备都可以使用ACK来确认,而NAK、STALL、NYET只有设备可以返回,主机不能使用这些握手包。NYET只在USB2.0的高速设备的输出事务中使用,表示本次数据成功接收,但没有足够的空间接收下一次数据,主机在下一次输出数据时,将先使用PING令牌包试探设备是否有空间接收数据,避免不必要的带宽浪费。

  注意,当USB主机或设备检测到数据传输错误时(如CRC校验错、PID校验错、位填充错误时),将什么都不返回,这是等待接收握手信号包的一方将不会收到握手包而等待超时。

例子:

 2.1.3  数据包的处理

  数据包处理的很多过程在USB接口芯片中都已经处理好,故我们不必关心这些细节。一般的USB接口芯片会完成如CRC校验、位填充、数据切换、握手等协议的处理。

  当USB接口芯片正确接收到数据时,如有空间保存,则将数据保存并返回ACK,同时设置一个标志表示已经正确接收到数据;如果没有空间保存,则自动返回一个NAK。

  收到输入请求时,如有数据需要发送,则发送数据,并等待接收ACK。只有当数据成功发送出去(即接收到应答信号ACK)之后,它才设置标志,表示数据已经成功发送;如果无数据需要发送,则地洞返回NAK。

  通常只需要根据芯片提供的一些标志,准备要发送的数据到端点,或从端点读取接收到的数据即可。所要发送的数据是指数据包中的数据,至于同步域、包标识、地址、端点、CRC等是看不到的,在BUS Hound(USB抓包工具)中抓到的数据也是如此,仅是数据包。在USB接口芯片中,通过一些标志,我们知道哪个端点接收或成功发送了数据。

 

2.2 事务

    在USB上数据信息的一次接收或发送的处理过程称为事务处理(Transation)。事务通常由三个包组成:令牌包、数据包和握手包。

  • 令牌包用来启动一个事务,总由主机发送;
  • 数据包传送数据,可以由主机到设备或从设备到主机,方向由令牌包来指定。
  • 握手包的发送着通常时数据的接收者,当数据正确接收时,发送握手信号,设备也可发送NAK握手包表示数据未准备好。

    Transaction可以分成三类 :

  • Setup transaction:主机用来向设备发送控制命令
  • Data IN transaction:主机用来从设备读取数据
  • Data OUT transaction:主机用来向设备发送数据

    在OUT和SETUP事务处理中,紧接在SETUP和OUT包后的是DATA包,DATA0和DATA1包是接替地发送的,在DATA包后面,设备将回应一个握手信号,(如果设备可以接受数据,就回应ACK包;如果设备忙,则回应NAK包;如果设备出错,则回应STALL包)。

    在IN事务中,在IN包后面是设备发送的DATA包或NAK包或STALL包,(若设备忙或者出错,就发送NAK包或STALL包给主机;若设备数据准备好发送,则发送DATA包),DATA0和DATA1包也是交替发送的,紧接着DATA包后面的是主机发送给设备的握手包。(ACK表示主机可以接收数据,NAK包代表主机忙,STALL代表主机出错

例子:

1)输入(IN)事务处理:(USB主机从设备接收数据包)

①正常的输入事务处理

②设备忙时的输入事务处理

③设备出错时的输入事务处理

2)输出(OUT)事务处理

①正常的输出事务处理

②设备忙时的输出事务处理

③设备出错时的输出事务处理

3)设置(SETUP)事务处理

①正常的设置事务处理

②设备忙时的设置事务处理

③设备出错时的设置事务处理

 

2.3 传输

    USB协议定义了四种传输类型:控制传输、中断传输、批量传输以及等时传输。其中,批量传输、等时传输、中断传输每传输一次数据就是一个事务控制传输分为2~3个阶段:建立阶段、数据阶段(无数据控制没有此阶段)以及状态阶段,其中建立阶段和状态阶段分别是一个事务,数据阶段则可能包含多个事务。根据数据阶段的数据传输方向,控制传输又可分为3种类型:控制读取(读取USB描述符)、控制写入(配置USB设备)以及无数据控制。

①控制传输(Control Transfers): 非周期性,突发。用于命令和状态的传输。

②中断传输(Interrupt Transfers): 周期性,低频率,允许有限延迟的通信 如人机接口设备(HID)中的鼠标、键盘、轨迹球等

③批量(大容量数据)传输(Bulk Transfers): 非周期性,突发大容量数据的通信,数据可以占用任意带宽,并容忍延迟 。如USB打印机、扫描仪、大容量储存设备等

④等时(同步)传输(Isochronous Transfers): 周期性、持续性的传输,用于传输与时效相关的信息,并且在数据中保存时间戳的信息 ,如音频视频设备

    其中,批量传输、同步传输和中断传输每传输一次数据都是一个事务,控制传输包括3个过程,建立过程和状态过程分别是一个事务,数据过程则可能包含多个事务。

2.3.1 控制传输

    控制传输时USB传输中最重要的传输,包含3种传输类型:控制读取、控制写入以及无数据控制。这3种控制传输类型又可分为2~3个过程:(1)设置过程(2)数据过程(可选)(3)状态过程.

  建立过程使用一个建立事务,是一个输出数据的过程。控制传输和批量传输的输出事务不同,首先令牌包使用SETUP令牌包,其次数据包类型,SETUP只能使用DATA0包,最后是握手包,设备只能使用ACK来应答(除非是错了、不应答),而不能使用NAK或STALL,即设备必须要接收建立事务的数据。

(1)设置过程

    主机从USB获得配置信息,并设置设备的配置值。

    设置阶段的数据交换包含SETUP令牌封包,其后是DATA0数据包以及ACK握手包。它的作用是执行一个设置的数据交换,并定义此控制传输的内容(即:在Data Stage中IN或OUT的data包个数,及发送方向,在Setup Stage已经被设定)。

(2)数据传输过程

    该阶段用来传输主机和设备之间的数据。其数据传输过程为前面提到的事务处理过程。

    而根据数据阶段的数据传输的方向,控制传输又可分为3种类型:1) 控制读取(读取USB描述符);2) 控制写入(配置USB设备);3) 无数据控制

  数据过程的所有数据事务必须是同一传输方向,一旦数据传输方向发生改变,就会认为是进入状态阶段。数据过程的第一个包必须是DATA1包,然后每次正确传输一个数据包后就在DATA0和DATA1之间替换。

 

(3)状态过程

    状态过程用来表示整个传输的过程已完全结束。(过程类似数据传输过程,但传输方向相反,且状态过程只使用DATA1包).

    状态传输的方向必须与数据传输方向相反,即原来是IN令牌包,则这个阶段应为OUT令牌包。对于控制读取而言,主机会发送OUT令牌包,其后为0长度的DATA1封包,此时,设备也会做出相对应的动作,送ACK、NAK或STALL握手封包。对于控制写入传输,主机会送出IN令牌包,然后设备送出表示完成阶段的0长度的DATA1封包,主机再做出相应的动作;送ACK、NAK或STALL封包。

以高速设备的最大数据包长度64字节为例 :

  • 要传输250字节,拆分成4个packet

  • 要传输正好256字节,通过最后一个0字节包告诉设备传输完成

2.3.2 中断传输

    中断传输方式总是相对于设备查询的,以确定是否有数据需要传输,因此中断传输的方向总为从USB设备到主机。中断传输由IN或OUT事务组成。中断端点在端点描述符中要报告它的查询间隔,主机会保证在小于这个时间间隔的范围内安排一次传输。这里说的中断与硬件上的中断不同,他不是由设备主动发起的一个中断请求,而是由主机保证不大于某个时间间隔内安排一次传输。

    中断传输在流程上除不支持PING 之外,其他的跟批量传输是一样的。他们之间的区别也仅在于事务传输发生的端点不一样、支持的最大包长度不一样、优先级不一样等这样一些对用户来说透明的东西。

    主机在排定中断传输任务时,会根据对应中断端点描述符中指定的查询间隔发起中断传输。中断传输有较高的优先级,仅次于同步传输。

    同样中断传输也采用PID翻转的机制来保证收发端数据同步。下图为中断传输的流程图(DATA0或DATA1中的包含的是中断信息,而不是中断数据)。

2.3.3 批量传输

  • 用来传输大量数据,要求传输不能出错,适用于打印机、存储设备等。
  • 批量传输是可靠的传输,需要握手包来表明传输的结果。若数据量比较大,将采用多次批量事务传输来完成全部数据的传输,传输过程中数据包的PID 按照 DATA0-DATA1-DATA0-…的方式翻转,以保证发送端和接收端的同步。
  • USB 允许连续 3次以下的传输错误,会重试该传输,若成功则将错误次数计数器清零,否则累加该计数器。超过三次后,HOST 认为该端点功能错误(STALL),放弃该端点的传输任务
  • 一次批量传输(Transfer)由 1 次到多次批量事务传输(Transaction)组成。
  • 翻转同步:发送端按照 DATA0-DATA1-DATA0-…的顺序发送数据包,只有成功的事务传输才会导致 PID 翻转,也就是说发送端只有在接收到 ACK 后才会翻转 PID,发送下一个数据包,否则会重试本次事务传输。同样,若在接收端发现接收到到的数据包不是按照此顺序翻转的,比如连续收到两个 DATA0,那么接收端认为第二个 DATA0 是前一个 DATA0 的重传。

    它通过在硬件级执行"错误检测"和"重传"来确保host与device之间"准确无误"地传输数据,即可靠传输。它由三种包组成(即IN事务或OUT事务):1) token; 2) data; 3) handshake

    其传输过程如下:

①批量输出事务:(1)主机先发出一个OUT令牌包(包含设备地址,端点号),(2)然后再发送一个DATA包,这时地址和端点匹配的设备就会收下这个数据包,主机切换到接收模式,等待设备返回握手包,(3)设备解码令牌包,数据包都准确无误,并且有足够的缓冲区来保存数据后就会使用ACK/NYET握手包来应答主机(只有高速模式才有NYET握手包,他表示本次数据成功接收,但是没有能力接收下一次传输),如果没有足够的缓冲区来保存数据,就返回NAC,告诉主机目前没有缓冲区可用,主机会在稍后时间重新该批量传输事务。如果设备检查到数据正确,但端点处于挂起状态,返回STALL。如果检测到有错误(如校验错误,位填充错误),则不做任何响应,让主机等待超时。

②批量输入事务:(1)主机首先发送一个IN令牌包(包含设备地址,端点号),(2)主机切换到接收数据状态等待设备返回数据。如果设备检测到错误,不做任何响应,主机等待超时。如果此时有地址和端点匹配的设备,并且没有检测到错误,则该设备作出反应:设备有数据需要返回,就将一个数据包放在总线上;如果没有数据需要返回,设备返回NAK响应主机;如果该端点处于挂起状态,设备返回STALL。如果主机收到设备发送的数据包并解码正确后,使用ACK握手包应答设备。如果主机检测到错误,则不做任何响应,设备会检测到超时。注意:USB协议规定,不允许主机使用NAK来拒绝接收数据包。主机收到NAK,知道设备暂时没有数据返回,主机会在稍后时间重新该批量输入事务。

    在USB2.0高速设备中增加了一个PING令牌包,它不发送数据,直接等待设备的握手包,因此PING事务只有令牌包和握手包。

2.3.4 等时传输

    等时(同步)传输适用在数据量大、对实时性要求高的场合,如音频设备,视频设备等,这些设备对数据的延迟很敏感。对于音频或视频设备数据的100%正确性要求不高,少量的数据错误是可以容忍的,主要是保证数据不能停顿,所以等时传输是不保证数据100%正确的。

    实时传输只需要令牌和数据两个信息包,没有握手应答包,故当数据错误时,不再重传操作。数据是否正确,由数据的CRC校验来确认。同步传输也不支持PID翻转。主机在排定事务传输时,同步传输有最高的优先级。

各种传输特性比较:

2.5 设备列举

2.5.1 描述符

    USB描述符类似USB外围设备的"身份证"一样,详细地记录着外围设备相关的一切信息(设备类型、厂商的ID和产品的ID、端点情况、本版本号等)。为了描述不同的数据,需要以不同的数据类型的USB描述符加以描述,共有11种类型,每种描述符的第一个字节描述该描述符包含的字节数目,第二个字节描述该描述符的类型。

  USB1.1协议定义的标准描述符是:设备描述符,配置描述符、接口描述符、端点描述符和字符串描述符,USB2.0中又新增了Device Qualifier Descriptor 和 Other Speed Configuration Descriptor。除此之外,还有其他描述符如:组描述符、报告描述符、类特殊描述符等。

  一个USB设备只有一个设备描述符,设备描述符里决定了该设备有多少种配置,每种配置都有一个配置描述符;而在每个配置描述符中又定义了该配置有多少个接口,每个接口都有一个接口描述符;在接口描述符中又定义了该接口有多少个端点,每个端点都有一个端点描述符;端点描述符定义了端点的大小、类型等。

  由此可以看出,USB描述符之间的关系是一层一层的,在主机获得描述符时,首先获取设备描述符,其次是配置描述符,再接下来是接口描述符,最后是端口描述符。

  这些描述符参数字段都有一个小写字母表示的前缀,它们所表示的意思如下:
 b 表一个字节,=8bits;
 w 表一个字,=16bits;
 bm 表按位寻址;
 bcd 用BCD码表示;
 i 表索引值
 id 表标识码

(1)设备描述符

    设备描述符具有18字节的长度,并且是主机向设备请求的第一个描述符。包含的信息有:设备所使用的USB协议版本号,设备类型、端点0的最大包大小、厂商ID(VID)和产品ID(PID)、设备版本号、厂商字符索引、产品字符索引、设备序列号索引、可能的配置数等。以下列出设备描述符的范围、数值以及各个字段的意义:

 bLength: 表示描述符的长度,对于设备描述符来说,其值为18,即0x12。
 bDescriptorType: 描述符类型,对应表1中的值,设备描述符为0x01。
 bcdUSB:该设备遵循的USB版本号,以BCD码表示,USB1.1为0x0101,USB2.0为0x0200。
 bDeviceClass:该设备所属的标准设备类,USB协议中对常见的设备进行了分类。该字段值为0x01~0xFE时,表示是USB协议中已定义的设备类,常用的HID设备类编号为0x03,其它设备类编号参:http://www.usb.org/developers/defined_class
 bDeviceProtocol:用于表示USB设备类所采用的设备类协议,其值和bDeviceClass和bDeviceSubClass有关。当此 字段为0时,表示不使用任何设备类协议。如果该USB设备属于某个设备类和设备子类,则应该继续指明所采用的设备类协议。当该字段为0xFF时,表明设备 类协议由供应商自定义。
 bMaxPacketSize0:用于表示在USB设备中,端点0所支持最大数据包的长度,它以字节为单位。对于低速USB设 备,bMaxPacketSize0为8;对于全速USB设备,bMaxPacketSize0为8、16、32、64;对于高速USB设 备,bMaxPacketSize0为64。
 IdVendor:用于表示USB设备供应商的ID。USB组织中规定每种产品都必须包含一个供应商ID,这样可以使主机加载合适的驱动程序。
 idProduct:用于表示USB产品的ID,由设备供应商提供。idProduct用于表示特定的USB设备,在USB设备上电的时候可以帮助USB主机选择合适的驱动程序。
 bcdDevice:用于表示USB设备的版本号,它以BCD码的形式表示。一般来说bcdDevcie由设备供应商指定,在USB设备上电的时候可以帮助USB主机选择合适的驱动程序。
 iManufacturer:用于表示供应商字符串描述符的索引值。具体字符串的内容在后面字符串描述符中定义。如果没有供应商字符串,可以置0。
 iSerialNumber:用于表示设备序列号字符串描述符的索引值,如果没有,可以置为0。
 bNumConfigurations:用于表示该USB设备所支持的配置数。

(2)配置描述符

    配置描述符具有9字节长度,针对设备给予配置的信息,包括配置所包含的接口数、配置的编号、供电方式、是否支持远程唤醒、电流需求量等。以下列出配置描述符的范例、数值以及各个字段的意义。

 bLength:用于表示配置描述符的长度,固定为9个字节,即0x09。
 bDescriptorType:用于表示配置描述符的类型值,固定为0x02。
 wTotalLength:用于表示配置信息的总长度,包括配置描述符、接口描述符、端点描述符长度的总和。
 bNumInterfaces:用于表示配置所支持的接口数。一般来说,USB设备的接口至少有一个,因此其最小值为1。
 bConfigurationValue:用于表示USB设备的配置值。
 iConfiguration:用于指出配置字符串描述符的索引值。具体字符串的内容在后面字符串描述符中定义。如果没有配置字符串,可以置为0。
 bmAttributes:用于表示USB设备特性。bmAttributes是接位寻址的,第6位置1表示使用总线电源;第5位置1表示支持远程唤醒功能;该字段其他位均保留,一般来说,第0~4位置0即可,第7位置1即可。
 bMaxPower:用于表示USB设备运行时所需要消耗的总线电流,单位以2mA为基准。USB设备可以从USB总线上获得最大的电流为500mA,因此bMaxPower字段的最大值可以设置为250。

(3)接口描述符

    接口描述符具有9字节的长度,用来描述每个设备的接口特性,包括接口的编号、接口的端点数、接口所使用的类、子类、协议等。以下列出配置描述符的范例、数值以及各个字段的意义。

(4)端点描述符

    端点描述符具有7字节的长度,用来描述端点的属性以及各个端点的位置,有端点号及方向、端点的传输类型、最大包长度、查询时间间隔等。该实例中有两个端点,首先介绍端点1的描述符:

    接下来介绍端点2的描述符:

 bLength:用于表示端点描述符的长度,固定为7字节,即0x07。
 bDescriptorType:用于表示接口描述符的类型值,固定为0x05。
 bEndpointAddress:用于表示端点的端点号以及端点的数据传输方向。第七位表示端点的数据传输方向,0表示OUT数据传输,1表示IN数据传输;第0~位表示端点号,例如001B表示端点1、010B表示端点2;其余位均保留,必须置0。
 bmAttributes:用于表示端点的特性。其中第0位和第1位表示端点的数据传输类型,00B表示控制传输、01B表示同步传输、10B表示块传 输、11B表示中断传输;如果是同步传输,第2位和第3位表示同步类型,00B表示非同步、01B表示异步、10B表示自适应、11B表示同步;第4、5 位表示端点的用法类型,00B表示数据端点、01B表示显示反馈端点、10B表示隐匿反馈端点、11B保留。其余位保留。
 wMaxPacketSize:用于表示端点所支持最大数据包的长度。其中第0~10位表示数据包的长度,第11位和12位指出每小帧最多传输的事务数,其余位均保留,必须置0。
 bInterval:用于指定端点数据传输的访问间隔。低速中断端点,取值范围为10~255,对应的访问间隔为10~255ms;对于全速中断端点,取值范围为1~255,对应的访问间隔为1~255ms;对于其他端点,可以参阅USB相关协议。

 2.6  端点类型和传输类型的关系

  一个具体的端点,只能工作在一种传输模式下。通常,我们把工作在什么模式下的端点就叫做什么端点,如控制端点、批量端点等。

  端点0是每个USB设备都必须具备的默认控制端点,它一上电就存在并且可用。设备的各种描述符以及主机发送的一些命令,都是通过端点0传输的。其他端点都是可选的,需要通过具体设备来决定。非0端点只有在Set Config之后才能使用

2.7  传输类型和端点支持的最大包长

  每个端点描述符都规定了端点支持的最大数据包长,主机每次发送数据包,都不能超过端点的最大包长。

  • 控制传输的端点,低速模式最大包长固定为8字节,高速模式最大包长固定为64字节,而全速模式在8,16,32,64中选择。
  • 等时传输的端点,全速模式最大包长的上限为1023字节,高速模式最大包长上限是1024字节,低速模式不支持等时传输。
  • 中断传输的端点,低速模式最大包长的上限为8字节,全速模式最大包长上限是64字节,高速模式最大包长上限是1024字节。
  • 批量传输的端点,高速模式固定为512字节,全速模式最大包长可在8、16、32、64字节中选择,低速模式不支持批量传输。

3 USB标准请求

3.1 USB标准请求的数据结构

  USB设备请求命令 :bmRequestType + bRequest + wValue + wIndex + wLength

  USB协议定义了一个8字节的标准设备请求,主要用在设备的枚举过程中。这8个字节的数据使用在控制传输的过程中通过默认的控制端点0发出的。在这8字节的数据中,包含了数据过程所需要的传输数据的方向、长度以及数据类型等信息。正式由于8字节的标准请求的原因,USB协议规定,端点0的最大包长度至少为8字节,就是说,任何一个USB设备都能够(而且必须)接收8字节的标准请求。

  注意:wValue、wIndex、wLength这三个域都是两字节的。在USB协议中用的是小端结构,即低字节在先,高字节在后

  这里只介绍了USB协议定义的标准请求,即bmRequestType的D6~5位位00的标准请求。

3.2 USB设备请求

  • 0 GET_STATUS:用来返回特定接收者的状态
  • 1 CLEAR_FEATURE:用来清除或禁止接收者的某些特性
  • 3 SET_FEATURE:用来启用或激活命令接收者的某些特性
  • 5 SET_ADDRESS:用来给设备分配地址
  • 6 GET_DEscriptOR:用于主机获取设备的特定描述符
  • 7 SET_DEscriptOR:修改设备中有关的描述符,或者增加新的描述符
  • 8 GET_CONFIGURATION:用于主机获取设备当前设备的配置值(注同上面的不同)
  • 9 SET_CONFIGURATION:用于主机指示设备采用的要求的配置
  • 10 GET_INTERFACE:用于获取当前某个接口描述符编号
  • 11 SET_INTERFACE:用于主机要求设备用某个描述符来描述接口
  • 12 SYNCH_FRAME:用于设备设置和报告一个端点的同步帧

    这里主要介绍几种常用的设备请求:

 

(1)取得描述符(Get Descriptor)

 

    该请求是在枚举过程中使用最多的一个请求,主机通过发送获得描述符请求读取设备的各种描述符,从而获得设备类型,端点情况等众多重要信息。获得描述符的接收者只能是设备,从bmRequestType的第7位可以看出,它是请求数据输入的。

  该请求可以取得USB设备中存在的特定的描述符,其格式如下:

 

 

    该请求的wValue的高字节表示要取的描述字符类型,低字节表示描述符的索引值,描述的类型有:1=设备描述符;2=配置描述符;3=字符串描述符;4=接口描述符;5=端点描述符。wIndex的值为0或语言ID,当要取得的描述符是字符描述符时,该域的值为语言ID;当为其他的描述符时,该域为0。 wLength表示要返回的数据长度,如果SETUP阶段的地址使用的是预设地址0(ENDP字段0),这时的wLength值会大于实际描述的值(这是因为用户以预设地址0来取得设备描述符时,不管多少字节,用户最多只能取得前8字节,即在控制传输过程中只有一次数据阶段)。对于全速模式和低速模式,获取描述符的标准请求只有三种:获取设备描述符、获取配置描述符、获取字符串描述符。另外的接口描述符和端点描述符是跟配置描述符一并返回的,不能单独请求返回(如果单独返回,主机无法确认他们属于哪个配置)。

(2)设置地址(Set Address)

    该请求给USB设备设置地址,从而可以对USB设备进行进一步的访问。每个连接在同一主控器上的USB设备都需要有一个唯一的设备地址,这样主机才能区分每个不同的设备。当设备复位后,都是用默认的地址0,主机从地址位0的设备获取设备描述符,一旦收到第一次设备描述符之后,主机就会发送设置地址请求,以尽量减少设备使用公共地址0的时间。设置地址请求是没有数据的,因此wLength的值为0,wIndex用不到,值为0。当设备收到设置地址请求后,就直接进入状态过程,等待主机读取0长度的状态数据包。主机成功读取到状态数据包(用ACK响应设备),设备将启用新的地址。格式如下:

    该请求与其他请求有一个重要的不同,该请求下,USB设备一直不改变它的地址,直到该请求的状态阶段被成功的完成,而其他请求的操作都是在状态阶段之前完成的。若特定的设备地址大于127,或者wIndex或我Length为非0值,那么该请求不执行。

(3)设置配置(SET_CONFIGURATION)

    该请求对设备进行设置。其格式如下:

    该请求中的wValue域的低字节表示设置的值,该值必须为0或者域配置描述符中的配置值相匹配。如果与配置描述符中的配置编号一致时,表示选中该配置。该值通常为1,因为大多数USB设备只有一种配置,配置编号为1,如果设置值等于0,表示设备在地址状态。设备只有收到非0的配置后,才能启动它的非0端点。如果Index或wLength为非0值,那么该请求不执行。

 

(4)清除特性(Clear Feature)

 

    该请求是用来取消一个特性,其格式如下:

 

 

    该请求的wValue表示特性选择器,它对应的值为:0=端点,1=设备。当某个特点不允许取消,或该特性根本不存在,或者指向一个根本不存在的端点或者接口时,该请求将会导致设备请求失败。如果端点被固件设为停止状态,主机软件(总线驱动程序)也可以发送一个值为0的CLEAR_FEATURE命令清除该端点的停止状态。

 

 3.3 设备描述符的返回

  当主机由端点0向设备发送设备描述符请求时,设备将通过控制输入端0来返回。在端点0的输出中断处理函数中,设备先对接收到的建立过程的数据进行判断,如果是获取设备设备描述符的请求时,那么将设备描述符数组内容写入到端点0输入缓冲区中,并使能端点发送。当下一次主机发送IN令牌后,将自动将端点0的输入缓冲区内的数据返回给主机,首先获取设备描述符的请求。

4 USB主机识别USB设备

    当USB设备插上主机时,主机就通过一系列的动作来对设备进行枚举配置,即从设备读取各种描述符信息,这样主机就可以根据这些信息来加载合适的驱动程序从而知道设备是什么样的设备,如何进行通信等。

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

  根据USB协议,对于总线供电设备,在枚举完成前最多可以从总线获取100mA电流,在枚举后,最多可以从总线上获取500mA的电流。

4.1 USB设备状态

USB设备的状态如下:

  • 接入态(Attached):设备接入主机后,主机通过检测信号线上的电平变化来发现设备的接入;
  • 供电态(Powered):就是给设备供电,分为设备接入时的默认供电值,配置阶段后的供电值(按数据中要求的最大值,可通过编程设置)
  • 缺省态(Default):USB在被配置之前,通过缺省地址0与主机进行通信;
  • 地址态(Address):经过了配置,USB设备被复位后,就可以按主机分配给它的唯一地址来与主机通信,这种状态就是地址态;
  • 配置态(Configured):通过各种标准的USB请求命令来获取设备的各种信息,并对设备的某此信息进行改变或设置。
  • 挂起态(Suspended):总线供电设备在3ms内没有总线***作,即USB总线处于空闲状态的话,该设备就要自动进入挂起状态,在进入挂起状态后,总的电流功耗不超过280UA。

4.2 USB设备枚举过程

    对应USB设备的状态,host对USB设备会有以下活动:

    在枚举过程中,都是使用控制传输

(1)复位阶段

    USB主机检测到USB设备插入后,就会对设备复位。USB设备在总线复位后其地址为0,这样主机就可以通过地址0和那些刚刚插入的设备通信。USB主机往地址为0的设备的端点0发送获取设备描述符的标准请求。设备会将设备描述符返回给主机,主机在成功获取到数据包后,就会返回一个确认数据包给设备,从而进入接下来的分配地址阶段。

(2)分配地址阶段

    主机对设备又一次复位,就进入到分配地址阶段。主机往地址为0的设备的端点0发送一个设置地址的请求,新的设备地址就包含在建立过程的数据包中。具体的地址由主机负责管理,主机会分配一个唯一的地址给刚接入的设备。设备在收到这个建立过程后,就会进入到状态过程。设备等待主机请求状态返回,收到状态请求后,设备就返回0长度的状态数据包。如果主机确认该状态包已经正确收到,就会发送应答包ACK给设备,设备在收到这个ACK之后,就要启用新的设备地址了。这样设备就分配到了一个唯一的设备地址。

(3)获取描述符阶段

    获取描述符可以形象地表述如下:

Host:你是什么设备?

Device:12 01 0100....Device Descriptor

Host:你有几种功能?

Device:09 02 09....Configuration Descriptor

Host:每个功能有几个接口?

Device:09 04 00....Interface Descriptor

Host:每个接口使用哪几个端点?

Device:06 05 82....Endpoint Descriptor

Host:好了,我知道你是谁了,开始传输设备吧!

Device:OK,Read Go!

    具体的过程如下所示:

 

第一步:

⑴用户将一个USB设备插入USB端口,主机为端口供电,设备此时处于上电状态。主机检测设备。集线器使用中断通道将事件报告给主机。

⑵主机发送Get_Port_Status(读端口状态)请求,以获取更多的设备信息。返回的消息告诉主机该设备是什么时候连接的。集线器检测设备是低速运行还是高速运行,并将此信息送给主机,这是对Get_Port_Status请求的响应。

⑶主机发送Set_Port_Feature(写端口状态)请求给集线器,要求它复位端口,请求集线器来重新设置端口。集线器使设备的USB数据线处于重启(RESET)状态至少10ms。

⑷主机使用Chirp K信号来了解全速设备是否支持高速运行。

⑸主机发送另一个Get_Port_Status请求,确定设备是否已经从复位状态退出。返回的数据有一位表示设备仍然处于重启状态。当集线器释放了重启状态,设备此时处于缺省状态,且已准备好在零端点通过缺省通道响应主机控制传输。缺省地址为00h,设备能从总线获取高达100mA的电流。

⑹集线器检测设备速度

集线器通过测定哪根信号线(D+或D-)在空闲时有更高的电压来检测设备是低速设备还是全速设备。全速和高速设备D+有上拉电阻,低速设备D-有上拉电阻。

⑺获取最大数据包长度(开始第一次数据传输)

    主机向address 0发送Get_Device_Deor(读设备描述符)的标准请求(这是一个控制传输的建立过程),以取得缺省控制管道所支持的最大数据包长度。设备在接收到该请求后,会按照主机请求的参数,在数据过程将设备描述符返回给主机。主机在成功获取到一个数据包的设备描述符,并确认没有错误后,就会返回一个0长度的确认数据包(状态过程)给设备,从而进入接下来的设置地址阶段。

  注意,第一次主机只会读取一个数据包的设备描述符标准的设备描述符具有18个字节,有的USB设备的端点0大小不足18字节(但至少具有8字节),这种情况下USB主机也是只发送一次数据输入请求,多余的数据将不会再次请求,即在第一次获取设备描述符时,只需返回一次数据即可。端点0的长度包含在设备描述符的bMaxPacketSize0字段中,其地址偏移量为7,所以这时主机只需读取该描述符的前8个字节之后,就知道端点0的最大长度了,这是因为端点0最大包长度刚好在设备描述符的第8字节处。注意,主机一次只能枚举一个USB设备,所以同一时刻只能有一个USB设备使用缺省地址0。

例:主机向设备发送一个八字节请求:80 06 00 01 00 00 40 00,设备接收到请求后产生一个中断,我们可以通过读中断寄存器知道中断源,并且可以加读最后状态寄存器来确定第一个接到的包是否为一个Setup包。当控制器处理程序判断出它是一个Get_descriptor请求时,把设备描述符的前16个字节发送到端点0缓冲区中。剩下的2个字节描述符第一次请求时不再发送。

第二步:

 

⑻主机分配一个新的地址给设备

    主机对设备又一次复位,这时就进入到了设置地址阶段。主机通过向地址0发送一个Set_Address请求来分配一个唯一的地址给设备(控制传输的建立过程),新的设备地址包含在建立过程的数据包中。设备在受到这个建立过程之后,直接进入到状态过程,因为这个控制传输没有数据过程。设备在等待主机请求状态返回(一个输入令牌包),收到令牌包后,设备就返回0长度的状态数据包。如果主机确认该状态包已经正常收到,就会发送应答包ACK给设备,设备在收到这个ACK之后,就会启用新的设备地址,这样设备就被分配到一个唯一的设备地址,从此开始所有通信都使用这个新地址。

例:当主机收到正确的前16字节描述符后,会给设备分配一个地址,我的PC分配的地址为:0x03(这个要看你的机子当时的USB接口设备数目而定) Set_Address 请求所发送的数据为:00 05 03 00 00 00 00 00,其中的03就表示主机为设备分配的地址为0x03,在以后的通信里设备就只对0x03地址作出应答。当设备产生一个接收中断后,根据所分配的地址设置设备的地址寄存器相应位。

第三步

 

主机再次获取设备描述符,主机会向新地址重新发送Get_Device_Deor命令,此次读取其设备描述符的全部字段,以了解该设备的总体信息,如VID,PID,这是会存在多次的请求数据输入(即主机会发送多个IN令牌包)。

例:主机发送设备描述符标准请求Get_descriptor:80 06 00 01 00 00 12 00,此次将要求把18个字节全部发送完。所以主机要分两次来读取。第一次读取16个字节,第二次读取两个字节,最后主机发送0表示发送完毕的应答。

第四步

主机获取配置描述符,配置描述符总共9字节,主机在获取配置描述符后,会根据描述符中所描述的配置集合总长度,获得配置集合。主机会向设备循环发送Get_Device_Configuration命令,要求USB设备回答,以读取全部配置信息。配置集合包括配置描述符、接口描述符、类特殊描述符(如果有)、端点描述符等。

 

⑾主机发送Get_Device_String命令,获得字符集描述(unicode)(如果有),比如产商、产品描述、型号等等。此时主机将会弹出窗口,展示发现新设备的信息,产商、产品描述、型号等。

     根据Device_Deor和Device_Configuration应答,PC判断是否能够提供USB的Driver,一般win2k能提供几大类的设备,如游戏操作杆、存储、打印机、扫描仪等,操作就在后台运行。但是Win98却不可以,所以在此时将会弹出对话框,索要USB的Driver。

⑿主机分配并加载设备驱动程序,这时就可能作应用中的数据传输了。

⒀主机发送Set_Configuration(x)(写配置)命令请求为该设备选择一个合适的配置(x代表非0的配置值)。如果配置成功,USB设备进入"配置"状态,并可以和客户软件进行数据传输。此时,常规的USB完成了其必须进行的配置和连接工作,至此设备应当可以开始使用。不过,USB协议还提供了一些用户可选的协议,设备如果不应答,也不会出错,但是会影响到系统的功能。

⒁主机为复合设备接口分配驱动程序。如果集线器检测到有过流现象,或者主机要求集线器关闭电源,则USB总线切断设备供电电源。在这种情况下,设备与主机无法通信,但设备处于连接状态。

4.3 USB枚举实例

    对2440的USB HOST进行初始化完毕(主要包括对符合OHCI规范的寄存器的初始化—总线复位、中断使能、清除中断标志、电源管理、内存指针寄存器的初始化,各种数据结构的初始化等),等待USB设备的插入,当2440检测到有设备插入,就要对设备进行枚举了。起始枚举就相当于主机和设备建立连接的过程(接头),Host向Device询问一些东西,Device将自身的设备类型,如何进行通信报告给Host,这样Host就知道怎么对Device进行操作了。

    枚举的过程实际上用到而且只用到了总线的"控制传输(Control Transfer)"。这种传输方式通常用于配置/命令/状态等情形,其中的设置操作setup和状态操作status过程的数据包具有USB协议定义的数据结构,因此,控制传输只能通过消息管道进行。

    一个完整的控制传输包括三个过程:

  • 建立连接。
  • 数据过程(可选) 。
  • 状态过程。

     建立连接的过程都是由Host发起,它开始于一个Setup令牌包,后面紧跟一个DATA0包。如果是控制输入传输,数据过程则为输入数据,若是控制输出传输,则数据过程是输出数据。

    数据过程的可选型是指设置过程需要指定数据长度,如果指定为0,则没有数据过程。状态过程跟在数据过程之后,状态过程恰好和数据过程的数据传输方向相反,因为此阶段主要是用来确认之前两阶段的所有数据都已经正确传输了。

    好了,下面就结合我的这个实例来看看枚举的详细过程:

①控制2440向U盘发送第一个Setup包,内容是80 06 00 01 00 00 08 00,其中最后的00 08表示得到DEVICE_DCESCRIPTOR的前8个字节,因为这个包的主要目的是要获得USB Device中端点0的最大包的大小(第8个字节),所以只需要8个字节就可以了。USB Device返回的设备标识符为12 01 10 01 00 00 00 40,下面我们需要把0x40记录下来,将其放到Endpoint Descriptor数据结构的DWORD0的MPS(bit16~bit32)块中去。

②接下来2440发送第二个Setup包,内容是00 05 01 00 00 00 00 00,这一次的作用是为USB设备分配地址。如果USB Device接收并接受了此地址设置包,会返回一个长度为0的数据包。主机接收到长度为0的状态包之后就会返回一个ACK给Device,Device再接收到这个ACK之后,就可以启用新地址了。这样Device就得到了一个唯一的设备地址,作为主机通信的唯一表示。

③发送第三个Setup包,内容是80 06 00 02 00 00 09 00,这次是为了获取配置描述符集合的大小,此位位于读回数据的第三个字节。U盘返回的数据为09 02 20 00 01 01 00 80 32,即描述符集合总大小为0x20。

④发送第四个Setup包,内容是80 06 00 02 00 00 09 00,和上次不同的仅仅是,这次要读回来的数据是整个配置描述符区域。U盘返回来的数据是09 02 20 00 01 01 00 80 32 09 04 00 00 02 08 06 50 00 07 05 82 02 40 00 00 07 05 02 02 40 00 00。这时候我们就可以知道该设备是什么类型的设备,支持什么样的操作了。

    上述这两个过程也有的程序就是直接读取0xff个字符大小,当然同样可以达到读回设备描述符集合的目的。至此,我们已经得到了所需要的设备信息,之后就可以对设备进行配置了。

⑤向设备发送第五个Setup包,数据为00 09 01 00 00 00 00 00,USB Device返回一个长度为0的数据包,表明数据正确接收。至此,USB枚举过程就完成了。初始设置步骤:就是一个由SET事务构成的传输

    可选数据步骤:就是一个由IN或OUT事务构成的传输,这个步骤是可选的,要看初始设置步骤有没有要求读/写数据(由SET事务的数据包阶段发送的标准请求命令决定)。

    状态信息步骤:这个步骤就是要获取状态信息,由IN或OUT事务构成的传输,但是要注意这里的IN和OUT事务和之前的INT和OUT事务有两点不同:

    1) 传输方向相反,通常IN表示设备往主机送数据,OUT表示主机往设备送数据;在这里,IN表示主机往设备送数据,而OUT表示设备往主机送数据,这是为了和可选数据步骤相结合;

    2) 在这个步骤里,数据包阶段的数据包都是0长度的,即SYNC+PID+CRC16。