Linux系统下的USB设备枚举详解

linux usb 枚举过程

时间:2024-12-13 21:10


Linux USB 枚举过程详解 在现代计算机系统中,USB(Universal Serial Bus)接口已成为连接各种外设的标准方式

    Linux操作系统通过一套复杂的机制来识别和配置这些USB设备,这一过程被称为“枚举”

    本文将深入探讨Linux系统中USB设备的枚举过程,从物理连接到设备配置完成的每一步进行详细解析

     一、USB枚举的基本概念 USB枚举的本质是USB主机获取USB设备的参数信息,并对可配置参数进行配置的过程

    当枚举结束时,USB设备将使用在枚举过程中USB主机所配置的参数进行工作,从而确保通信双方使用相同的参数

     USB设备在枚举完成之前,会经历一系列的状态变化,这些状态包括连接状态(attach)、供电状态(powered)、默认状态(default)、地址状态(addressed)、配置状态(configured)和挂起状态(suspended)

    当设备状态变为配置状态时,即可认为USB设备与USB主机间的枚举完成

     二、USB枚举的详细步骤 1.连接状态 USB设备首先需要与主机建立起物理连接

    USB主机和设备都必须具备检测连接的能力

    这通常通过检测VBUS、D+、D-等信号线的电平信号状态来实现

     2.供电状态 USB设备可以从USB的VBUS上获取电源,或者通过外部电源获取电源(称为自供电设备)

    常见的是通过VBUS供电的设备,称为总线供电设备

     3.默认状态 USB设备进入供电状态后,在被复位之前,不能响应总线上的任何事务

    只有当USB设备被复位,处于默认状态后,才会响应主机发送过来的请求

     4.地址状态 USB设备在被复位后,且在USB主机给USB设备设置一个新的地址之前,所有的USB设备都使用默认的0地址与主机进行通信

    当USB设备在收到主机发送的设置地址请求之后,USB设备就会得到一个唯一的地址,用于后续通信

     5.获取设备描述符 这是枚举过程的第一步

    主机通过获取描述符请求来获取设备的描述符

    对于高速设备和低速设备,用于控制传输的端点0支持的最大包长度是确定的,分别是64字节和8字节

    但对于全速设备,端点0支持的最大包长度可能是8字节、16字节、32字节或64字节

    在USB主机获取到设备的设备描述符之前,USB主机无法确定USB设备端点0的最大包长度,这可能导致USB主机获取设备描述符的请求无法正常完成

     针对这个问题,不同的USB主机系统有不同的处理方式

    Windows 7系统在第一次获取设备描述符后,直接进行复位,将设备状态重置为初始状态,以确保能够获取到完整的设备描述符

    而Linux系统(如Ubuntu)在第一次获取设备描述符时,只获取其前8字节,然后根据设备描述符的第8个字节(即设备端点0所支持的最大包长度)来配置后续的控制传输

     6.设置设备的地址 主机发送设置地址请求来设置设备的地址

    设备收到地址后,进入地址状态

    在该设备未复位或断开之前,设备会一直使用该地址与主机通信

     7.获取完整设备描述符 在新地址设置完成后,主机与设备将会用新的地址通信

    USB主机会用新地址与设备进行通信,来获取完整的18字节的USB设备描述符

     8.获取配置描述符 由于每个设备配置描述符的长度都不一样,USB主机无法提前得知设备的配置描述符长度

    因此,配置描述符的数据中必须要有表示长度的部分

    主机将会先获取配置描述符的前9个字节,若该配置下的最大消耗电流值超过了USB主机可提供的额度,该配置将不可用

    如果设备中的所有配置都不可用,该设备也会不可用,这将中止整个枚举流程

     9.获取字符串描述符和配置设备的配置描述符 在获取配置描述符后,主机还需要获取字符串描述符,以了解设备的厂商、产品等信息

    最后,主机通过设置接口和设置配置来配置设备的相关配置项,使设备能够正常工作

     10. 挂起状态 当USB总线持续3ms没有活动时,设备会自动进入挂起状态

    这是USB协议实现低功耗的一种机制

    进入挂起状态后,USB设备要维持所有的内部状态,直到总线恢复后继续工作

     三、Linux下的USB枚举管理 在Linux系统中,可以通过多种方式对USB设备进行重新枚举和管理

     1.使用lsusb命令 `lsusb`命令可以列出当前连接的USB