果壳中的USB(7)终结篇:USB枚举

枚举

枚举是一个确定刚刚连接到总线的设备及其所需参数的过程,如功耗,端点的个数和类型,产品类别等等。然后主机为设备分配地址,使能配置并允许设备在总线上传输数据。USB 规范的 9.1.2 节①详细介绍了一个相当常规的枚举过程。但是,首次编写 USB 固件时,很容易准确地知道主机在枚举过程中的响应,而不是规范中详述的常规枚举过程。

常见的 Windows 枚举涉及以下步骤:
  1. 主机或 hub 经由设备数据线对上的上拉电阻检测到有新设备连接事件。主机等待至少 100ms 以等待设备插入并上电稳定。
  2. 主机发出一个 Reset,使设备处于 Default 状态。设备现在可以响应默认地址为 0 的数据包。
  3. Windows 主机询问设备描述符的前 64 字节。
  4. 一旦收到设备描述符的前 8 个字节,主机立即启动一个总线 Reset。
  5. 主机发送一个 SetAddress 命令,使设备处于 Address 状态。
  6. 主机查询完整的 18 字节的设备描述符。
  7. 然后,主机要求配置描述符的 9 字节,以确定整体大小。
  8. 主机要求 255 字节的配置描述符。
  9. 主机要求字符串描述符(如果指定了)。
 
第 9 步结束时,Windows 将询问您设备的驱动程序。然后通常会看到它在发出 SetConfiguration 请求之前再次请求所有描述符。
 
上述枚举过程是 Windows 2000,Windows XP 和 Windows 98 SE 共有的。
 
步骤 4 通常会让第一次写固件的人感到困惑。主机要求设备描述符的前 64 个字节,因此当主机在收到前 8 个字节后重置设备时,自然会认为设备描述符或固件处理请求有问题。但是,正如许多人会告诉您的那样,如果您坚持不懈地 SetAddress,它将在接下来要求完整的 18 个字节的设备描述符中获得回报。
 
通常,当描述符出现问题或发送描述符出现问题时,主机将在两次请求之间长时间停顿的情况下尝试读取三次。 第三次尝试后,主机放弃并报告您的设备错误。

附录

①9.1.2 总线枚举
将 USB 设备连接到总线或从总线移除时,主机使用被称作总线枚举的过程来标识和管理必要的设备状态。USB 设备连接到带电端口,将执行以下操作:
  1. USB 设备连接的 hub 经由它的状态改变管道(pipe)把事件通知给 host。此时设备处于 Powered 状态,设备连接的端口处于 Disabled 状态。
  2. host 询问 hub,来确定更改的进一步信息。
  3. 现在,host 知道新设备连接到了哪个端口上,host 等待至少 100ms,以让插入过程和设备上电稳定。主机然后向端口发送 Enable 和 Reset 命令。
  4. hub 代替端口执行 Reset 过程。Reset 信号释放后,端口被使能。此时设备处于 Default 状态,并可以从 VBUS 获取不超过 100mA 的电流。它的所有寄存器和状态都已重置,并且它可以在默认地址上进行回应。
  5. host 为设备分配一个唯一的地址。设备处于 Address 状态。
  6. 设备在收到唯一地址之前,它的默认控制管道依旧可以经由默认地址访问。host 读取设备描述符,确定设备默认管道实际的最大数据有效负载。
  7. host 读取 0~n-1 的配置描述符以获取配置信息,n 是配置的个数。此过程可能需要几毫秒才能完成。
  8. host 根据配置信息和 USB 设备的使用方式,为设备分配一个配置。此时设备处于 Configured 状态,并且配置中的所有端点都已经具有其描述的特征。设备现在可以从 VBUS 获取描述符中指定大小的电流。在设备看来,目前它已经处于可用状态(ready for use)。
 
USB 设备移除时,hub 会再次向 host 发送通知,拔除设备将禁止相应的端口。收到通知后,host 将更新它本地的拓扑信息。
原文地址:https://www.cnblogs.com/rockyching2009/p/14001643.html