USB枚举过程(具体请参考USB Specification Chapter 9)
1.枚举:
主机从USB设备中读取一些信息知道是一个什么样的设备,如何进行通信,并为设备选择合适的驱动程序。
USB架构中hub负责设备的连接和断开,利用interrupt IN Endpoint 向主机报告。在系统启动前主机轮询查看是否有设备连接(主机存在一个root hub)。
一旦有设备连接上来,主机会发送一系列请求给设备所挂载的hub上,再由hub建立起host到divice的通信。主机通过控制传输方式,通过端点0发送各种请求。设备收到请求后回复相应的信息,进行枚举操作。
控制传输分为三个阶段,分别是建立(setup),数据(IN/OUT),确认(ack/nak)
2.设备状态图:
如上图所述,USB设备插入到USB接口即为连接状态;USB设备的电源可从接口供电,也可以自己供电,当USB设备接入到USB接口上USB设备加电,VBUS对设备产生作用;设备对电源支持的能力通过配置描述符来反映的,设备可以改变其供电方式,改变供电方式后设备可能返回到加电状态,从新配置完成枚举过程;上电后的设备接收到总线的复位信号,完成复位进入到默认状态,通过设备终端阻抗,选择设备的工作速度(LS/FS);USB设备加电复位以后使用缺省地址,USB设备只对缺省通道请求产生响应;在SUSB设备正常工作以前设备需要被正确配置,配置设备即给设备的配置寄存器写入一个非零数据。设备在总参一定时间没有传输后进入挂起状态,当总线活动时退出该状态。
3.枚举步骤:
-
设备插入到USB接口上,连接到hub上,hub给设备供电,设备处于上电状态;
-
hub检测USB设备上D+或D-数据线被拉高,认为设备接入并根据电压判断设备所支持的速度类型;
-
hub报告设备的信息给主机,包括设备接入信息和速度信息,主机在接收到设备连接后,等待一段时间发送给hub请求复位设备(SE0),当设备是FS时,主机还需要判断设备是否支持HS模式(高速检测,需hub支持HS,见附一);
-
主机发送get_port_status请求给hub查询设备是否完成复位,hub完成复位后撤销复位信号设备处于default状态,准备接收主机发送的请求,设备和主机通过默认地址0端点0进行传输;
-
主机发送get_descriptor请求获取默认管道最大包长度,设备描述符的第八个字节表示设备端点0的最大包长度,设备返回的包(IN package)中,主机只关注第八个字节的数据,完成第一次控制传输后,系统要求设备再次复位设备(USB规范中没有改要求?)
-
主机发送set_address请求分配一个唯一的地址给设备,设备读取该请求并返回确认信息;
-
主机发送get_descriptor请求读取完整设备描述符,配置描述符,字符集描述符等;
-
主机解析设备描述符等信息,选择一个合适的驱动给设备,并说明设备已找到,将设备添加到usb设备列表中,完成设备的枚举;
以下是一些关于USB枚举的链接供参考:
-
USB枚举过程_usb枚举之后是怎么样匹配设备驱动的-优快云博客
-
USB枚举详细过程剖析_au6465r sd卡枚举成功如何知道-优快云博客
-
新浪博客
-
USB 枚举过程_usb debounce-优快云博客
以下是USBD的USB各种描述符的说明信息:
以下是一个关于USB枚举的讲解视频:
附一:高速检测(转载自全速USB和高速USB的识别过程分析_usb2.0 识别host device-优快云博客)
高速设备看到复位信号后,通过内部的电流源向D-线持续灌大小为17.78mA电流。因为此时高速设备的1.5k上拉电阻还未撤销,在hub端,全速/低速驱动器形成一个阻抗为45欧姆(Ohm)的终端电阻,2电阻并联后仍是45欧姆左右的阻抗,所以在hub端看到一个约800mV的电压(45欧姆*17.78mA),这就是Chirp K信号。Chirp K信号的持续时间是1ms~7ms。
在hub端,虽然下达了复位信号,并一直驱动着SE0,但USB2.0的高速接收器一直在检测Chirp K信号,如果没有Chirp K信号看到,就继续复位操作,直到复位结束,之后就在全速模式下操作。如果只是一个全速的hub,不支持高速操作,那么该hub不理会设备发送的Chirp K信号,之后设备也不会切换到高速模式。
设备发送的Chirp K信号结束后100us内,hub必须开始回复一连串的KJKJKJ….序列,向设备表明这是一个USB2.0的hub。这里的KJ序列是连续的,中间不能间断,而且每个K或J的持续时间在40us~60us之间。KJ序列停止后的100~500us内结束复位操作。hub发送Chirp KJ序列的方式和设备一样,通过电流源向差分数据线交替灌17.78mA的电流实现。
再回到设备端来。设备检测到6个hub发出的Chirp信号后(3对KJ序列),它必须在500us内切换到高速模式。切换动作有:
1. 断开1.5k的上拉电阻。
2. 连接D+/D-上的高速终端电阻(high-speedtermination),实际上就是全速/低速差分驱动器。
3. 进入默认的高速状态。
执行1,2两步后,USB信号线上看到的现象就发生变化了:hub发送出来的Chirp KJ序列幅值降到了原先的一半,400mV。这是因为设备端挂载新的终端电阻后,配上原先hub端的终端电阻,并联后的阻抗是22.5欧姆。400mV就是由17.78mA*22.5Ohm得来。以后高速操作的信号幅值就是400mV而不像全速/低速那样的3V。
至此,高速设备与USB2.0 hub握手完毕,进行后续的480Mbps高速信号通信。