可靠地检测外部硬件的存在 [英] Reliably detecting presence of external hardware

查看:57
本文介绍了可靠地检测外部硬件的存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须支持越来越多的硬件,至少按照今天的标准,这些硬件被认为是传统的.几乎所有这些设备的共同点是一个 FTDI FT232 UART 芯片,它充当串行到 USB 转换器.Windows 将其视为标准 COM 端口,尽管它是虚拟化的.

I have to support an increasing range of hardware that's considered, at least by today's standards, legacy. What nearly all of these devices have in common is an FTDI FT232 UART chip, which acts as a Serial-to-USB converter. Windows sees it as a standard COM port, though it is virtualized.

因此,以编程方式识别这些设备很麻烦.由于它们都使用相同的芯片(或类似芯片),因此通过典型的硬件 ID 进行查询是没有帮助的,因为它总是相同的.是否还有其他指标可用于识别设备?

Consequently, programmatically identifying these devices is troublesome. Since they all use the same chip (or similar), querying by typical Hardware IDs is no help since it's always the same. Are there any other metrics available to ID a device?

我目前的解决方案是遍历所有活动的串行端口,并以所有常见的波特率发出预先知道的hello"命令.如果我以测试的波特率在该端口上收到响应,则假定找到了感兴趣的设备.一些伪代码:

My current solution has been to loop through all the active Serial Ports, and issue pre-known "hello" commands at all the common baud rates. If I receive a response on that port at the baud rate tested, it's assumed the device of interest is found. Some pseudocode:

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;
        }
    }
}

这可以正常工作,但充其量是不可靠和缓慢的,因为我必须等待每个测试波特率的读取超时,乘以实际连接到系统的每个设备(可以有一个或多个).对于必须支持的每个新硬件,这会变得更慢.

This works OK, but is unreliable and slow at best, as I have to wait for the read to timeout for each tested baud rate, multiplied by each device actually connected to the system (there can be one or many). This gets slower with each new piece of hardware that has to be supported.

此代码的一个特点是它Just Works"™,用户不必为识别他们的设备和设置 COM 连接而大惊小怪.很明显,我的方法不可扩展;除了赋予用户权力并丧失我的软件的一种可赎回品质之外,我还能做些什么吗?

One of the features of this code is that it "Just Works"™, users don't have to fuss with identifying their device and setting up the COM connection. It's pretty clear that my method isn't scalable; Is there anything I can do, short of empowering the user and forfeiting one of the redeeming qualities of my software?

我想用一些展示问题的视觉效果来更新我的问题.接受的答案包含一些信息丰富的信息,但是当我决定尝试实施时,我仍然不确定如何进行.

I wanted to update my question with some visuals that demonstrates the issue. The accepted answer had some informative information, but when I decided to give the implementation a go, I'm still not certain how to proceed.

考虑我的注册表中的以下两个条目:

Consider the following two entries in my registry:

它们都共享相同的供应商 ID、硬件 ID 和几乎所有其他可区分属性.然而,众所周知,它们是不同的设备;它们唯一的共同点是通信接口,即 FTDI 芯片.知道 PortName/COM 地址根本没有帮助,因为它们从系统接收到的数字是任意的……无论接下来是什么.

They both share the same Vendor ID, Hardware ID, and virtually every other distinguishing property. However, they are known to be different devices; The only thing they share in common is the communication interface, ala FTDI chip. Knowing the PortName / COM Address isn't helpful at all since the number they receive from the system is arbitrary... whatever is next in line.

红色圈出的数字是如何产生的?据我所知,这是唯一有用的信息,因为设备似乎收到了附加到其条目的类似序列号.

How are the numbers circled in red generated? As far as I can tell, this is the only useful piece of information as it seems like devices receive similar Serial Numbers appended to their entry.

下图显示了一个实际有用的条目:

The next image shows an entry that is actually useful:

列出了制造商,带有注册的供应商和硬件 ID,并有所连接设备的描述.这我可以做些什么.不幸的是,这似乎是例外而不是规则.

The manufacturer is listed, with a registered Vendor and Hardware ID, and there is a description of the connected device. This I could do something with. Unfortunately, it seems to be the exception rather than the rule.

还有其他方法可以继续识别这些设备吗?并行运行跨设备检查将提供小幅提升,但真正的瓶颈是针对命令集测试波特率.

Is there any other way to proceed IDing these devices? Running checks across the devices in parallel will provide a small boost, but the real bottleneck is testing baud rates against the command sets.

推荐答案

由于您可以并行查询所有设备,因此此方法可跨设备扩展,但不能跨协议/波特率扩展.

Since you can be querying all the devices in parallel, this method scales across devices, but not across the protocols/baudrates.

每个 USB 设备都可以标明其制造商、描述、序列号等.我非常怀疑这些实际上是否相同,因为尽管使用了 FTDI 芯片,但供应商可以放置自定义制造商和描述 字符串,同时保持 VID 和 PID 不变,以避免需要支付签署驱动程序自定义变体所需的税".

Every USB device can indicate its manufacturer, description, serial number, etc. I very much doubt that those will in fact be identical, since in spite of using the FTDI chip, the vendors can put custom Manufacturer and Description strings, while keeping the VID and PID unchanged to avoid the need to pay the "tax" needed to sign a custom variant of the driver.

对于 FTDI 设备,有一种相当粗糙的驱动程序特定的获取方式设备信息.或者,您可以使用始终存在的 D2XX 功能,查询那里的设备,使用 FT_GetComPortNumber 获取端口号,然后继续使用常规 Windows 打开它-风格的 com 端口 API.

For FTDI devices, there's a rather crude driver-specific way of getting the device information. Alternatively, you can use the always-present D2XX functionality, query the devices there, use FT_GetComPortNumber to get the port number, and then proceed to open it using the regular Windows-style com port APIs.

如果设备真的没有什么不同(确保你先检查一下!!!),那么你能做的最好的事情就是缓存最后在给定的com端口号上工作的协议,然后先尝试那个给定的 com 端口.如果失败,则枚举其他协议.

If the devices are truly not different at all (make sure you check that first!!!), then the best you can do is cache the protocol that last worked on a given com port number, and try that one first for a given com port. If it fails, you enumerate other protocols.

这篇关于可靠地检测外部硬件的存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