USB枚举过程

本博客整理自网络,仅供学习参考,如有侵权,联系删除。邮箱:j1817524883@126.com

USB枚举过程

枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序。

步骤:
1、用户把USB设备插入USB端口或给系统启动时设备上电

这里指的USB端口指的是主机下的根hub或主机下行端口上的hub端口。Hub给端口供电,连接着的设备处于上电状态。此时,USB设备处于加电状态,它所连接的端口是无效的。

2、Hub监测它各个端口数据线上(D+/D-)的电压

在hub端,数据线D+和D-都有一个阻值在14.25k到24.8k的下拉电阻Rpd,而在设备端,D+(全速,高速)和D-(低速)上有一个1.5k的上拉电阻Rpu。
当设备插入到hub端口时,有上拉电阻的一根数据线被拉高到幅值的90%的电压(大致是3V)。hub检测到它的一根数据线是高电平,就认为是有设备插入,
并能根据是D+还是D-被拉高来判断到底是什么设备(全速/低速)插入端口。

3、Host了解连接的设备

每个hub利用它自己的中断端点向主机报告它的各个端口的状态(对于这个过程,设备是看不到的,也不必关心),报告的内容只是hub端口的设备连接/断开的事件。如果有连接/断开事件发生,那么host会发送一个 Get_Port_Status请求(request)给hub以了解此次状态改变的确切含义。Get_Port_Status等请求属于所有hub都要求支持的hub类标准请求(standard hub-class requests)。

4、Hub检测所插入的设备是高速还是低速设备

hub通过检测USB总线空闲(Idle)时差分线的高低电压来判断所连接设备的速度类型,当host发来Get_Port_Status请求时,hub就可以将此设备的速度类型信息回复给host。USB 2.0规范要求速度检测要先于复位(Reset)操作。

5、hub复位设备

主机一旦得知新设备已连上以后,它至少等待100ms以使得插入操作的完成以及设备电源稳定工作。然后主机控制器就向hub发出一个 Set_Port_Feature请求让hub复位其管理的端口(刚才设备插上的端口)。hub通过驱动数据线到复位状态(D+和D-全为低电平 ),并持续至少10ms。当然,hub不会把这样的复位信号发送给其他已有设备连接的端口,所以其他连在该hub上的设备自然看不到复位信号,不受影响。

6、Host检测所连接的全速设备是否是支持高速模式

因为根据USB 2.0协议,高速(High Speed)设备在初始时是默认全速(Full Speed )状态运行,所以对于一个支持USB 2.0的高速hub,当它发现它的端口连接的是一个全速设备时,会进行高速检测,看看目前这个设备是否还支持高速传输,如果是,那就切到高速信号模式,否则就一直在全速状态下工作。
同样的,从设备的角度来看,如果是一个高速设备,在刚连接bub或上电时只能用全速信号模式运行(根据USB 2.0协议,高速设备必须向下兼容USB 1.1的全速模式)。随后hub会进行高速检测,之后这个设备才会切换到高速模式下工作。假如所连接的hub不支持USB 2.0,即不是高速hub,不能进行高速检测,设备将一直以全速工作。

7、Hub建立设备和主机之间的信息通道

主机不停地向hub发送Get_Port_Status请求,以查询设备是否复位成功。Hub返回的报告信息中有专门的一位用来标志设备的复位状态。
当hub撤销了复位信号,设备就处于默认/空闲状态(Default state),准备接收主机发来的请求。设备和主机之间的通信通过控制传输,默认地址0,端点号0进行。此时,设备能从总线上得到的最大电流是100mA。(所有的USB设备在总线复位后其地址都为0,这样主机就可以跟那些刚刚插入的设备通过地址0通信。)

8、主机发送Get_Descriptor请求获取默认管道的最大包长度

