USB 规范定义的设备状态总共有 6 个,分别是连接(Attached)、上电(Powered)、默认(Default)、地址(Address)、配置(Configured)和挂起(Suspend)。USB 总线枚举过程中,USB 设备需要经历后 4 个状态,如图 6-12 所示。
USB 集线器负责监测设备的连接情况,而 USB 主机会通过集线器轮询地查询设备。当主机发现有一个新的设备时,会要求集线器建立与设备的
通信通道,即设备的端点 0,控制传输端点。之后,主机会通过此通道向设备发送一系列的标准 USB 请求以获取所需的信息,设备必须响应这些请求并且采取适当的动作。这个过程称为 USB 的总线枚举。设备描述符包含的是设备信息,而 USB 请求是指 USB 主机和设备之间获取特定信息的格式,标准的 USB 请求有 11 个。
设备枚举的步骤如下:
• 在主机的 USB 集线器口连接上 USB 设备,主机会首先发出一个获取设备描述符的请求Get_Descriptor(wValue = 0x01)。设备接收到这个主机请求,发送设备描述符,这时由于主机对设备的描述符将有多长实际上都不知道,所以这个步骤只是试探性的。实际上,这时候即使只发送部分设备描述符,主机也会进行下面的步骤。
• 主机发送设置地址的请求 Set_Address,这时候,设备的地址就是 Set_Address 请求数据包内对应的地址,一般为 02 或 03。
• 完成地址设置后,主机会再次发送 Get_Descriptor(wValue = 0x01)的请求,读取完整的设备描述符,一般为 18 个字节,如果没有收到正确的设备描述符,主机会再次尝试,总共尝试 3 次。
• 主机发送获取配置描述符的请求 Get_Descriptor(wValue = 0x02),此时请求的仅仅是配置描述符,总长度为 9 个字节。
• 主机再次发送获取配置描述符的请求 Get_Descriptor(wValue = 0x02),这次请求的数据长度可能会是 0xFF,这表示主机要求获取所有的配置信息,包括配置描述符、接口描述符和端点描述符,设备应该将以上所有的描述符都发送给主机。
• 在正确获取到所有配置描述符之后,主机就会开始查找驱动,如果未能搜索到驱动的话,主机系统会提示找到设备但是未找到驱动。
• 当正确找到驱动后,主机会给设备发送 Set_Configura
tion 的请求,这样才算是一个设备被正确枚举了。