LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Speed of "InstallComCallback()"

My problem is to aquire datas of two old RS422-interface (each: exact 500kBaud, every 20ms 150Words; the HW is modified to
ensure the 500kBaud instead of 1MBaud).
There is a synchronisation word "EB90" at the beginning only. The other datas could have every value between 0000 and FFFF.
The program works well with one interface but if I try to aquire the second one, one of aquirement stutters or stop the process.
Sometimes both threads run, but then some data frames get lost.
How can I make the progam faster and more stable.
My program:
main()
{
 // normal stuff
   
    iEventMask = LWRS_RXFLAG;
    iSynchByte1 = iSynchByte2 = 0xEB;
    iDataLength1 = iDataLength2 = 300;
    iPort1 = 3,
    iPort2 = 4;
    iReadTime = TSQ_INFINITE_TIMEOUT;
    iWriteTime = TSQ_INFINITE_TIMEOUT;
 
    OpenComConfig (iPort1, "", 921600, 2, 8, 1, 300, 30);  //921600 = 500000 because HW is modified
    OpenComConfig (iPort2, "", 921600, 2, 8, 1, 300, 30);
    FlushInQ (iPort1);
    FlushOutQ (iPort1);
    FlushInQ (iPort2);
    FlushOutQ (iPort2);
 
    InstallComCallback (iPort1, iEventMask, iDataLength1, iSynchByte1, Event_Char_Detect_Func1, 0);
    InstallComCallback (iPort2, iEventMask, iDataLength2, iSynchByte2, Event_Char_Detect_Func2, 0);
    CmtScheduleThreadPoolFunctionAdv (DEFAULT_THREAD_POOL_HANDLE, DataAcqFunction1,
                                      NULL, THREAD_PRIORITY_NORMAL, NULL,
                                      EVENT_TP_THREAD_FUNCTION_BEGIN, NULL,
                                      (iThreadFctID[0] = CmtGetCurrentThreadID ()), NULL);
          
    CmtScheduleThreadPoolFunctionAdv (DEFAULT_THREAD_POOL_HANDLE, DataAcqFunction2,
                                      NULL, THREAD_PRIORITY_NORMAL, NULL,
                                      EVENT_TP_THREAD_FUNCTION_BEGIN, NULL,
                                      (iThreadFctID[1] = CmtGetCurrentThreadID ()), NULL);
 // normal stuff
}
 
int CVICALLBACK StartData (int panel, int control, int event, void *callbackData,
                            int eventData1, int eventData2)
{                 
    switch (event)
        {
        case EVENT_COMMIT:
            iTSQ1 = CmtNewTSQ (iDataLength1, sizeof(char), OPT_TSQ_AUTO_FLUSH_EXACT, &hAcquire1);
            iTSQ1 = CmtInstallTSQCallback (hAcquire1, EVENT_TSQ_ITEMS_IN_QUEUE, iDataLength1,
                                           ProcessData1, NULL, CmtGetCurrentThreadID(), &iAcqDataID1);
            iTSQ2 = CmtNewTSQ (iDataLength2, sizeof(char), OPT_TSQ_AUTO_FLUSH_EXACT, &hAcquire2);
            iTSQ2 = CmtInstallTSQCallback (hAcquire2, EVENT_TSQ_ITEMS_IN_QUEUE, iDataLength2,
                                           ProcessData2, NULL, CmtGetCurrentThreadID(), &iAcqDataID2);
          
 bStart = 1;     //Starten
            break;
        }
    return 0;
}
 
void CVICALLBACK ProcessData1 (int Handle, unsigned int event, int value, void *callbackData)
{
 CmtReadTSQData (Handle, ucReadBuffer1, iDataLength1, iReadTime, 0);
 CmtFlushTSQ (Handle, TSQ_FLUSH_ALL, NULL);
 //analyse datas
 
 ProcessSystemEvents();
}
 
void CVICALLBACK ProcessData2 (int Handle, unsigned int event, int value, void *callbackData)
{
 CmtReadTSQData (Handle, ucReadBuffer2, iDataLength2, iReadTime, 0);
 CmtFlushTSQ (Handle, TSQ_FLUSH_ALL, NULL);
 //analyse datas
 
 ProcessSystemEvents();
}
 
int CVICALLBACK DataAcqFunction1 (void *fctData)
{
 if (bStart) {
  while (iSynch1 == 0)
   iSynch1 = find_Synch_1(iPort1);  //if lose the synch-word EB90
  }
  
 return 0;
}
 
int CVICALLBACK DataAcqFunction2 (void *fctData)
{
 if (bStart) {
  while (iSynch2 == 0)
   iSynch2 = find_Synch_2(iPort2);  //if lose the synch-word EB90
  }
 return 0;
}
 
void CVICALLBACK Event_Char_Detect_Func1 (int portNo, int eventMask, void *callbackData)
{
 iTemp12 = ComRd (iPort1, ucWriteBuffer1, iDataLength1);
 FlushInQ (iPort1);
 if ((ucWriteBuffer1[0] << 😎 + ucWriteBuffer1[1] == 0xEB90) {
  if (bStart)
   CmtWriteTSQData (hAcquire1, ucWriteBuffer1, iDataLength1, iWriteTime, &iTemp12);
  //make some stuff to control
                }
 else {
  while (iSynch1 == 0)
   iSynch1 = find_Synch_1(iPort1);  //if lose the synch-word EB90
  }
 ProcessSystemEvents();
 return;
}
  
void CVICALLBACK Event_Char_Detect_Func2 (int portNo, int eventMask, void *callbackData)
{
 
 iTemp22 = ComRd (iPort2, ucWriteBuffer2, iDataLength2);
 FlushInQ (iPort2);
 if ((ucWriteBuffer2[0] << 😎 + ucWriteBuffer2[1] == 0xEB90) {
  if (bStart)
   CmtWriteTSQData (hAcquire2, ucWriteBuffer2, iDataLength2, iWriteTime, &iTemp22);
                //make some stuff to control
  }
 else {
  while (iSynch2 == 0)
   iSynch2 = find_Synch_2(iPort2);  //if lose the synch-word EB90
  }
 ProcessSystemEvents();
 return;
}
  
// some other CVICALLBACKs to stop etc.
 
int find_synch_1()
int find_synch_2()
0 Kudos
Message 1 of 2
(3,395 Views)
The problem seems to be that one acquisition thread can hold the CPU too long, causing the other acquisition to stall or lose data.  Ideally, to avoid losing data, your serial communication should be set up to use some sort of handshaking.  Hardware handshaking (using the flow control lines) is usually preferable to software handshaking, but either one requires that the connected device be configured to use that handshaking scheme.  Using handshaking will prevent data loss by pausing the data transfer when the receiving end's input queue gets full.  When data is processed and the queue is no longer full, the data transfer is resumed.

I would also suggest you take a look at the find_synch_x functions and determine if there is a logical place for these functions to call Sleep(). Your thread functions just call find_synch_x in a tight loop, so you should make sure that find_synch_x does not do any busy waiting.  Also, since performance seems to be a factor, try to avoid doing any unnecessary, time-consuming work (file IO, etc) in these functions.

Lastly, I would suggest you pass an input queue length of -1 to OpenComConfig.  If you are doing any writing to the devices, disabling the output queue in this way might help remove some inefficiencies.

Mert A.
National Instruments
0 Kudos
Message 2 of 2
(3,384 Views)