默认管道(Default Pipe)在设备一端来看就是端点0。主机此时发送的请求是默认地址0,端点0,虽然所有未分配地址的设备都是通过地址0来获取主机发来的请求,但由于枚举过程不是多个设备并行处理,而是一次枚举一个设备的方式进行,所以不会发生多个设备同时响应主机发来的请求。
设备描述符的第8字节代表设备端点0的最大包大小。虽然说设备所返回的设备描述符(Device Descriptor)长度只有18字节,但系统也不在乎,此时,描述符的长度信息对它来说是最重要的,其他的瞄一眼就过了。当完成第一次的控制传输后,也就是完成控制传输的状态阶段,系统会要求hub对设备进行再一次的复位操作(USB规范里面可没这要求)。再次复位的目的是使设备进入一个确定的状态。

9、主机给设备分配一个地址

主机控制器通过Set_Address请求向设备分配一个唯一的地址。在完成这次传输之后,设备进入地址状态(Address state),之后就启用新地址继续与主机通信。这个地址对于设备来说是终生制的,设备在,地址在;设备消失(被拔出,复位,系统重启),地址被收回。同一个设备当再次被枚举后得到的地址不一定是上次那个了。

10、主机获取设备的信息

主机发送 Get_Descriptor请求到新地址读取设备描述符,这次主机发送Get_Descriptor请求可算是诚心,它会认真解析设备描述符的内容。设备描述符内信息包括端点0的最大包长度,设备所支持的配置(Configuration)个数,设备类型,VID(Vendor ID,由USB-IF分配), PID(Product ID,由厂商自己定制)等信息。Get_Descriptor请求(Device type)和设备描述符(已抹去VID,PID等信息)

11、主机给设备挂载驱动(复合设备除外)

主机通过解析描述符后对设备有了足够的了解,会选择一个最合适的驱动给设备。  然后tell the world(announce_device)说明设备已经找到了,最后调用设备模型提供的接口device_add将设备添加到 usb 总线的设备列表里,然后 usb总线会遍历驱动列表里的每个驱动,调用自己的 match(usb_device_match) 函数看它们和你的设备或接口是否匹配,匹配的话调用device_bind_driver函数,现在就将控制权交到设备驱动了。 

12 、设备驱动选择一个配置

驱动(注意,这里是驱动,之后的事情都是有驱动来接管负责与设备的通信)根据前面设备回复的信息,发送Set_Configuration请求来正式确定选择设备的哪个配置(Configuration)作为工作配置(对于大多数设备来说,一般只有一个配置被定义)。至此,设备处于配置状态(Configured),当然,设备也应该使能它的各个接口(Interface)。
对于复合设备,主机会在这个时候根据设备接口信息,给它们挂载驱动。

“主机”指的是PC的USB主控制器,“设备”指插入USB接口的设备。所有的USB通信的数据流都是由主控器发起,其它从设备进行响应。设备配置需要2个USB端点,一个是IN端点支持最大包长度为8字节,另外一个是OUT端点支持最大包大小为1字节。

一个transfer(传输)由一个或多个transaction(事务)构成,
一个transaction(事务)由一个或多个packet(包)构成,
一个packet(包)由一个或多个sync(域)构成。

1.传输数据通信

 USB的数据通讯首先是基于传输(transfer)的,传输的类型有:中断传输、批量传输、同步传输、控制传输。

2.事务数据通讯

一次传输由一个或多个事务(transaction)构成,事务可以分为:in事务、out事务、setup事务。
	1、in事物:
	令牌包阶段——主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;
	数据包阶段——设备根据情况会作出三种反应(要注意:数据包阶段也不总是传送数据的,根据传输情况还会提前进入握手包阶段)
		1) 设备端点正常,设备往入主机里面发出数据包(DATA0与DATA1交替);
		2) 设备正在忙,无法往主机发出数据包就发送NAK无效包,IN事务提前结束,到了下一个IN事务才继续;
		3) 相应设备端点被禁止,发送错误包STALL包,事务也就提前结束了,总线进入空闲状态。
	握手包阶段——主机正确接收到数据之后就会向设备发送ACK包。
	2、OUT事务:
	令牌包阶段——主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;
	数据包阶段——比较简单,就是主机会设备送数据,DATA0与DATA1交替
	握手包阶段——设备根据情况会作出三种反应
		1)设备端点接收正确,设备往入主机返回ACK,通知主机可以发送新的数据,如果数据包发生了CRC校验错误,将不返回任何握手信息;
		2) 设备正在忙,无法往主机发出数据包就发送NAK无效包,通知主机再次发送数据;
		3) 相应设备端点被禁止,发送错误包STALL包,事务提前结束,总线直接进入空闲状态。
	3、SETUT事务:
	令牌包阶段——主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;
	数据包阶段——比较简单,就是主机会设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令(共有11条)
	握手包阶段——设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后通常是一个IN或OUT事务构成的传输)。

