什么可以导致串口上的CreateFile调用非常慢?

时间:2012-07-17 15:33:22

标签: c++ windows serial-port

我有一个Qt应用程序(Qt 4.8.1)正在做一些Windows串口任务。我发现有时我打开串口的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的虚拟机,但系统是四核的,其中3个核心就像你在Windows机器上看到的那样几乎空闲,只有一个在做任何事情VM。

串口是8端口USB串口盒,可能是相关的吗?

这是否以某种方式与重叠IO相关?

回应评论:

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

我无法确定它与30秒之间的任何相关性 - 有时我启动应用程序,单击按钮我们即将离开比赛,有时需要30秒。

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

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

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

我想到了一个想法:端口寻址的形式可以与它有关吗?我工作的其他类似应用程序使用qestserialport库,它使用'\\。\ COM#'表示法打开端口。是否有某种方式使用的符号会影响时间?

USB串行设备在其上显示“VScom”,通常它立即打开(对于CreateFile调用,<10毫秒)。这只是一个偶然的事情,事情变得充实,我还有其他程序,似乎从来没有表现出这种行为。

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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

有趣的是,这种影响似乎取决于端口上次使用的波特率。在我初次询问之前,我一直在以9600波特及以下的速度运行,并且不记得曾经看到过这个问题。当我第一次提出这个问题时,我正在处理一个115000波特的设备,并且间歇性地遇到了这个问题。最新的设备在460800波特,我经常遇到问题,能够解决问题。不知道为什么,但确实如此。

答案 1 :(得分:0)

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

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

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

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