我必须支持越来越多的硬件,至少按照今天的标准来考虑。几乎所有这些设备的共同点是FTDI FT232 UART芯片,它充当串口转USB。 Windows将其视为标准COM端口,但它是虚拟化的。
因此,以编程方式识别这些设备很麻烦。由于它们都使用相同的芯片(或类似芯片),因此通过典型的硬件ID查询无济于事,因为它始终是相同的。是否有任何其他指标可用于ID设备?
我目前的解决方案是遍历所有活动的串行端口,并以所有常见的波特率发出预先知道的“hello”命令。如果我在测试的波特率下收到该端口的响应,则假定找到了感兴趣的设备。一些伪代码:
for each(Serial Port)
{
for each(Device Definition)
{
for each(Baud Rate)
{
WriteToPort(Device Definition.helloString, Baud Rate)
ReadPort(response)
if(response)
Serial Port = this device // break loop
else
continue;
}
}
}
这样工作正常,但是不可靠且速度最慢,因为我必须等待每个测试波特率的读取超时,乘以实际连接到系统的每个设备(可能有一个或多个)。每个必须支持的新硬件都会变慢。
此代码的一个特性是它“Just Works”™,用户不必大惊小怪识别他们的设备和设置COM连接。很明显我的方法不可扩展;有什么我可以做的,除了赋予用户权力和丧失我的软件的一种兑换品质之外?
编辑:我想用一些展示问题的视觉效果来更新我的问题。接受的答案有一些信息,但当我决定实施时,我仍然不确定如何继续。
在我的注册表中考虑以下两个条目:
它们共享相同的供应商ID,硬件ID以及几乎所有其他区别属性。然而,众所周知,它们是不同的设备;他们共同的唯一共同点是通信接口,即FTDI芯片。知道PortName / COM地址根本没有用,因为它们从系统接收的数字是任意的......无论下一行是什么。
如何以红色圈出数字?据我所知,这是唯一有用的信息,因为设备似乎会在其条目中附加类似的序列号。
下一张图片显示了一个实际有用的条目:
列出制造商,其中包含已注册的供应商和硬件ID,并且已显示已连接的设备。我可以做点什么。不幸的是,这似乎是例外,而不是规则。
还有其他方法可以继续识别这些设备吗?并行运行检查将提供一个小的提升,但真正的瓶颈是测试命令集的波特率。
答案 0 :(得分:1)
由于您可以并行查询所有设备,因此该方法可以跨设备进行扩展,但不能跨协议/波特率进行扩展。
每个USB设备都可以指示其制造商,描述,序列号等。我非常怀疑它们实际上是相同的,因为尽管使用FTDI芯片,供应商可以自定义制造商和说明字符串,同时保持VID和PID不变,以避免支付签署自定义变体驱动程序所需的“税”。
对于FTDI设备,有一个相当粗糙的driver-specific way of getting the device information。或者,您可以使用始终存在的D2XX功能,查询设备那里,使用FT_GetComPortNumber
获取端口号,然后继续使用常规Windows样式的com端口打开它的API。
如果设备真的没有完全不同(请确保先检查一下!!!),那么你能做的最好的事情是缓存最后在给定的com端口号上工作的协议,然后先尝试使用给定的com端口。如果失败,则枚举其他协议。