3.包数据通讯

一个事务由一个或多个包(packet)构成,包可分为:令牌包(setup)、数据包(data)、握手包(ack)、特殊包。
	令牌包阶段:启动一个输入、输出或设置的事务;
	数据包阶段:按输入、输出发送相应的数据;
	握手包阶段:返回数据接收情况,在同步传输的IN和OUT事务中没有这个阶段,这是比较特殊的。

4.域数据通讯

一个包由多个域构成,域可分为:同步域(sync)、标识域(pid)、地址域(addr)、端点域(endp)、帧号域(fram)、数据域(data)、校验域(crc)。

在这里插入图片描述
1、PID:
在这里插入图片描述
这里只用(PID04),PID47是PID0~4的取反,用来校验PID
PID1~0:01 令牌包、11 数据包、10 握手包、00 特殊包
在这里插入图片描述
2、地址:

在这里插入图片描述

3、帧号
在这里插入图片描述
4、数据
在这里插入图片描述
5、crc

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

例程
USB鼠标枚举
在这里插入图片描述

1、 获取设备描述符 : 这次传输方式是控制传输,她由5个事务组成,分别是SETUP、IN、IN、IN、OUT。
第一个是控制传输,它包含了4个事物,分别是:1个setup事务,3个in事务,1个out事务
首先是setup事物, 包含了3个包,
第一个包是令牌包,它由主控制器发送给目标设备的0号端口,用于设置目标设备的地址和端口号,我们看到后面两个包都缺省了地址与端口号。在usb系统中,所有的通信都是由主机发出相应的令牌所引起的。
第二个是数据包,由主控器发送给目标设备,其中数据的内容表示:
80:表示要求设备向主机发送信息
06:表示GET_DESCRIPTOR,即设备向主机发送设备描述符
00与01:Word-sized field that varies according to request
00与40:Word-sized field that varies according to request; typically used to pass an index or offset
00:Number of bytes to transfer if there is a:Data stage
总结一下第二个包就是向默认地址0 发送GET_DESCRIPTOR 指令包,请求设备发送设备描述符
第三个是应答包:设备接收到主机发送的数据后会给出应答

第一个in事物,包含了3个包
第一个是in包:由主机发送给设备,表示要设备向主机发送上面请求的设备描述符
第二个是数据包:由设备发送给主机,当然是发送设备描述符
12:表示接下来要求主机向设备发送信息
01:CLEAR_FEATURE、
第三个是应答包,由主机发送给设备

第二个in事物,三个包
第一个是in包:由主机发送给设备,表示需要输入
第二个是数据包:由设备发送给主机,我们来解析一下:
6D:表示要求主机发给设备数据
04:Reserved for future use
第三个是主机给设备的应答包
out事物,三个包
第一个是out包:由主机发给设备
第二个是数据包:由主机发给设备,无数据
第三个包是设备给主机的应答包
在这里插入图片描述

2、 复位
在这里插入图片描述

3、 设置地址
在这里插入图片描述

4、 再次获取设备描述符(同第2部分)
5、 获取配置描述符
在这里插入图片描述

6、 获取接口、端点描述符
在这里插入图片描述

7、 获取字符串描述符
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8、 选择设备配置
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值