可以通过VID和PID区分不同厂家的USB设备,但是同一厂家同一类设备VID和PID甚至bcdDevice等也都是一样的,此时如何区分不同实例呢。 比如常见的USB转串口线,可能同时接多个,每个设备都是一模一样的,如何区分呢,此时要用到iSerialNumber。iSerialNumber不为0时,则由iSerialNumber区分,不同的值就代表不同的设备实例,iSerialNumber为0时则Windows通过其他方式(USB的路径,HUB口等)等区分。
我们在使用某些USB转串口线时,可能有疑惑,为什么有些换USB口COM号不会变,有些换USB口COM号就会变。这一篇我们就通过实测来搞懂,究竟CDC虚拟串口的COM号什么时候固定,什么时候会自动变。
以上提到了可以通过设备描述符的iSerialNumber区分实例,
iSerialNumber 为0x00则USB 设备不使用序列号。
iSerialNumber不为0x00则USB设备使用序列号。 iSerialNumber 字符串索引对应的字符串即序列号字符串。
如果使用序列号,则序列号必须唯一标识同一类设备的每个实例,即同类设备,不同的个体需要不一样。设备描述符的idVendor,idProduct,bcdDevice相同,则 iSerialNumber 必须不同,以便区分不同设备。
而使用序列号时,序列号字符串也必须符合为可见有效字符(0x20~0x7f,不含0x2C(逗号))才认为是有效,否则认为无效相当于iSerialNumber为0.
此时不使用序列号,Windows操作系统会自动根据其他方式区分(USB路径,HUB口等),自动修改COM口。此时可以接多个同样的设备,COM号会自动修改,且插入不同的USB口时COM号不同。
以下进行测试(以下是一个双CDC设备),可以看到COM口连续变化,换USB口自动变化。
换一个USB口则COM会自动变
此时使用序列号,Windows操作系统以iSerialNumber为准区分不同实例,不会自动修改COM口。换了USB口COM号也固定。
此时不可以接多个同样的设备,因为COM号会重复。
测试如下,可以看到换USB口COM号不变,且不是连续:
换USB口,依然是COM22和COM25.
快捷键打开注册表: win图标按键+r按键
输入regedit回车
找到表项[HKEY LOCAL MACHINEISYSTEM\ControlSet001\ControlUsbFlags],修改如下项目(不存在则添加):
"GlobalDisableSerNumGen"=hex:01
"lgnoreHWSerNum19930101"=hex:01
这里VID是0x1993 PID是0x0101
修改之前是如下
测试,此时iSerialNumber != 0换USB口,COM口也会自动变化,也支持多个相同设备,COM会自动连续变化。效果和iSerialNumber=0一样。
换USB口。
注册表修改如下时,就会不管iSerialNumber的值,强制认为其相当于0不使用设备序列号。
Windows自动区分同样的设备(实际时通过USB的路径,HUB口等区分)。
"GlobalDisableSerNumGen"=hex:01
"lgnoreHWSerNumxxxxyyyy"=hex:01
其中xxxx为16进制vid,yyyy为16进制pid。
所以对于CDC如果想要COM号不变,则可以设置iSerialNumber不为0,此时注册表项设置为"GlobalDisableSerNumGen"=hex:00。
,但是此时不能接多个同样的实例。 如果既要要求每个实例的COM不变,且能区分不同实例,则每个实例的iSerialNumber要不一样,可以通过引脚配置,flash参数,efuse,otp等方式初始化时配置。
如果想要COM自动变化,可以接多个同样的实例,则可设置iSerialNumber为0,或者按前面介绍的修改注册表,强制让系统不使用序列号。