From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

ReadDigital32 writing out of bounds of array and freezing computer?

Hello all, I am a graduate student will little programming experience trying to modify our lab's code to use a new detector which interfaces to the computer with a NI PCI-6534 card.  The code is written in Borland C++ builder 6 and uses the ANSI C library support provided with the NIDAQmx drivers. 

I have been able to get data, but have run into problems when trying to run experiments and retrieve many scans.  After taking so many scans, the computer will freeze up completely, as in you must hold down the power button for a hard reset.  How many scans before this occurs is tied to how many accumulations are requested, higher accumulations will freeze the computer in fewer measurements.  It seems to be somehow related to the NIDAQmx ReadDigital32 function writing outside of the allocated bounds of the buffer array, as the computer only freezes when I include this step while executing the program, and purposefully making the buffer much larger, say 100x, only delays the freezing.  I

 

This is the our code that reads the data, I only copied enough of the GetScanData() function to show where it puts the data from the GetRawData() function:

 

bool MultiChDetector::getRawData(uInt32 *dbuffer, int nRawScans) {

   if (nRawScans>5000)   {
   last_error = "Bad number of accumulations" ;
   return false;
   }
    MeasurementTask acq_task;
    //One 32bit channel with 16 bit upper and lower words
    DAQ_ERR( DAQmxCreateDIChan(acq_task.h(), DAQ_DEVICE"/port0_32", "Port32", DAQmx_Val_ChanForAllLines) );

    DAQ_ERR( DAQmxCfgSampClkTiming(
        acq_task.h(),
        NULL, //internal clock
        10e6, //10 MHz
        DAQmx_Val_Rising,
        DAQmx_Val_FiniteSamps, //DAQmx_Val_ContSamps
        MCHD_CH_AMT*nRawScans) );

    DAQ_ERR( DAQmxCfgBurstHandshakingTimingExportClock(
        acq_task.h(),
        DAQmx_Val_FiniteSamps, //DAQmx_Val_ContSamps
        MCHD_CH_AMT*nRawScans,
        10e6, //10 MHz
        "/"DAQ_DEVICE"/PFI4",
        DAQmx_Val_ActiveHigh, //the polarity for exported sample clock: active high or active low
        DAQmx_Val_High, //whether the task pauses while the signal is high or low
        DAQmx_Val_ActiveHigh) ); //the polarity for the Ready for Transfer event (System Ready)

    double timeout_sec = 10.0 + nRawScans/1e3; //sec timeout, 1e3 = 1 kHz

    bool interactive_wait = false;

 if(interactive_wait) {
    DAQ_ERR( DAQmxStartTask(acq_task.h()) );   // don't forget to Stop Task

   
    int time0=GetTickCount();
    unsigned long isDone=false;
    do {
        Application->ProcessMessages();

        DAQ_ERR( DAQmxIsTaskDone(acq_task.h(), &isDone) );

        if(isDone) {
            break;
        }
        if( (GetTickCount()-time0)> int(1000*timeout_sec) ) {
            Application->MessageBox("Error", "Multi-channel data not ready in time", MB_OK);
            break;
        }
    }
    while(!isDone);

  }

    int32 nRead = 0;
 
   DAQ_ERR( DAQmxReadDigitalU32(
        acq_task.h(),
        MCHD_CH_AMT*nRawScans,
        timeout_sec,
        DAQmx_Val_GroupByChannel,
        dbuffer,
        MCHD_CH_AMT*nRawScans,
        &nRead,
        NULL) );

    if (nRead != MCHD_CH_AMT*nRawScans) {
        last_error = "Less amount of data was read";
        return false;
    }
    if(interactive_wait) {
        DAQ_ERR( DAQmxStopTask(acq_task.h()) );
    }
    /*thr_buffer = buffer;
    thr_counter = nRawScans*MCHD_CH_AMT;
    thr_request_scan = true;
    while (thr_counter);
    return true;
}
.................................
bool MultiChDetector::getScanDataS(float *destBuffer, ScanType scanType, bool subtractBackground, bool divideReference) {
    bool requestOK;
    bool* bad_points;
    bad_points = new bool[MCHD_CH_AMT];
       int het_extra_pts = 0;
    if (scanType==SetPhase12){
    het_extra_pts=3;
    }


    double *raw_data = (double *)calloc(MCHD_CH_AMT, sizeof(double));
    double *norm_data = (double *)calloc(64, sizeof(double));
    uInt16 *buffer = (uInt16 *)calloc(MCHD_CH_AMT*(nScans+het_extra_pts), sizeof(uInt16));
    uInt32 *dual_buffer = (uInt32*)calloc(MCHD_CH_AMT*(nScans+het_extra_pts+200), sizeof(uInt32));  //Furman
    //uInt16 *externalch = (uInt16*)calloc(16), sizeof(uInt16));
    try {
        if (!getRawData(dual_buffer, nScans+het_extra_pts)) {
            return false;
        }

    for(int d=0; d<nScans*MCHD_CH_AMT; d+=128){ //Discarding extra data from 16 external inputs and unused channels (up to 256) and skip first channel
        for (int a=0; a<64; a+=16){             //Separating the upper and lower words of the 32 bit samples dbuffer[0]->buffer[16,0], etc.
                for (int b=0; b<8; b++){        //FIFO reads out even then odd channels 0246...1357
                        buffer[(2*a)+(2*b)+d]=(uInt16)dual_buffer[a+b+(d+1)];
                        buffer[(2*a+16)+(2*b)+d]=(uInt16)(dual_buffer[a+b+(d+1)]>>16);
                        buffer[(2*a)+(2*b+1)+d]=(uInt16)dual_buffer[a+(b+8)+(d+1)];
                        buffer[(2*a+16)+(2*b+1)+d]=(uInt16)(dual_buffer[a+(b+8)+(d+1)]>>16);
                }
        }
   }
.................................
if (scanType == AccumulationScan) {
            for (int s = 0; s < nScans; ++s) {
                for (int c = 0; c < MCHD_CH_AMT; ++c) {
                    raw_data[c] += buffer[MCHD_CH_AMT*s + c];
                    }
            }
            for (int c = 0; c < MCHD_CH_AMT; ++c) {
                raw_data[c] /= nScans;
                raw_data[c] *= MCHD_COEFF;
            }
...........
 __finally {
        free(raw_data);
        free(norm_data);
        free(buffer);
        free(dual_buffer);
        delete[] bad_points;
    }

    return true;
}

This is the system information form NI MAX:

Operating System(OS)                     Windows 7 Professional
OS Version                               6.01.7601
OS Info                                  Service Pack 1
Processor                                Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz / x86 Family 6 Model 60 Stepping 3 / GenuineIntel / 3299 MHz
Number of Processors                     4
Physical Memory                          3.20 GB of RAM
Drive C:\                                108 GB of 232 GB free
                                         
National Instruments Software:           Version:
                                         
CVI Run-Time                             8.1.1.361
NI-DAQmx Device Driver                   15.5.1f0
NI-DAQmx ADE Support                     15.5.1
NI-DAQmx MAX Configuration               15.5.1
NI I/O Trace                             15.0.0f0
IVI Compliance Package                   4.0
LabVIEW Run-Time 2012 SP1 f5             12.0.1
Measurement & Automation Explorer        15.3.0f0
Measurement Studio                       Visual Studio 2005 Support - See individual versions below.
     DotNET                               
          Common                         8.7.20.131
Measurement Studio                       Visual Studio 2010 Support - See individual versions below.
     DotNET                               
          Common                         15.1.40.49152
          Common (64-bit)                15.1.40.49152
NI-USI                                   1.0.2
NI PXI Platform Services Configuration   15.0.0f1
NI PXI Platform Services Runtime         15.0.0f1
NI-PAL Software                          15.1.0
LabVIEW SignalExpress                    3.5
NI System Configuration                  15.3.0f0
NI-VISA                                  15.0.1
NI-VISA Runtime                          15.0.1
LabVIEW Run-Time 2014 SP1 f3             14.0.1
LabVIEW Run-Time 8.0.1                   8.0.1
LabVIEW Run-Time 8.2.1                   8.2.1
LabVIEW Run-Time 8.5.1                   8.5.1
LabVIEW Run-Time 8.6.1                   8.6.1
LabVIEW Run-Time 2009                    9.0.0
 
And finally, this is the version of the DAQmx library header:
/*============================================================================*/
/*                 National Instruments / Data Acquisition                    */
/*----------------------------------------------------------------------------*/
/*    Copyright (c) National Instruments 2003.  All Rights Reserved.          */
/*----------------------------------------------------------------------------*/
/*                                                                            */
/* Title:       NIDAQmx.h                                                     */
/* Purpose:     Include file for NI-DAQmx library support.                    */
/*                                                                            */
/*============================================================================*/
 
I know that I probably have not provided all needed information, I can attempt to describe further if needed, but as I said at the start, I really don't have much experience with computer programming
Thanks in advance for any help you may be able to provide.
0 Kudos
Message 1 of 4
(3,058 Views)

Hi marsfur,

 

There are a couple of debugging tools that I think will help narrow down what is happening:

 

1) Can you enable the Resource Tracking Window? This will allow you to see the memory allocated by your variables as your programs run and lets you look for memory leaks. You go to options -> build options -> Configuration Options and set the "Debugging Level" to extended.

 

2)  Can you monitor the memory being used by CVI inside of the windows task manager? If you are experiencing a memory leak the amount of memory being used by CVI should slowly be increasing over time.

0 Kudos
Message 2 of 4
(3,013 Views)

Hi, thanks for the response.  I'm actually just using the NIDAQmx api in an application built in Borland C++ Builder 6, so I dont have those options.  what I have done is use NI Trace to capture all of the api function calls until the program crashes, and it seems to crash in the midst of a DAQmxReadDigitalU32 command. I'm attaching the end of the captured nitrace file, its the last data collection cycle the code runs and then crashes partway through the buffer.

0 Kudos
Message 3 of 4
(3,002 Views)

I'd be curious to see if we are writing to memory that is never released. What does the memory indicator in your Windows task manager do while this code runs? A steady increase might mean that the program eventually begins to overwrite memory not allocated to LabVIEW, causing a system halt.

Sam R.
0 Kudos
Message 4 of 4
(2,994 Views)