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

问题描述:

我有一个Qt应用程序(Qt 4.8.1),它执行一些Windows串行端口任务。我偶尔发现打开串口所需的CreateFileA调用需要30秒才能完成!很明显,我正在做一些事情来触发这种奇怪的行为,我想知道我可能会做什么来实现这一点。什么会导致串口上的CreateFile调用非常慢?

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是一个句柄,portDevice是一个std :: string并包含“COM5”。

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

系统中唯一主要的事情是运行Linux的虚拟机,但系统是一个四核,而且其中的三个核心几乎像在Windows上看到的那样空闲,只有一个处理器执行任何操作与VM。

串口位于一个8端口的USB串行盒上,可以关联吗?

这与某些方面的重叠IO有关吗?

在回应评论:

端口没有被其他应用程序打开。先前调用此应用程序时,端口先前已打开,该应用程序已正确关闭,并且端口用“CloseHandle”关闭。

我还没有能够确定它之间的任何相关性需要30秒,而不是 - 有时我启动应用程序,点击按钮,我们对比赛,有时需要长达30秒。

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

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

我还没有看到其他应用程序的行为。我会尝试切换到内置端口(主板上的COM1),看看它是否有效。

我想起了一个想法:端口寻址的形式可以与它有什么关系吗?我使用的其他类似应用程序使用qestserialport库,该库使用'\\。\ COM#'表示法打开端口。有没有某种方法可以影响计时?

USB串行设备上有'VScom',通常它立即打开(<为CreateFile调用10毫秒)。这只是一个偶尔的问题,事情会被堵塞,而且我还有其他一些永远不会出现这种行为的程序。

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

+0

端口是否被另一个应用程序打开?也许它正在等待互斥锁或锁释放。 – 2012-07-17 15:38:07

+0

您展示的'CreateFileA()'调用看起来确定。在什么情况下需要30秒?在插入USB设备后立即进行?你有没有试图在其他应用程序中获得这种行为?你有没有试图用另一个COM端口来获得这种行为?你的USB总线有多忙?你有VM拦截USB设备吗? – tinman 2012-07-17 15:40:06

+1

即使连接了很多USB COM端口,串行端口也能以我的经验开启得相当快。您使用的是什么品牌的USB串行端口? – 2012-07-17 16:59:18

好的,问题可以理解,如果解决不了的话。我正在玩一个不同的串口设备,问题开始显得更加频繁。

问题似乎是,当虚拟机控制某些串行端口时,驱动程序变得间歇性地慢以打开可用端口。

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

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

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

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

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

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

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

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