11

我有一个正在执行一些 Windows 串行端口任务的 Qt 应用程序(Qt 4.8.1)。我发现有时我为打开串行端口所做的 CreateFileA 调用最多需要 30 秒才能完成!显然我正在做一些事情来触发这种奇怪的行为,我想知道我可能会做什么来导致这种情况。

m_portHand = CreateFileA( portDevice.c_str(),
                          GENERIC_READ | GENERIC_WRITE,
                          0,      //  must be opened with exclusive-access
                          NULL,   //  default security attributes
                          OPEN_EXISTING, //  must use OPEN_EXISTING
                          FILE_FLAG_OVERLAPPED,      //  overlapped I/O
                          NULL ); //  hTemplate must be NULL for comm devices

m_portHand 是 HANDLE,portDevice 是 std::string 并包含“COM5”。

此调用由我的应用程序主线程中的按钮按下触发。发生这种情况时,应用程序最多有一个其他线程,但这些线程(如果有的话)是空闲的。

系统中唯一发生的主要事情是运行 Linux 的 VM,但该系统是四核的,其中 3 个内核与您在 Windows 机器上看到的一样接近空闲,只有一个内核在 VM 上做任何事情。

串口在8口USB串口盒上,有关系吗?

这在某种程度上与重叠的 IO 相关吗?

回应评论:

端口未被其他应用程序打开。之前调用此应用程序之前已打开端口,该应用程序已正确关闭,并且端口已使用“CloseHandle”关闭。

我无法确定它需要 30 秒与否之间的任何相关性 - 有时我启动应用程序,单击按钮然后我们就开始比赛,有时需要长达 30 秒。

虚拟机正在拦截同一串行盒上的一些其他 USB 设备。

除了串行盒(VM 轮询 4 个端口来寻找设备)之外,USB 总线被卸载。

我没有在其他应用程序中看到这种行为。我将尝试切换到内置端口(主板上的 COM1),看看是否有任何影响。

我突然想到一个想法:端口寻址的形式与它有什么关系吗?我使用的其他类似应用程序使用 qestserialport 库,它使用 '\\.\COM#' 符号打开端口。使用的符号是否有某种方式会影响时间?

USB 串行设备上显示“VScom”,通常它会立即打开(CreateFile 调用小于 10 毫秒)。这只是偶尔会出现问题,而且我还有其他程序似乎从未表现出这种行为。

我正在与之交谈的设备是使用 IEEE 11073 协议的医疗监视器。无论如何,我与设备的连接工作正常,只有串行端口打开才有问题。打开时串行控制线的状态是否与此有关?另一端的设备正在轮询它的端口,以寻找各种可以与之交谈的东西,所以我不知道在出现问题的确切时刻串行线是什么样子的。

4

2 回答 2

1

好的,如果没有解决,问题就明白了。我正在使用不同的串行设备,问题开始更加频繁地出现。

问题似乎是,当 VM 控制某些串行端口时,驱动程序会间歇性地缓慢打开可用端口。

我的测试程序打开然后关闭端口 1000 次,定时打开调用。它不会以任何方式设置串口参数。在运行测试程序之前,我正在使用波特率 460800 的设备进行实际工作。

当虚拟机拥有 4 个端口时,在其余 4 个端口上打开有时(1000 次尝试中的 20-30 次)需要 20-30 秒才能完成。当 VM 未运行时,所有 1000 次尝试都会快速打开。在 VM 运行但没有 USB 串行端口的情况下,所有 1000 次尝试都很快打开。

由于 VM 是一个开发工具,而不是我们预期的部署场景的一部分,我可以忍受这个问题。

有趣的是,这种效果似乎取决于端口上次使用的波特率。在我最初的询问之前,我一直在 9600 波特及以下运行,并且不记得曾经看到过这个问题。当我第一次问这个问题时,我正在使用一个 115000 波特的设备,并且间歇性地遇到问题。使用 460800 波特的最新设备,我经常遇到问题,足以解决问题。不知道为什么,但它就在那里。

于 2012-08-21T15:17:51.820 回答
0

与设备驱动程序问题交互的串行控制线是一个可能的原因。

您是否正确连接了控制信号?

如果没有,请将 RTS 连接到 CTS 并连接 CD、DTR 和 DSR。在 DB25 上,这意味着连接引脚 4 和 5 以及连接引脚 6、8 和 20。在 DB9 上,连接引脚 7 和 8 以及连接引脚 1、4 和 6。

如果这解决了问题,您应该寻找驱动程序设置以忽略打开时的控制信号。

于 2012-07-24T08:42:22.587 回答