LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

CloseCom() causing program freeze

Hi everyone,

I have a problem with the CloseCom() function, which sometimes freezes my application when tries to close a COM port. All I can do is terminate the execution of the application through the STOP button, but this does not release the COM port, and the application window does not close. In turn, I am not able to use that serial port again without rebooting the machine.

 

I checked this in debug mode and the program flow gets stuck while executing the CloseCom() function, thus I don't know what is the real cause as I don't know how to check deeper. This happens in both debug and release configurations, for both 32 and 64 bits program versions. This happens only with FTDI cables, in particular we use the TTL-232R-5V-AJhttp://www.ftdichip.com/Products/Cables/USBTTLSerial.htm ) to communicate with external hardware. I can exclude it is a problem from a specific cable as I tried several ones, and all fail in the same way.

This is the code I use for closing the COM port:

 

int CVICALLBACK QuitCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
		{
		case EVENT_COMMIT:
		  if(n_com)
if (hw_type) ComWrtByte (n_com, 0x41); else { ComWrtByte (n_com, COD_SCHEDA); ComWrtByte (n_com, COD_COMMAND_STOP ); ComWrtByte (n_com, COD_SCHEDA); } CloseCom (n_com); QuitUserInterface (0);
} break; } return 0; }

 

By looking at the following post:

http://forums.ni.com/t5/LabWindows-CVI/CloseCom-causing-general-protection-fault/m-p/608518/highligh...

it seems it could be a General Protection Fault problem (even if I don't get any error, the program just freezes) as I send bytes just before closing the COM port. Thus I tried to modify the code as follows:

 

int CVICALLBACK QuitCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
		{
		case EVENT_COMMIT:
		  if(n_com)
                    if (hw_type) ComWrtByte (n_com, 0x41);
		    else {
			ComWrtByte (n_com, COD_SCHEDA);	
			ComWrtByte (n_com, COD_COMMAND_STOP );	
			ComWrtByte (n_com, COD_SCHEDA);
		    }
                    FlushInQ(n_com);
                    FlushOutQ(n_com);
                    Delay(0.1);
		    CloseCom (n_com);
		
		    QuitUserInterface (0);
                  }
		  break;	
		  }
	return 0;
}

----- OR -----

int CVICALLBACK QuitCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
		{
		case EVENT_COMMIT:
		  if(n_com)
                    if (hw_type) ComWrtByte (n_com, 0x41);
		    else {
			ComWrtByte (n_com, COD_SCHEDA);	
			ComWrtByte (n_com, COD_COMMAND_STOP );	
			ComWrtByte (n_com, COD_SCHEDA);
		    }
                    
                    while(GetOutQLen(n_com)>0){};
		    CloseCom (n_com);
		
		    QuitUserInterface (0);
                  }
		  break;	
		  }
	return 0;
}

with no success. As I said, the problem seems to show up only with that cable type (other devices attached through their own serial/USB cables never fail). However, the same cable does not fail when used in other environments, such as MATLAB.

 

I am using LabWindows/CVI 2010 version 10.0.1 (434). I would like to avoid to update the system as this usually is a time consuming operation.

Please let me know if you need any other information

Thank you in advance

 

0 Kudos
Message 1 of 5
(5,093 Views)

Try monitoring the return values of the Comms library functions.  See if any of them are returning errors.  Also, their library is setting a global called rs232err.  In my own experience, doing some amount of error handling on library functions helps a lot in debugging.

 

From the help...

 

RS-232 Error Codes
The following table lists the error codeserror codes, defined constants, and error messages associated with functions in the the LabWindows/CVI RS-232 Library.

 

Use the GetRS232ErrorString function to convert the error code, returned by the ReturnRS232Err function, into meaningful error messages.

 

You can call ReturnRS232Err to obtain the error code, either zero or a negative value, from the most recent function call in the current thread. If the most recent call was successful but an asynchronous write operation failed, ReturnRS232Err returns the error code from the asynchronous operation. To ensure that a particular function call succeeded, use the return value from that function call.

 

The rs232err global variable is the error code from the most recent function call or failed asynchronous write operation in your application, regardless of thread. In multithreaded applications, use ReturnRS232Err instead of rs232err.

Error codes are defined in the cvi\include\rs232.h file.

 

0 Kudos
Message 2 of 5
(5,083 Views)

Dear ElectroLund,

thanks for your message. Shouldn't such errors come eventually up in debug mode? I don't get any of them. However, I'll try monitoring every single write and read operations on COM ports and let you know.

0 Kudos
Message 3 of 5
(5,066 Views)

Three Ideas:

 

First:

With our application I observed that "CloseCom()" causes an USB connection termination.

We have a USB device which creates an virtual COM-port and by a random type of "CloseCom" I get that USB-communication termination.

With a newer driver I face that problem less.

--> Maybe the driver itself is the problem. Do you use the most actual COM-port driver?

 

Second:

If possible use a "real" COM-port.

If not possible use a "better" virtual COM-port, e.g. "http://www.vscom.de/commercial-line.htm". (Or from some other company with an "industrial product line".)

Because the "cheap" virtual COM's are not that reliable as these which are developed for "industrial purposes".

 

Third:

I faced some problems with the COM-communication since NI made it's driver MS-compliant. Especially if you have a long lasting "ping-pong"-communication between the PC and the COM-device. I developed a "new" function instead of delivered "ComWrtByte" with that function I alwas wait as long as "GetOutQLen(...)>0". In that function I have also programmed a timeout time (number of wait-loops for "GetOutQLen(...)>0").

 

I had massive problems as long as I used only the lib-function "ComWrtByte" for my "ping-pong"-communication. After introducing my own "WriteByteAndWaitOutQEmptyImpr"-function my programs have no problems with unforseen corruption of the COM-communication. They run as stable as in former times (LabWindows 5.1). With error-handling such a improved "ComWrtByte"-function is more complex than only a few program lines.

 

Especially with these virtual COM's you should check every communication step that the Output-Queue is empty, before you continue. In comparison to the "real"-COM-ports these virtual ones are very slowly. My experiences are that the "real" ones have reaction times in milli-seconds and the virtual ones have reaction times about some houndred milli-seconds! So you can easily be in trouble by that fact.

 

I hope one or some of these ideas will help.

 

0 Kudos
Message 4 of 5
(5,062 Views)

I had this problem and found it was because my timeouts were set to inifinity.  Which was not intended to be so but got set somehow by specifying "0.0001" for timout value.

 

SetComTime(s_CurrentComPort, 0.0001);

 

CVI specifies this field is a double, so this value should be valid, however it accepted it as "0" and set the timeouts to infinity.  This resulted in my ComRd() function hanging in my receive thread.  And when I go to close the port it also hangs there.  Once I corrected this the issue was gone.

 

I find throughout CVI the minimum time for pretty much everything is 0.001 (1ms).  They charge enough for this software you would think this would be specified in documentation vs us wasting time figuring it out for ourselves.  So NI if you could please add this to your documentation that'd be great.  All though I think it may also be dependent on the machine/OS you are working with.  You could still note it however.

0 Kudos
Message 5 of 5
(3,273 Views)