转:https://blog.csdn.net/u011594613/article/details/48291307编程
1、USB硬件介绍
1.一、概述数据结构
一条USB传输线分别由地线、电源线、D+和D-四条线构成,D+和D-是差分输入线,它使用的是3.3V的电压(与CMOS的5V电平不一样),而电源线和地线可向设备提供5V电压,最大电流为500mA(能够在编程中设置)。
USB设备能够直接和HOST通讯,或者经过Hub和Host通讯。一个USB系统中仅有一个USB 主机,设备包括USB功能设备和USB HUB,最多支持127个设备。物理链接指的是USB传输线。在USB 2.0系统中要求使用屏蔽双绞线。
1.二、USB HUB
USB HUB提供了一种低成本、低复杂度的USB接口扩展方法。HUB的上行PORT面向HOST,下行PORT面向设备(HUB或功能设备)。在下行PORT上,HUB提供了设备链接检测和设备移除检测的能力,并给各下行PORT供电。HUB能够单独使能各下行PORT。不一样PORT能够工做在不一样的速度等级(高速/全速/低速)。
若是USB设备经过集线器和Host通讯,主机集线器监视着每一个端口的信号电压,当有新设备接入时即可觉察。集线器端口的两根信号线的每一根都有15kΩ的下拉电阻,而每个设备在D+都有一个1.5kΩ的上拉电阻。当用USB线将PC和设备接通后,设备的上拉电阻使信号线的电位升高,所以被主机集线器检测到。大数据
2、USB数据格式编码
USB的重要关键字:.net
端点(Endpoint):位于USB设备或主机上的一个数据缓冲区,是USB设备中能够进行数据收发的最小单元,支持单向或者双向的数据传输,用来存放和发送USB的各类数据,每个端点都有唯一的肯定地址,有不一样的传输特性(如输入端点、输出端点、配置端点、批量传输端点)。设备支持端点的数量是有限制的,除默认端点外低速设备最多支持2组端点(2 个输入,2 个输出),高速和全速设备最多支持15组端点。指针
帧:时间概念,在USB中,一帧就是1MS,它是一个独立的单元,包含了一系列总线动做,USB将1帧分为好几份,每一份是一个USB的传输动做。code
上行、下行:设备到主机为上行,主机到设备为下行。blog
2.一、USB数据传输方法索引
数据在USB线里传送是由低位到高位发送的。接口
USB采用不归零取反来传输数据,当传输线上的差分数据输入0时就取反,输入1时就保持原值,为了确保信号发送的准确性,当在USB总线上发送一个包时,传输设备就要进行位插入操做(即在数据流中每连续6个1后就插入一个0),从而强迫NRZI码发生变化。这些是由专门硬件处理的。
2.二、数据格式
USB数据是由二进制数字串构成的,首先数字串构成域(有七种),域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、并行传输、批量传输和控制传输)。下面介绍一下域、包和事务。
2.2.一、域
域是USB数据最小的单位,由若干位组成(多少位由具体的域决定),域可分为七个类型:
一、同步域(SYNC)
全部的USB包都由SYNC开始,高速包的SYNC宽度为32bit,全速/低速包的SYNC段度为8bit。实际接收到的SYNC长度因为USB HUB的关系,可能会小于该值。八位的值固定为0000 0001,用于本地时钟与输入同步。
二、标识域(PID)
由四位标识符 + 四位标识符反码构成,代表包的类型和格式,这是一个很重要的部分,这里能够计算出,USB的标识码有16种。USB2.0使用了十六种标识码,标识码的做用是用来讲明包的属性的,标识码是和包联系在一块儿的,标识码分别有如下十六种:
令牌包 :
0x01:输出(OUT)启动一个方向为主机到设备的传输,并包含了设备地址和标号。
0x09:输入(IN) 启动一个方向为设备到主机的传输,并包含了设备地址和标号。
0x05:帧起始(SOF)表示一个帧的开始,而且包含了相应的帧号。
0x0d:设置(SETUP)启动一个控制传输,用于主机对设备的初始化。
数据包 :
0x03:偶数据包(DATA0)。
0x0b:奇数据包(DATA1)。
握手包:
0x02:确认接收到无误的数据包(ACK)。
0x0a:无效,接收(发送)端正在忙而没法接收(发送)信息。
0x0e:错误,端点被禁止或不支持控制管道请求。
特殊包0x0C前导,用于启动下行端口的低速设备的数据传输。
三、地址域(ADDR):七位地址,表明了设备在主机上的地址,地址000 0000被命名为零地址,是任何设备第一次链接到主机时,在被主机配置、枚举前的默认地址,由此能够知道为何一个USB主机只能接127个设备的缘由。
四、端点域(ENDP),四位,由此可知一个USB设备端点数量最大为16个。
五、帧号域(FRAM),11位,每个帧都有一个特定的帧号,帧号域最大容量0x800,对于同步传输有重要意义。
六、数据域(DATA):长度为0~1023字节,在不一样的传输类型中,数据域的长度各不相同,但必须为整数个字节的长度。
七、校验域(CRC):对令牌包和数据包中非PID域进行校验的一种方法,CRC校验在通信中应用很泛,是一种很好的校验方法,CRC码的除法是模2运算,不一样于10进制中的除法。
2.2.二、包
USB数据包的格式以下:
由域构成的包有四种类型,分别是令牌包、数据包、握手包和特殊包,前面三种是重要的包,不一样包的域结构不一样,介绍以下:
一、令牌包
分为输入包、输出包、设置包和帧起始包(注意这里的输入包是用于设置输入命令的,输出包是用来设置输出命令的,而不是放数据的)其中输入包、输出包和设置包的格式都是同样的:
SYNC + PID + ADDR + ENDP + CRC5(五位的校验码)
帧起始包的格式:
SYNC + PID + 11位FRAM + CRC5(五位的校验码)
二、数据包
分为DATA0包和DATA1包,当USB发送数据的时候,若是一次发送的数据长度大于相应端点的容量时,就须要把数据包分为好几个包,分批发送,DATA0包和DATA1包交替发送,即若是第一个数据包是DATA0,那第二个数据包就是DATA1。但也有例外状况,在同步传输中(四类传输类型中之一),全部的数据包都是为DATA0,格式以下:
SYNC + PID + 0~1023字节 + CRC16
三、握手包
结构最为简单的包,格式以下:
SYNC + PID
握手包包括 ACK、NAK、STALL以及NYET 四种,其中 ACK 表示确定的应答,成功的数据传输。NAK 表示否认的应答,失败的数据传输,要求从新传输。STALL表示功能错误或端点被设置了STALL属性。NYET表示还没有准备好,要求等待。
2.2.三、事务
分别有IN、OUT和SETUP三大事务,每一种事务都由令牌包、数据包、握手包三个阶段构成,这里用阶段的意思是由于这些包的发送是有必定的时间前后顺序的,事务的三个阶段以下:
一、令牌包阶段:启动一个输入、输出或设置的事务。
二、数据包阶段:按输入、输出发送相应的数据。
三、握手包阶段:返回数据接收状况,在同步传输的IN和OUT事务中没有这个阶段,这是比较特殊的。
事务的三种类型以下(如下按三个阶段来讲明一个事务):
一、 IN事务:
令牌包阶段——主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;
数据包阶段——设备根据状况会做出三种反应(要注意:数据包阶段也不老是传送数据的,根据传输状况还会提早进入握手包阶段)。
1) 设备端点正常:设备往主机里面发出数据包(DATA0与DATA1交替);
2) 设备正在忙:没法往主机发出数据包就发送NAK无效包,IN事务提早结束,到了下一个IN事务才继续;
3) 相应设备端点被禁止:发送错误包STALL包,事务也就提早结束了,总线进入空闲状态。
握手包阶段——主机正确接收到数据以后就会向设备发送ACK包。
二、 OUT事务:
令牌包阶段——主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;
数据包阶段——比较简单,就是主机会往设备送数据,DATA0与DATA1交替
握手包阶段——设备根据状况会做出三种反应
1) 设备端点接收正确,设备给主机返回ACK,通知主机能够发送新的数据,若是数据包发生了CRC校验错误,将不返回任何握手信息;
2) 设备正在忙,没法给主机返回ACK,就发送NAK无效包,通知主机再次发送数据;
3) 相应设备端点被禁止,发送错误包STALL包,事务提早结束,总线直接进入空闲状态。
三、SETUT事务:
令牌包阶段——主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;
数据包阶段——比较简单,就是主机往设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令,详见2.4。
握手包阶段——设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后一般是一个IN或OUT事务构成的传输)。
2.三、标准的USB设备请求命令
标准的USB设备请求命令是用在控制传输中的“初始设置步骤”里的数据包阶段(即DATA0,由八个字节构成)。命令共有11个,大小都是8个字节,具备相同的结构,由5个字段构成(字段是标准请求命令的数据部分),结构以下(括号中的数字表示字节数,首字母bm,b,w分别表示位图、字节,双字节):
bmRequestType(1) + bRequest(1) + wvalue(2) + wIndex(2) + wLength(2)
各字段的意义以下:
一、bmRequestType:D7D6D5D4D3D2D1D0
D7=0主机到设备
=1设备到主机;
D6D5=00标准请求命令
=01 类请求命令
=10用户定义的命令
=11保留值
D4D3D2D1D0=00000 接收者为设备
=00001 接收者为设备
=00010 接收者为端点
=00011 接收者为其余接收者
=其余 其余值保留
二、bRequest:请求命令代码,在标准的USB命令中,每个命令都定义了编号,编号的值就为字段的值,编号与命令名称以下(要注意这里的命令代码要与其余字段结合使用,能够说命令代码是标准请求命令代码的核心,正是由于这些命令代码而决定了11个USB标准请求命令):
0 GET_STATUS:用来返回特定接收者的状态;
1 CLEAR_FEATURE:用来清除或禁止接收者的某些特性;
2) 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:用于设备设置和报告一个端点的同步帧;
控制传输是USB的重心,而这11个命令是控制传输的重心,因此这11个命令是重中之重。
2.四、描述符(Descriptor)
Descriptor是一个完整的数据结构,能够经过C语言等编程实现,并存储在USB设备中,用于描述一个USB设备的全部属性,USB主机是经过一系列命令来要求设备发送这些信息的。它的做用就是给主机传递信息,从而让主机知道设备具备什么功能、属于哪一类设备、要占用多少带宽、使用哪类传输方式及数据量的大小,只有主机肯定了这些信息以后,设备才能真正开始工做,因此描述符也是十分重要的部分,标准的描述符有5种,USB为这些描述符定义了编号:
1——设备描述符
2——配置描述符
3——字符描述符
4——接口描述符
5——端点描述符
上面的描述符之间有必定的关系,一个设备只有一个设备描述符,而一个设备描述符能够包含多个配置描述符,而一个配置描述符能够包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。这些描述符是用必定的字段构成的,分别以下说明:
一、设备描述符
struct _DEVICE_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小,为0x12
BYTE bDescriptorType; //描述符类型编号,为0x01
WORD bcdUSB; //USB版本号
BYTE bDeviceClass; //USB分配的设备类代码,0x01~0xfe为标准设备类,0xff为厂商自定义类型
//0x00不是在设备描述符中定义的,如HID
BYTE bDeviceSubClass; //usb分配的子类代码,同上,值由USB规定和分配的
BYTE bDeviceProtocl; //USB分配的设备协议代码,同上
BYTE bMaxPacketSize0; //端点0的最大包的大小
WORD idVendor; //厂商编号
WORD idProduct; //产品编号
WORD bcdDevice; //设备出厂编号
BYTE iManufacturer; //描述厂商字符串的索引
BYTE iProduct; //描述产品字符串的索引
BYTE iSerialNumber; //描述设备序列号字符串的索引
BYTE bNumConfiguration; //可能的配置数量
}
二、配置描述符
struct _CONFIGURATION_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小,为0x12
BYTE bDescriptorType; //描述符类型编号,为0x01
WORD wTotalLength; //配置所返回的全部数量的大小
BYTE bNumInterface; //此配置所支持的接口数量
BYTE bConfigurationVale; //Set_Configuration命令须要的参数值
BYTE iConfiguration; //描述该配置的字符串的索引值
BYTE bmAttribute; //供电模式的选择
BYTE MaxPower; //设备从总线提取的最大电流
}
三、字符描述符
struct _STRING_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小,为0x12
BYTE bDescriptorType; //描述符类型编号,为0x01
BYTE SomeDescriptor[36]; //UNICODE编码的字符串
}
四、接口描述符
struct _INTERFACE_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小,为0x12
BYTE bDescriptorType; //描述符类型编号,为0x01
BYTE bInterfaceNunber; //接口的编号
BYTE bAlternateSetting;//备用的接口描述符编号
BYTE bNumEndpoints; //该接口使用端点数,不包括端点0
BYTE bInterfaceClass; //接口类型
BYTE bInterfaceSubClass;//接口子类型
BYTE bInterfaceProtocol;//接口所遵循的协议
BYTE iInterface; //描述该接口的字符串索引值
}
五、端点描述符
struct _ENDPOIN_DEscriptOR_STRUCT
{
BYTE bLength; //设备描述符的字节数大小,为0x12
BYTE bDescriptorType; //描述符类型编号,为0x01
BYTE bEndpointAddress; //端点地址及输入输出属性
BYTE bmAttribute; //端点的传输类型属性
WORD wMaxPacketSize; //端点收、发最大包的大小
BYTE bInterval; //主机查询端点的时间间隔
}
3、传输
USB系统中的数据传输,宏观看是在HOST和USB功能设备之间进行。微观看是在应用软件的Buffer和USB功能设备的端点之间进行。通常来讲端点都有Buffer,能够认为USB通信就是应用软件Buffer和设备端点Buffer之间的数据交换,交换的通道称为管道。应用软件经过和设备之间的数据交换来完成设备控制和数据传输。一般须要多个管道来完成数据交换,由于同一管道只支持一种类型的数据传输。用在一块儿来对设备进行控制的若干管道称为设备的接口,这就是端点、管道和接口的关系。
USB 采用“令牌包”-“数据包”-“握手包”的传输机制,在令牌包中指定数据包去向或者来源的设备地址和端点(Endpoint),从而保证了只有一个设备对被广播的数据包/令牌包做出响应。握手包表示了传输的成功与否。
USB 采用轮询的广播机制传输数据,全部的传输都由主机发起,任什么时候刻整个 USB 体系内仅容许一个数据包的传输,即不一样物理传输线上看到的数据包都是同一被广播的数据包。
传输由OUT、IN和SETUP事务构成,传输有四种类型,中断传输、批量传输、同步传输、控制传输,其中中断传输和批量传输的结构同样,同步传输有最简单的结构,而控制传输是最重要的也是最复杂的传输。
3.一、控制传输
控制传输是一种可靠的双向传输,是最重要也是最复杂的,一次控制传输可分为构成(初始设置阶段、可选数据阶段、状态信息步骤),每个阶段能够当作一个传输,也就是说控制传输实际上是由三个传输构成的,在USB设备初次接到主机后,主机经过控制传输来交换信息、设备地址和读取设备的描述符,使得主机识别设备,并安装相应的驱动程序,这是每个USB开发者都要关心的问题。
第一阶段:从HOST到Device的SETUP事务传输,这个阶段指定了这次控制传输的请求类型。
第二阶段:数据阶段,也有些请求没有数据阶段。
第三阶段:状态阶段,经过一次IN/OUT传输代表请求是否成功完成。
控制传输经过控制管道在应用软件和Device的控制端点之间进行,控制传输过程当中传输的数据是有格式定义的,USB 设备或主机可根据格式定义解析得到的数据含义。其余三种传输类型都没有格式定义。控制传输对于最大包长度有固定的要求。对于高速设备该值为64Byte,对于低速设备该值为8,全速设备能够是8或16或32或64。
最大包长度表征了一个端点单次接收/发送数据的能力,实际上反应的是该端点对应Buffer的大小。Buffer越大,单次可接收/发送的数据包越大,反之亦反。当经过一个端点进行数据传输时,若数据的大小超过该端点的最大包长度时,须要将数据分红若干个数据包传输。并保证除最后一个包外,全部的包长度均等于该最大包长度。这也就是说若是一个端点收到/发送了一个长度小于最大包长度的包,即意味着数据传输结束。
控制传输在访问总线时也受到一些限制,如高速端点的控制传输不能占用超过 20%的微帧,全速和低速的则不能超过 10%。在一帧内若是有多余的未用时间,而且没有同步和中断传输,能够用来进行控制传输。
控制传输(Transaction) 一次控制传输分为三(或两个)个阶段:创建(Setup)、数据(DATA)(可能没有)以及状态(Status)。每一个阶段都由一次或屡次(数据阶段)事务传输组成(Transaction)。
上图为创建阶段的事务传输流程图。能够看出:
与批量传输相比,在流程上并无多大区别,区别只在于该事务传输发生的端点不同、支持的最大包长度不同、优先级不同等这样一些对用户来讲透明的东西。
创建阶段事后,可能会有数据阶段,这个阶段将会经过一次或屡次控制传输事务,完成数据的传输。一样也会采用PID翻转的机制。
创建阶段,Device 只能返回ACK包,或者不返回任何包。
最后是状态阶段,经过一次方向与前一次相反的控制事务传输来代表传输的成功与否。若是成功会返回一个长度为0的数据包,不然返回 NAK或STALL。下图为整个控制传输的示意图:
3.二、中断传输
中断传输是一种轮询的传输方式,是一种单向的传输。HOST经过固定的间隔对中断端点进行查询,如有数据传输或能够接收数据则返回数据或发送数据。不然返回NAK,表示还没有准备好。中断传输的延迟有保证,但并不是实时传输,它是一种延迟有限的可靠传输,支持错误重传。对于高速/全速/低速端点,最大包长度分别能够达到1024/64/8 Bytes。 高速中断传输不得占用超过 80%的微帧时间,全速和低速不得超过90%。 中断端点的轮询间隔由在端点描述符中定义,全速端点的轮询间隔能够是1~255mS。低速端点为10~255mS,高速端点为(2interval-1)*125uS,其中 interval 取 1到 16 之间的值。
除高速高带宽中断端点外,一个微帧内仅容许一次中断事务传输。高速高带宽端点最多能够在一个微帧内进行三次中断事务传输,传输高达 3072 字节的数据。
所谓单向传输,并非说该传输只支持一个方向的传输。而是指在某个端点上该传输仅支持一个方向,或输出、或输入。若是须要在两个方向上进行某种单向传输,须要占用两个端点,分别配置成不一样的方向。能够拥有相同的端点编号。
中断传输由OUT事务和IN事务构成,用于键盘、鼠标等HID设备的数据传输。
中断传输在流程上除不支持PING以外,其余的跟批量传输是同样的。他们之间的区别也仅在于事务传输发生的端点不同、支持的最大包长度不同、优先级不同等这样一些对用户来讲透明的东西。
主机在排定中断传输任务时,会根据对应中断端点描述符中指定的查询间隔发起中断传输。中断传输有较高的优先级,仅次于同步传输。一样中断传输也采用 PID 翻转的机制来保证收发端数据同步。
下图为中断传输的流程图。
3.三、批量传输
批量传输由OUT事务和IN事务构成,是一种可靠的单向传输,但延迟没有保证,它尽可能利用能够利用的带宽来完成传输,适合数据量比较大的传输。低速USB设备不支持批量传输,高速批量端点的最大包长度为512,全速批量端点的最大包长度能够为八、1六、3二、64。
批量传输在访问USB总线时,相对其余传输类型具备最低的优先级,USB HOST老是优先安排其余类型的传输,当总线带宽有富余时才安排批量传输。高速的批量端点必须支持PING操做,向主机报告端点的状态。NYET表示否认应答,没有准备好接收下一个数据包,ACK 表示确定应答,已经准备好接收下一个数据包。
图中一个方框表示一个 Packet,灰色的包表示主机发出的包,白色的包表示Device发出的包。批量传输是可靠的传输,须要握手包来代表传输的结果。若数据量比较大,将采用屡次批量事务传输来完成所有数据的传输,传输过程当中数据包的PID按照 DATA0-DATA1-DATA0-...的方式翻转,以保证发送端和接收端的同步。若成功则将错误次数计数器清0,不然累加该计数器。USB容许连续3次如下的传输错误,会重试该传输。超过三次后,HOST 认为该端点功能错误(STALL),放弃该端点的传输任务。
一次批量传输(Transfer)由 1 次到屡次批量事务传输(Transaction)组成。
翻转同步:发送端按照 DATA0-DATA1-DATA0-...的顺序发送数据包,只有成功的事务传输才会致使PID翻转,也就是说发送段只有在接收到ACK后才会翻转PID,发送下一个数据包,不然会重试本次事务传输。一样,若在接收端发现接收到的数据包不是按照此顺序翻转的,好比连续收到两个DATA0,那么接收端认为第二个DATA0是前一个DATA0的重传。
3.四、同步传输
同步传输是一种实时的、不可靠的传输,不支持错误重发机制。只有高速和全速端点支持同步传输,高速同步端点的最大包长度为1024,低速的为1023。由OUT事务和IN事务构成。有两个特殊地方,第一,在同步传输的IN和OUT事务中是没有返回包阶段的;第二,在数据包阶段全部的数据包都为DATA0。
除高速高带宽同步端点外,一个微帧内仅容许一次同步事务传输,高速高带宽端点最多能够在一个微帧内进行三次同步事务传输,传输高达 3072 字节的数据。全速同步传输不得占用超过 80%的帧时间,高速同步传输不得占用超过90%的微帧时间。同步端点的访问也和中断端点同样,有固定的时间间隔限制。
同步传输是不可靠的传输,因此它没有握手包,也不支持PID翻转。主机在排定事务传输时,同步传输有最高的优先级。
3.五、分离传输(Split Transaction)
分离传输是在主机控制器和USB HUB之间的传输,它仅在主机控制器和HUB之间执行,经过分离传输,能够容许全速/低速设备链接到高速主机。分离传输对于USB设备来讲是透明的、不可见的。
分离传输,顾名思义就是把一次完整的事务传输分红两个事务传输来完成。其出发点是高速传输和全速/低速传输的速度不相等,若是使用一次完整的事务来传输,势必会形成比较长的等待时间,从而下降了高速USB总线的利用率。经过将一次传输分红两次,将令牌(和数据)的传输与响应数据(和握手)的传输分开,这样就能够在中间插入其余高速传输,从而提升总线的利用率。
3.六、总结
包是USB总线数据传输的最小单位,不能被打断或干扰,不然会引起错误。若干个数据包组成一次事务传输,一次事务传输也不能打断,属于一次事务传输的几个包必须连续,不能跨帧完成。一次传输由一次到屡次事务传输构成,能够跨帧完成。
4、枚举
USB设备链接到HOST时,HOST必须经过默认的控制管道对其进行枚举,完成得到其设备描述、进行地址分配、得到其配置描述、进行配置等操做后方可正常使用。USB设备的即插即用特性即依赖于此。
4.一、枚举时USB的状态
当USB设备插上主机时,主机就经过一系列的动做来对设备进行枚举配置(配置是属于枚举的一个态,态表示暂时的状态),这些态以下:
一、接入态(Attached):设备接入主机后,主机经过检测信号线上的电平变化来发现设备的接入;
二、供电态(Powered):就是给设备供电,分为设备接入时的默认供电值,配置阶段后的供电值(按数据中要求的最大值,可经过编程设置);
三、缺省态(Default):USB在被配置以前,经过缺省地址0与主机进行通讯;
四、地址态(Address):通过了配置,USB设备被复位后,就能够按主机分配给它的惟一地址来与主机通讯,这种状态就是地址态;
五、配置态(Configured):经过各类标准的USB请求命令来获取设备的各类信息,并对设备的某些信息进行改变或设置。
六、挂起态(Suspended):总线供电设备在3ms内没有总线操做,即USB总线处于空闲状态的话,该设备就要自动进入挂起状态,在进入挂起状态后,总的电流功耗不超过280uA。
状态转移图以下所示:
4.二、枚举过程
一、用户将一个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(读设备描述符)报文,以取得缺省控制管道所支持的最大数据包长度。并在有限的时间内等待USB设备的响应。该长度包含在设备描述符的bMaxPacketSize0字段中,其地址偏移量为7,因此这时主机只需读取该描述符的前8个字节。注意,主机一次只能枚举一个USB设备,因此同一时刻只能有一个USB设备使用缺省地址0。
例:主机向设备发送一个八字节请求:80 06 00 01 00 00 40 00,设备接收到请求后产生一个中断,咱们能够经过读中断寄存器知道中断源,而且能够加读最后状态寄存器来肯定第一个接到的包是否为一个Setup包。当控制器处理程序判断出它是一个Get_descriptor请求时,把设备描述符的前16个字节发送到端点0缓冲区中。剩下的2个字节描述符第一次请求时再也不发送。
八、主机分配一个新的地址给设备
主机经过发送一个Set_Address请求来分配一个惟一的地址给设备。设备读取这个请求,返回一个确认,并保存新的地址。今后开始全部通讯都使用这个新地址。
例:当主机收到正确的前16字节描述符后,会给设备分配一个地址,个人PC分配的地址为:0x03(这个要看你的机子当时的USB接口设备数目而定) Set_Address 请求所发送的数据为:00 05 03 00 00 00 00 00,其中的03就表示主机为设备分配的地址为0x03,在之后的通讯里设备就只对0x03地址做出应答。当设备产生一个接收中断后,根据所分配的地址设置设备的地址寄存器相应位。
九、主机向新地址从新发送Get_Device_Deor命令,这次读取其设备描述符的所有字段,以了解该设备的整体信息,如VID,PID。
例:主机发送设备描述符标准请求Get_descriptor:80 06 00 01 00 00 12 00,这次将要求把18个字节所有发送完。因此主机要分两次来读取。第一次读取16个字节,第二次读取两个字节,最后主机发送0表示发送完毕的应答。
十、主机向设备循环发送Get_Device_Configuration命令,要求USB设备回答,以读取所有配置信息。
十一、主机发送Get_Device_String命令,得到字符集描述(unicode),好比产商、产品描述、型号等等。此时主机将会弹出窗口,展现发现新设备的信息,产商、产品描述、型号等。
根据Device_Deor和Device_Configuration应答,PC判断是否可以提供USB的Driver,通常win2k能提供几大类的设备,如游戏操做杆、存储、打印机、扫描仪等,操做就在后台运行。可是Win98却不能够,因此在此时将会弹出对话框,索要USB的Driver。
十二、主机分配并加载设备驱动程序,这时就可能做应用中的数据传输了。
1三、主机发送Set_Configuration(x)(写配置)命令请求为该设备选择一个合适的配置(x表明非0的配置值)。若是配置成功,USB设备进入“配置”状态,并能够和客户软件进行数据传输。此时,常规的USB完成了其必须进行的配置和链接工做,至此设备应当能够开始使用。不过,USB协议还提供了一些用户可选的协议,设备若是不该答,也不会出错,可是会影响到系统的功能。
1四、主机为复合设备接口分配驱动程序。若是集线器检测到有过流现象,或者主机要求集线器关闭电源,则USB总线切断设备供电电源。在这种状况下,设备与主机没法通讯,但设备处于链接状态。
使用USB View 采集到的数据:
Device Descriptor:
bcdUSB: 0x0100
bDeviceClass: 0xDC
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x10 (16)
idVendor: 0x0471
idProduct: 0x0666
bcdDevice: 0x0100
iManufacturer: 0x00
iProduct: 0x00
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Full
Device Address: 0x02
Open Pipes: 4
Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x01
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x82
Transfer Type: Bulk
wMaxPacketSize: 0x0040 (64)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x02
Transfer Type: Bulk
wMaxPacketSize: 0x0040 (64)
bInterval: 0x0A
4.三、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。