周行文 2025-11-08 05:40 采纳率: 98.4%
浏览 14
已采纳

圈圈教你玩转USB:如何识别设备PID和VID?

在进行USB设备开发或调试时,很多开发者会遇到“无法正确识别USB设备的VID和PID”这一常见问题。即使设备已成功连接电脑,但在设备管理器或第三方工具中仍显示为未知设备。这种情况通常源于设备描述符配置错误、驱动程序未正确加载,或VID/PID未在主机系统中注册。如何通过Windows设备管理器、Linux的lsusb命令或专业工具(如USBView)准确获取并验证USB设备的VID(厂商ID)和PID(产品ID)?同时,如何判断这些值是否与固件中定义的一致?掌握这些识别方法对后续驱动匹配、通信协议开发至关重要。
  • 写回答

1条回答 默认 最新

  • 冯宣 2025-11-08 10:12
    关注

    一、USB设备VID与PID识别基础概念

    在USB设备开发过程中,厂商ID(Vendor ID, VID)产品ID(Product ID, PID)是唯一标识一个USB设备的核心参数。它们由设备的描述符(Device Descriptor)提供,并在设备插入主机时通过控制传输发送给操作系统。

    标准USB规范要求每个合法USB设备必须拥有由USB-IF分配的唯一VID,而PID则由厂商自行定义。若VID/PID配置错误或未被系统识别,设备将显示为“未知设备”或无法加载正确驱动程序。

    常见问题包括:

    • 固件中硬编码的VID/PID与实际申请不符
    • 设备描述符结构体初始化错误
    • 主机系统未安装匹配驱动导致无法解析设备信息
    • 使用了未注册的测试用VID(如0x1234)但未手动绑定驱动

    二、Windows平台下获取VID/PID的方法

    Windows提供了多种方式查看连接的USB设备及其VID/PID信息:

    1. 设备管理器(Device Manager):右键“此电脑”→“管理”→“设备管理器”,展开“通用串行总线控制器”或“其他设备”。找到目标设备(可能标记为“未知设备”),右键属性→“详细信息”选项卡→选择“硬件ID”属性。通常会看到类似如下格式的字符串:
      USB\VID_1A86&PID_7523
    2. PowerShell命令查询:可通过WMI接口批量获取USB设备信息。 Get-WmiObject Win32_PnPEntity | Where-Object {$_.PNPClass -eq "USB"} | Select Name,HardwareID
    3. USBView工具(微软官方诊断工具):该工具可深度展示USB树状拓扑结构,精确显示每个端点的描述符内容,包括bDeviceClass、idVendor、idProduct等字段。
    方法适用场景是否支持未知设备识别是否需额外安装
    设备管理器快速定位已枚举设备部分支持(依赖硬件ID)
    PowerShell脚本自动化批量分析
    USBView深入调试描述符错误
    Zadig/Lsusb-Win32驱动替换与验证

    三、Linux系统下的VID/PID提取技术

    Linux提供了更为底层且灵活的工具链用于USB设备调试:

            $ lsusb
            Bus 001 Device 005: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
        

    输出中“1a86”为VID,“7523”为PID。进一步可通过-v参数查看完整描述符:

            $ lsusb -v -d 1a86:7523 | grep -i "idVendor\|idProduct\|iManufacturer\|iProduct"
        

    也可直接读取sysfs虚拟文件系统数据:

            /sys/bus/usb/devices/<busnum>-<devnum>/idVendor
            /sys/bus/usb/devices/<busnum>-<devnum>/idProduct
        

    例如:

    cat /sys/bus/usb/devices/1-2/idVendor

    四、验证固件中定义的VID/PID一致性

    确保主机侧读取的VID/PID与嵌入式固件一致至关重要。以基于STM32 HAL库的代码为例:

            /* usbd_desc.c */
            USBD_DeviceDescriptorTypeDef device_descriptor = {
                .bLength            = USB_LEN_DEV_DESC,
                .bDescriptorType    = USB_DESC_TYPE_DEVICE,
                .bcdUSB             = 0x0200,
                .bDeviceClass       = 0xFF,
                .bDeviceSubClass    = 0xFF,
                .bDeviceProtocol    = 0xFF,
                .bMaxPacketSize     = 64,
                .idVendor           = 0x1A86,  // 必须与实际一致
                .idProduct          = 0x7523,  // 必须匹配
                .bcdDevice          = 0x0100,
                .iManufacturer      = 1,
                .iProduct           = 2,
                .iSerialNumber      = 3,
                .bNumConfigurations = 1
            };
        

    建议做法:

    • 建立统一的头文件定义VID/PID宏,供上位机和固件共用
    • 在CI流程中加入lsusb抓取结果比对步骤
    • 使用Wireshark抓包分析枚举过程中的GET_DESCRIPTOR请求响应

    五、典型故障排查流程图

    当设备无法识别时,推荐按以下逻辑进行诊断:

    graph TD A[USB设备插入主机] --> B{设备是否被枚举?} B -- 否 --> C[检查供电、D+/D-接线] B -- 是 --> D[查看设备管理器/lsusb] D --> E{能否看到VID/PID?} E -- 否 --> F[使用USBView/Wireshark抓包] E -- 是 --> G[比对固件中定义值] G --> H{是否一致?} H -- 否 --> I[修正固件描述符] H -- 是 --> J[检查INF驱动绑定或udev规则] J --> K[加载自定义驱动或libusb访问]
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 11月9日
  • 创建了问题 11月8日