Digital I/O

Showing results for 
Search instead for 
Did you mean: 

DIG_Transfer returns error -10003 when passed mapped view of file

I'm using a 6533 PCMCIA card and i'm trying to use memory mapping to improve the performance.  DIG_DB_Transfer returns an error of invalid numeric parameter, when I pass it a mapped view of a file (portion of code shown below).  If I pass Transfer a normal character array and save that array in memory location, the error disappears and the data gets mapped to the harddrive, but this would seem to slow down the process significantly.  Why doesn't DIG_DB_Transfer accept this call?
memorylocation = (char*) MapViewOfFile(hmemmap, FILE_MAP_WRITE, 0, numberofbuffersmapped*ulPtsTfr*2, ulPtsTfr*2);
iStatus = DIG_DB_Transfer(iDevice, iGroup, (short*) memorylocation, ulPtsTfr);

0 Kudos
Message 1 of 8
Hi Buffning -

It looks like you're using the WINE API here -- is that the case?  Unfortunately, I can't ensure that our drivers will work through WINE, and I'm unable to help you troubleshoot that type of application.  (If none of our other forum users can help here, you might try posting to a WINE forum.)

If I'm mistaken though, please let me know.  I'll be happy to help out.
David Staab, CLA
Staff Systems Engineer
National Instruments
0 Kudos
Message 2 of 8
I have absolutely no idea what WINE is.  Looking online it looks like a way to run windows on Unix.  I'm not using that as far as I can tell.  I'm running on windows XP using microsoft XP and running microsoft SDK and programming in c++.  the functions i specifically posted were under the kernel32 library.  Mapping a view of the file, theoretically, should just return a pointer to an area of the harddrive inside of a created file so that I can put things directly onto the disk as opposed to passing through RAM, which I was hoping would cut down on memory transfers and speed up the process. 

0 Kudos
Message 3 of 8
Hi Mark -

I'm not sure why the function call isn't working.  Is the code you posted fully inclusive of the calls necessary to set this up, or is there more code you could post for reference?  (I'm going to ask our developers to help me debug this, and I'd like to make sure all necessary resources are available.)
David Staab, CLA
Staff Systems Engineer
National Instruments
0 Kudos
Message 4 of 8
I attached the entire program below.  The problem seems to be in the line of the DB_Transfer function though because if I uncomment the char* memtowrite and pass memtowrite in place of memorylocation, the code works fine (albeit too slowly for my needs since I then have to transfer from memtowrite into memory.)

void main(void)
    cout << "This program should display out information as to what it is taking \n in and where in the program it currently is so that \n we can check to see where the program is failing.\n" << endl;
// handle file I/O and get location to store data
    char filename[32];
    short *memorylocation;
    ofstream outputfile;

    u32 numberofbuffersmapped=0, numberofbuffersinfile=13000;
    const u32 buffersize = 800;  // sets up size of buffer, must be divisible by 16 so that whole number of bytes can be drawn from it

    HANDLE hfile, hmemmap;
    DWORD lasterror;

    LPCWSTR temp = MultiCharToUniChar((char*) &"hello.txt");
    delete[] temp;
    lasterror = GetLastError();
    if ( hfile == INVALID_HANDLE_VALUE )
         printf( "Cannot open file because %d \n", lasterror);
    hmemmap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0, numberofbuffersinfile*buffersize, NULL);
    lasterror = GetLastError();
    if ( hmemmap == INVALID_HANDLE_VALUE )
         printf( "Cannot open mememap because %d \n", lasterror);

//initiate variables to be used in card interface
    const i16 itimetowaitbeforeending = 6; // in seconds
    i16 iStatus = 0;
    i16 iRetVal = 0;
    const i16 iDevice = 1;
    const i16 iGroup = 1;
    const i16 iGroupSize = 2;
    const i16 iPort = 0;
    const i16 iDir = 0;
    const i16 iProtocol = 0;
    const i16 iEdge = 0;
    const i16 ireqPol = 1;
    const i16 iackPol = 0;
    const i16 iackDelayTime =0;
    const i16 iPgConfig = 1;
    const i16 iReqSource = 1;
    const i16 iPgTB = -3; 
    const i16 iReqInt = 10;
    const i16 iExtGate = 0;
    const i16 iDBModeON = 1;
    const i16 iDBModeOFF = 0;
    const i16 iOldDataStop = 1;
    static i16 piBuffer[buffersize]={0};
    const u32 ulPtsTfr = buffersize/2;
    const i16 iPartialTransfer = 0;
    const i16 iIgnoreWarning = 0;    //1 to ignore warning,
    const i32 lTimeout = 180;
    const i16 iYieldON = 1;
    u32 PointsRemaining     = 0;
    u32 lastpointsremaining = buffersize*numberofbuffersinfile;
