2012-07-17 24 views
11

Tengo una aplicación Qt (Qt 4.8.1) que está haciendo algunas tareas del puerto serie de Windows. ¡Estoy descubriendo que ocasionalmente la llamada CreateFileA que hago para abrir el puerto serial tarda hasta 30 segundos en completarse! Obviamente estoy haciendo algo para desencadenar este extraño comportamiento, y quiero saber qué es lo que podría estar haciendo para causar esto.¿Qué puede hacer que las llamadas a CreateFile en un puerto serie sean extremadamente lentas?

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 es un mango, y portDevice es un std :: string y contiene "COM5".

Esta llamada se desencadena mediante un botón presionar en el hilo principal de mi aplicación. En el momento en que sucede, la aplicación tiene como máximo otro hilo, pero esos hilos (si los hay) están inactivos.

Lo único que sucede en el sistema es una máquina virtual que ejecuta Linux, pero el sistema es de cuatro núcleos y 3 de los núcleos están tan inactivos como se ve en una caja de Windows, con solo uno haciendo algo con la VM

Los puertos serie están en una caja serial USB de 8 puertos, ¿podría estar relacionado?

¿Está relacionado esto con el IO superpuesto de alguna manera?

En respuesta a los comentarios:

puerto no está abierto por otra aplicación. El puerto se abrió anteriormente mediante una invocación previa de esta aplicación, que se cerró correctamente, y el puerto se cerró con 'CloseHandle'.

No he podido determinar ninguna correlación entre tomar 30 segundos y no - a veces comienzo la aplicación, hago clic en el botón y vamos a las carreras, a veces demora hasta 30 segundos.

La VM está interceptando algunos otros dispositivos USB en la misma caja de serie.

Aparte del cuadro de serie (con los 4 puertos de sondeo de VM que buscan dispositivos), el bus USB está descargado.

No he visto el comportamiento en otras aplicaciones. Intentaré cambiar a un puerto integrado (COM1 en la placa base) para ver si tiene algún efecto.

Se me acaba de ocurrir una idea: ¿puede la forma del direccionamiento del puerto tener algo que ver con eso? Otras aplicaciones similares en las que trabajo utilizan la biblioteca qestserialport, que abre puertos usando la notación '\\. \ COM #'. ¿Hay alguna forma en que la notación utilizada podría afectar el tiempo?

El dispositivo serie USB dice 'VScom' y normalmente se abre de inmediato (< 10 milisegundos para la llamada CreateFile). Es solo un problema ocasional donde las cosas se llenan, y tengo otros programas que NUNCA parecen exhibir este comportamiento.

El dispositivo con el que estoy hablando es un monitor médico que utiliza el protocolo IEEE 11073. De todos modos, tengo la conexión al dispositivo funcionando bien, SOLO es el puerto serie abierto lo que es problemático. ¿Podría el estado de las líneas de control en serie en tiempo abierto tener algo que ver con esto? El dispositivo en el otro extremo está sondeando sus puertos buscando varias cosas con las que hablar, así que no tengo idea de cómo son las líneas seriales en el momento exacto en que las cosas van mal.

+0

¿El puerto está abierto por otra aplicación? Tal vez está esperando la liberación de un mutex o bloqueo. –

+0

La llamada 'CreateFileA()' que muestra se ve bien. ¿Bajo qué circunstancias toma 30s? Inmediatamente después de conectar su dispositivo USB? ¿Has intentado obtener este comportamiento en otras aplicaciones? ¿Has intentado obtener este comportamiento con otro puerto COM? ¿Qué tan ocupado está tu bus USB? ¿Tienes el VM interceptando dispositivos USB? – tinman

+1

Los puertos serie se abren bastante rápido en mi experiencia, incluso con muchos puertos COM USB conectados. ¿De qué marca son los puertos serie USB que estás usando? –

Respuesta

1

Bien, se comprende el problema, si no se resuelve. Estaba jugando con un dispositivo en serie diferente y el problema comenzó a manifestarse con más frecuencia.

El problema parece ser que cuando la máquina virtual tiene el control de algunos de los puertos serie, los controladores se vuelven intermitentemente lentos para abrir los puertos disponibles.

Mi programa de prueba se abre y luego cierra el puerto 1000 veces, cronometrando la llamada abierta. NO establece los parámetros del puerto serie de ninguna manera. Antes de ejecutar el programa de prueba, estaba haciendo un trabajo real con un dispositivo que usa la velocidad en baudios 460800.

Cuando la VM está en posesión de 4 de los puertos, a continuación, se abre en los 4 puertos restantes a veces (20- 30 veces de cada 1000 intentos) tome de 20 a 30 segundos para completar. Cuando la VM no se está ejecutando, las aperturas ocurren rápidamente en los 1000 intentos. Con la VM ejecutándose, pero no hay puertos seriales USB en su posesión, las aperturas ocurrieron rápidamente en los 1000 intentos.

Dado que la VM es una herramienta de desarrollo, que no forma parte de nuestro escenario de implementación previsto, puedo aceptar este problema.

Curiosamente, este efecto parece depender de la velocidad de transmisión en baudios en la que se utilizó el puerto por última vez. Antes de mis consultas iniciales, había estado operando a 9600 baudios y menos y no recuerdo haber visto el problema. Cuando le pregunté por primera vez, estaba trabajando con un dispositivo que estaba en 115000 baudios, y estaba teniendo el problema intermitentemente. Con el dispositivo más nuevo a 460800 baud, recibo el problema con la frecuencia suficiente para poder cazar el problema. No tengo idea por qué, pero ahí está.

0

Las líneas de control serie que interactúan con un problema de controlador de dispositivo es una causa probable.

¿Tiene las señales de control correctamente conectadas?

Si no, conecte RTS a CTS y conecte CD, DTR y DSR. En un DB25, esto significa conectar los pines 4 y 5 y los pines de conexión 6, 8 y 20. En un DB9, conecte los pines 7 y 8 y conecte los pines 1, 4 y 6.

Si esto soluciona el problema, debe busque la configuración del controlador para ignorar las señales de control en abierto.

Cuestiones relacionadas