From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiport comm. driver & Testand model

Hello, I have a question regarding a test application that must be run in Testand 3.0, I have to test 6 UUT, each is connected on a serial port of a NI PCI232/8 multiport card (Card driver is NI Serial 1.7).
To start I created a DLL (with CVI 7.0), that manages the communication functions like Open & Close Port, sending commands and receiving answers to / from UUT etc. I made a sequence file that call functions inside the DLL, using Sequential Model and tested the application on one UUT, everything seems to be OK.
Now I would like to increase the number of UUT's that I controll, and to use Parallel Model. I am not very familiar with this model and my question is if the DLL that I created to manage the communication functions, must be changed or it can be used and it is. When creating the DLL I didn't employ any thread safe functions or thread safe variable access methods. Will Testand take care of this issues when using the parallel model ?
 
Below is a part of the code that implements main functions in the communication DLL.
 
Any comments or examples about using serial port communication in a multithreaded application manged by Testand would be greatly appreciated.
 
Regards

int  InitUIForDLL (void);
void DiscardUIObjectsForDLL (void);

int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
 switch (fdwReason)
  {
  case DLL_PROCESS_ATTACH:
   if (InitCVIRTE (hinstDLL, 0, 0) == 0) 
    return 0; /* out of memory */
   break;
  case DLL_PROCESS_DETACH:
   if (!CVIRTEHasBeenDetached())  /* Do not call CVI functions if cvirte.dll has already been detached. */
    {
    CloseCVIRTE (); 
    }
   break;
  }
 return 1;
}
int __stdcall DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
 /* Included for compatibility with Borland */
  return DllMain (hinstDLL, fdwReason, lpvReserved);
}
int _VI_FUNC OpenConfigPort (int COMPort, long baudRate, char parity,char deviceName[], int databits, int stopBits,int inputQueueSize, int outputQueueSize)
{
int retVal;
  OpenComConfig (COMPort,"", baudRate, parity, databits, stopBits, inputQueueSize, outputQueueSize);
  if ((retVal = ReturnRS232Err ())!=0) return(-1);
  comPort = COMPort;
  FlushInQ(comPort);
  FlushOutQ(comPort);
  return(0);
   
}
int _VI_FUNC ClosePort (int COMPort)
{
     CloseCom(COMPort);
     FWT_Connect=0;
     return(0);
}
int _VI_FUNC sendcmdNoParam (int comPort, int *errorCode, char classID, char CommandID)
{
unsigned char Command[10];
char  InBuffer[16384];
char  InQ,OutQ;
unsigned char i;
unsigned char  ChkSum;

  FlushInQ(comPort);
  memset (InBuffer, 0, strlen(InBuffer));

/*
  Command[0] =
  Command[2] = ClassId;
  Command[3] = CommandID;
  ...
 
  Command[5] = ChkSum;
*/
  OutQ = ComWrt (comPort, Command, 6);
  while((OutQ = GetOutQLen(comPort))!=0);
  InQ = GetInQLen (comPort);
  ComRd(comPort,InBuffer,InQ);
  ChkSum=0;
  for(i=0;i<strlen(InBuffer);i++) ChkSum+=InBuffer[i];
  if(ChkSum) return(-1);     //CheckSum Fail
/*
  ...

*/
  return(0);
}
0 Kudos
Message 1 of 2
(2,600 Views)
Hi miniMe,

The parallel process model simply launches a separate execution (thread) for each test socket.  When you use DLLs, global variables and structures are shared between all threads that call into the DLL so all calls by TestStand share the same data. On the other hand, variables or structures you declare inside the scope of a particular DLL function are not shared, so these items would be unique to each TestStand call. In your case, it does not appear that you have any global variables so running your sequence with the parallel process model should not be a problem as long as you configure the functions' parameters correctly.  Since using the parallel model means you will have multiple threads running simultaneously, you will need to programmatically determine which parameters to send to the function (i.e. COMPort) so that you're not trying to communicate with the same hardware in every thread.  This could most easily be achieved by utilizing the RunState.TestSockets.MyIndex property which provides the zero-based index of the test socket.

Have a great day,

Ecleamus Ricks, Jr
National Instruments
Applications Engineer
0 Kudos
Message 2 of 2
(2,570 Views)