LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

multithreading with serial port

hi, i'm writing serial port listener(monitor) to my ARM microcontroler , using VISA to listen to com port  and print data in the textbox. but in the same time i want to use another GUI element and another functions.

here some code explanation:

here i'm open thread for task:

 

int CVICALLBACK SW_ON_OFF (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	char *value;
	int val;
	char params[32]; 
	switch (event)
	{
	   case EVENT_COMMIT:
	   GetCtrlVal (panel, PANEL_BINARYSWITCH, &val);
	   if(val == 1)
	   {
	     CmtScheduleThreadPoolFunction(DEFAULT_THREAD_POOL_HANDLE, ThreadFunction, NULL, &mainThreadID);
	     CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, mainThreadID, OPT_TP_PROCESS_EVENTS_WHILE_WAITING);          
	   }
	   else
	   {
		 CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, mainThreadID);
	        ResetTextBox (panelHandle, PANEL_TEXTBOX, "");
		ResetTextBox (panelHandle, PANEL_TEXTBOX_STATUS,"");
		executeCOMCommand("CLOSE", 1);
	    }
		break;
	}
	return 0;
}

 

double executeCOMCommand(char *commandString, int deviceNumber)
{

	ViSession defaultRM;  
	ViReal64 measurement = 0;
   	ViUInt32 num_bytes;
   	ViUInt32 RTCount;
	ViBoolean packetOK;
	int result, pp = 0;
	
	char dirName[4096], pathName[4096];
	
	int i, currentIndex, verbal = 0; //verbal - the returned measurement is in words
	int *deviceNumberTosend = malloc(sizeof(int));
	char adressString[1024], Databuf[1024], meas[1024], debugMSG[1024];
	 
	char dataToSend[4], err[4096], *packetdata;
	
	int status;
	
	char *command = strtok(commandString, " ");
	
	if(deviceNumber<0)
	{
		
		MessagePopup("Internal Error", "Window");
		return -1;
	}
	
	
		//Run coresponding thread
		*deviceNumberTosend = deviceNumber;

	
	
	//init anyway
	sprintf(adressString, "%s", UUTAddr);    
	viOpenDefaultRM (&defaultRM);
	result = viOpen(defaultRM,(ViRsrc)adressString, VI_NULL ,VI_NULL, &ssp);	
	if(result!=0)
		return -1;
	
	

	//init of ssp protocol
    viSetAttribute (ssp, VI_ATTR_TERMCHAR_EN, VI_TRUE);   //disable termination char
	viSetAttribute (ssp, VI_ATTR_TERMCHAR, 0x0A);
	viSetAttribute (ssp, VI_ATTR_ASRL_END_IN, VI_ASRL_END_LAST_BIT);
	
	viSetAttribute (ssp, VI_ATTR_ASRL_BAUD, 38400); 
	viSetAttribute (ssp, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_NONE);
	 
	viSetAttribute (ssp, VI_ATTR_TMO_VALUE, 25000); //TMO 15 seconds
	
	viFlush (ssp, VI_ASRL_IN_BUF_DISCARD);
	Sleep(1);
	
	if (!strcmp(command,"CLOSE")) //Reading     
	{
           viFlush (ssp, VI_WRITE_BUF);
	   viFlush (ssp, VI_READ_BUF);  
	   viClose(ssp);
	   return 0;
        }
	
        if (!strcmp(command,"LISTEN")) //Reading     
	{
	   status = viScanf(ssp, "%t", &Databuf);
	InsertTextBoxLine(panelHandle, PANEL_TEXTBOX, debugTextBoxLine++, Databuf); 
	//*************** Auto Scroll ***********************
	SetCtrlAttribute(panelHandle, PANEL_TEXTBOX, ATTR_FIRST_VISIBLE_LINE, debugTextBoxLine);
		//****************************************************
		return 0;
	} 
	   viFlush (ssp, VI_WRITE_BUF);
	   viFlush (ssp, VI_READ_BUF);  
	   viClose(ssp);
	   return 0;
}

 and thread function is: this function listen to com port and writes data to textbox

int CVICALLBACK ThreadFunction(void *functionData)
{
    
	while(!done)
	{
	    executeCOMCommand("LISTEN", 1);	
	}
	
	return 0;
	
}

 when i press quit button

int CVICALLBACK Quit (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			done = 1;
			
			executeCOMCommand("CLOSE", 1);
			
			QuitUserInterface (0);
			break;
	}
	return 0;
}

 the program hangs and give me general protection error , it's still check the THreadFunction and do executeCOMCommand("LISTEN", 1).

 

do i wrote it correctly for multithreading or i must to use something else. how i can quit program in write way.

thanks

0 Kudos
Message 1 of 5
(4,781 Views)

There are several points of your code that must be corrected for the application to work regularly. I'm not examining the VISA section here as it depends on external device characteristics which I don't know.

 

First of all, in SW_ON_OFF you must launch the thread and then exit the function. In your code the program is stuck in CmtWaitForThreadPoolFunctionCompletion, even if it processes events so the application is not hang. Nevertheless, this isn't a good approach: correct way is to launch the thread and then let it run by itself the same as the UI thread.

 

When you want to terminate the thread, set done = 1, next call CmtWaitForThreadPoolFunctionCompletion and only after it terminates you can dispose of system resourced with CmtReleaseThreadPoolFunctionID. The GPF error you are receiving is likely to happen since you are not guaranteed that the order of calls follows this pattern. This pattern is to be followed both on program end (Quit callback) and when you simply want to terminate interaction with the microcontroller (SW_ON_OFF function with binary switch set to off).

 

Last but not least, the main thread in such a pattern is the one that handles the user interface: is misleading using 'mainthreadID' as the variable name of a second thread. It seems a detail but it's not: correct names help you remember the theorical pattern that lies behind the code; in a few weeks you may be stuck in other projects and when you'll come back to this app again there is no guarantee that you'll remember the pattern (according to Murphy's law, you surely won't Smiley Wink )



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 5
(4,753 Views)

There also may be a problem with multithreads and using DLL,

If the thread is in the main program (example running a timer or heartbeat indicator) and the VISA communication is handled by a dll, any delay in response (long time to read data from instrument etc) within the dll causes the main program thread to appear to stop.

 

It may be I am doing something wrong, Hope someone else can comment on this

 

0 Kudos
Message 3 of 5
(4,747 Views)

 

thanks for an answers , i will check and write the code according to suggestions.

 

 

 

 

 

 

 

 

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

john_cvi_user

 

sorry but this is not a dll file 

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