【问题标题】:Make USB virtual COM device persistent through reboots通过重启使 USB 虚拟 COM 设备持久化
【发布时间】:2014-04-09 18:28:19
【问题描述】:

我有一个嵌入式控件,它使用 STM32 微控制器,它使用其 USB 端口作为“虚拟 COM 端口”与计算机通信。我目前正在运行一个循环测试,其中控件自动循环打开 5 分钟并关闭 10 秒。这是为了捕获每 50-200 次重启时出现的错误。

设备已经通过虚拟 COM 端口输出调试消息,但是当设备重新启动时,USB 设备断开并重新连接。然后我用来监视输出的任何程序(putty、Tera Term 等)都会失去连接,我必须手动拔下并重新插入 USB 电缆并重新启动我正在使用的任何 COM 应用程序。

我的目标是设置 Tera Term 或 putty 以保持 COM 端口打开并将整个会话写入日志文件,但由于重新启动,USB 设备不会持久。

有什么方法可以“虚拟化”USB 端口或修改 .ini 文件以使 USB 端口持久化?这是我认为是 .ini 文件的相关部分

[USBtoSer.nt.Services] 
AddService=usbser, 0x00000002, DriverService

[DriverService] 
DisplayName=%USBIOMport% 
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys 

我无法修改在 STM32 上运行的嵌入式应用程序,只能通过 USB 通过预编程终端与其交互

编辑:这里是a link 来自 Microsoft 的信息,它解释了上述内容。我没有运气确定哪种更改适用于我的应用程序,因此我可能会使用不同的 ErrorControl 和 StartType 开始试错(尽管从我读到的内容来看,我几乎不怀疑它们会解决我的问题)

【问题讨论】:

  • 由于您被限制使用别人编写的终端,您自己没有更改,也没有对嵌入式代码进行任何更改,所以这个问题根本没有编程组件。你可以试试超级用户。
  • 感谢@BenVoigt 的推荐,我可以这样做。我当然不必使用不同的终端,我可以自己编写,但这仍然不能解决设备非持久性的问题。您是否建议我可以编写自己的程序来保持主动轮询 USB 端口?
  • 如果您编写了自己的程序,您可以处理与设备移除相关的操作系统事件并关闭端口。然后,当设备回来时,它不会找到正在使用的首选端口,并会回收它。您还会收到一个设备连接事件,表明又到了打开端口的时候了。
  • 感谢@BenVoigt,我认为可能有一种方法可以通过编程方式来实现,我只是在寻找一个简单的解决方案,而无需滚动我自己的串行记录器。如果我在 SuperUser 上没有任何运气,我可能会回到这里问一个不同的问题 :-)

标签: windows serial-port usb driver putty


【解决方案1】:

刚刚意识到我从未为此发布过答案。原来这是我无法解决的 USB 虚拟 COM 驱动程序的问题,但我能够解决这个问题。

注意:此问题和答案是Windows 平台特定的

Microsoft 提供了一个名为devcon.exe 的程序。它是 Windows 设备控制台,一种命令行版本的设备管理器。

最终,一旦我发现我可以移除设备并重新扫描(不拔掉它,所以有点“虚拟”拔掉它),我意识到我可以调用这个应用程序来为我移除特定的设备,然后如果我检测到断开连接,请重新扫描设备结构。所以这是我用来在转储串行数据之间完成此操作的python sn-p。可能不是有史以来最干净的代码,但这仅适用于快速而肮脏的日志记录脚本。希望这可以帮助你们中的一些人遇到同样的问题。

import serial
from subprocess import call
from time import sleep

def remove(ser):
    try:
        ser.close()
    except:
        print "Could not close port"
    call(["devcon.exe","remove","USB\VID_0D59&PID_0005*"])

def rescan():
    call(["devcon.exe","rescan"])
    sleep(30)

def send(ser, message):
    if ser.isOpen():
        try:
            ser.write(message)
        except serial.serialutil.SerialException:
            remove(ser)
            rescan()
            try:
                ser.open()
            except serial.serialutil.SerialException:
                try:
                    remove(ser)
                    rescan()
                except:
                    print 'Could not reconnect'
                    return False
            else:
                print 'Reconnected to %s' % (ser.portstr)
                ser.write(message)
                return True
        else:
            return True

重要提示:尝试向端口发送数据然后接收异常是判断设备已重新启动的唯一方法。这个驱动程序没有任何打开、关闭或检查连接的成功,所以这是我当时能想到的最好的解决方案。

另外,请注意rescan() 函数中的任意 30 秒延迟。这是为了让计算机有足够的时间来识别设备并找到合适的驱动程序。时间因系统和设备而异。

这段代码 sn-p 是 Python 2

最后,这可能是显而易见的,但是这个解决方案在同一目录下或PATH 下有devcon.exe

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-02
    • 2014-01-03
    • 2011-06-28
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    相关资源
    最近更新 更多