//    char *memtowrite;
//    memtowrite = new char [buffersize];

// set up time to find when timeout occurs to stop program
    clock_t start = clock();
    clock_t end = clock();

    iStatus = DIG_Block_Clear(iDevice, iGroup);
    iStatus = Timeout_Config(iDevice, lTimeout);  // set to 10 seconds
    iRetVal = NIDAQErrorHandler(iStatus, "Timeout_Config", iIgnoreWarning);

    /* Configure group of ports as input, with handshaking. */
    iStatus = DIG_Grp_Config(iDevice, iGroup, iGroupSize, iPort, iDir);
    iRetVal = NIDAQErrorHandler(iStatus, "DIG_Grp_Config", iIgnoreWarning);

    iStatus = DIG_Grp_Mode(iDevice, iGroup, iProtocol, iEdge, ireqPol, iackPol, iackDelayTime);
    iRetVal = NIDAQErrorHandler(iStatus, "DIG_Group_Mode", iIgnoreWarning);

    iStatus = DIG_Block_PG_Config(iDevice, iGroup, iPgConfig, iReqSource, iPgTB, iReqInt, iExtGate);
    iRetVal = NIDAQErrorHandler(iStatus, "DIG_Block_PG_Config", iIgnoreWarning);

    iStatus = DIG_DB_Config(iDevice, iGroup, iDBModeON, iOldDataStop, iPartialTransfer);
    iRetVal = NIDAQErrorHandler(iStatus, "DIG_DB_Config", iIgnoreWarning);

    iStatus = DIG_Block_In(iDevice, iGroup, (short*) memorylocation, buffersize);
    iRetVal = NIDAQErrorHandler(iStatus, "DIG_Block_In", iIgnoreWarning);

    // number of buffers mapped can't change unless the line that says how big of a file to create changes.
    while ( ((end-start)/1000 < itimetowaitbeforeending) && (numberofhalfbuffersmapped<= numberofbuffersinfile))
       iStatus = DIG_DB_HalfReady(iDevice, iGroup, &iHalfReady);
        iRetVal = NIDAQErrorHandler(iStatus, "DIG_DB_HalfReady", iIgnoreWarning);
        if ( iStatus >= 0 )
            if (iHalfReady)   // gets half buffer to work with while rest of buffer continues to input
                memorylocation = (short*) MapViewOfFile(hmemmap, FILE_MAP_WRITE, 0,numberofhalfbuffersmapped*buffersize, buffersize);
                iStatus = DIG_DB_Transfer(iDevice, iGroup, (char*) memorylocation, buffersize/2);
                iRetVal = NIDAQErrorHandler(iStatus, "DIG_DB_Transfer", iIgnoreWarning);           

                start = clock();  // took in half buffer so reset beginning of wait time
            iRetVal = NIDAQErrorHandler(iStatus, "DIG_DB_HalfReady", iIgnoreWarning);
    iStatus = DIG_Block_Check (iDevice, iGroup, &PointsRemaining);
    iRetVal = NIDAQErrorHandler(iStatus, "DIG_Block_Check", iIgnoreWarning);

    cout << "PointsRemaining = " << PointsRemaining << endl;

    iStatus = DIG_Block_Clear(iDevice, iGroup);
0 Kudos
Message 5 of 8
Hi Buffning -

The error is most likely being returned by our function when it performs a sanity check on its input arguments.  Without trying to run your code, I suspect that the MapViewOfFile function is returning an invalid location.  Have you tried adding an error check to that line?
David Staab, CLA
Staff Systems Engineer
National Instruments
0 Kudos
Message 6 of 8
I've checked mapviewoffile and it seems to be working.  it lets me use it and the data i store in it gets written to the file like it should.  I haven't checked to see if it returns an odd address that would misalign the 2 byte shorts that are to be stored in it. 

Thanks for the help
0 Kudos
Message 7 of 8
Hi Buffning -

Unfortunately, that's the only potential problem we can immediately see.  Could you check for this and let me know if that's it?
David Staab, CLA
Staff Systems Engineer
National Instruments
0 Kudos
Message 8 of 8