一、背景
公司有3个下位机USB接入,其中2个设备用的STM32,另一个用的ESP32,测试组发现STM32的两个设备重启的时候,有一个设备恢复USB连接总要慢很多,大概3~5秒,大概原因就是两个stm32设备移植USB CDC库的时候,没有区分设备描述导致第二个设备接入时PC在分配USB资源的时候需要解决冲突。
        二、解决办法:

USB设备描述中有几个关键字符串

  • iManufacturer: 制造商字符串
  • iProduct: 产品字符串
  • iSerialNumber: 序列号字符串

在STM32芯片上使用USB虚拟串口(Virtual COM Port, VCP)时,设备管理器显示的设备名称(如“STMicroelectronics Virtual COM Port”)通常是由USB设备描述符中的制造商字符串产品字符串序列号字符串字段决定的。前面两个修改较为复杂,涉及驱动安装文件,最后一个序列号可以通过修改底层固件实现。

根据不同的设备使用宏定义区分usbd_desc.c中USBD_SERIALNUMBER_FS_STRING(这里我使用的是USB全速)宏定义字符串即可:

修改后,两个设备同时重启,识别速度就不会有太大的区别了,

        三、以下是AI给的总结解释,可供参考
1. ​操作系统对相同设备的处理机制

当两个相同的 USB 设备(相同的 VID/PID)同时接入时,操作系统会尝试区分它们。如果它们的 iSerialNumber 相同,操作系统会认为它们是同一个设备的多个实例,需要进行额外的处理:

  • 设备枚举:操作系统需要为每个设备分配资源并加载驱动程序。如果 iSerialNumber 相同,操作系统可能需要重新验证设备的唯一性,这会增加枚举时间。
  • 驱动程序绑定:Windows 使用 iSerialNumber 来绑定驱动程序。如果 iSerialNumber 相同,操作系统可能会尝试为两个设备绑定同一个驱动程序实例,导致冲突或延迟。

2. ​**iSerialNumber 的作用**

iSerialNumber 是 USB 设备描述符中的一个字段,用于标识设备的唯一性。它的主要作用是:

  • 区分相同 VID/PID 的设备:操作系统使用 iSerialNumber 来区分相同 VID/PID 的多个设备。
  • 驱动程序实例化:Windows 使用 iSerialNumber 为每个设备创建独立的驱动程序实例。

3. ​修改 iSerialNumber 后的效果

当你为两个设备设置不同的 iSerialNumber 后,操作系统能够快速区分它们:

  • 快速枚举:操作系统可以立即识别出这是两个不同的设备,无需额外的验证步骤。
  • 独立驱动程序实例:Windows 可以为每个设备创建独立的驱动程序实例,避免冲突。
  • 资源分配:操作系统可以更快地为每个设备分配资源(如 COM 端口号),减少延迟。

4. ​为什么识别速度变快

通过修改 iSerialNumber,你消除了操作系统在处理相同设备时的歧义和额外步骤,从而提高了设备识别的效率。具体原因包括:

  • 唯一标识:不同的 iSerialNumber 让操作系统能够立即识别出两个设备是独立的。
  • 避免冲突:操作系统无需为两个设备绑定同一个驱动程序实例,减少了潜在的冲突和重试。
  • 资源分配优化:操作系统可以更快地为每个设备分配资源(如 COM 端口号),无需等待冲突解决。

5. ​最佳实践

为了避免类似问题,建议在设计和开发 USB 设备时:

  • 使用唯一的 iSerialNumber:确保每个设备都有唯一的序列号,即使它们的 VID/PID 相同。
  • 动态生成序列号:可以在设备固件中动态生成序列号(如基于芯片唯一 ID),以确保每个设备的 iSerialNumber 都不同。
  • 测试多设备场景:在实际使用中测试多个设备同时接入的情况,确保识别速度和稳定性。
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