async reads and timeouts

Michael K via Linux-gpib-general <[email protected]> Sat, 7 May 2022 15:55:28 +0000 (UTC)
Newsgroups gmane.linux.hardware.gpib.general
Message-ID <[email protected]>
I'm trying to write a routine to use asynchronous reads so that I can handle a long timeout (the device may take ~minute to respond) while still being responsive.

My plan was to set a short timeout (100ms) use ibrda (async read) and wait on CMPL, TIMO and END.
After a timeout, I check to see if we need to respond to other parts of the program (or an abort request) and then ibwait again.

This doesn't work. It seems that the read aborts after the timeout.

I can do an ibwait with 0 instead of ( TIMO | CMPL | END), check the ibstatus response, then use usleep to wait 100ms but this means that if the read completes while I'm sleeping I have an unnecessary (up to) 100ms delay.

What is the correct way to use ibrda and ibwait together in this scenario ?
 

typedef enum { eRD_OK=0, eRD_ERROR, eRD_TIMEOUT, eRD_ABORT, eRD_CONTINUE } tReadStatus;

tReadStatus
GPIB_AsyncRead( int GPIBdescriptor, void *readBuffer, long maxBytes, double timeout, int bAbort )
{
    int GPIBstatus, currentTimeout;

    tReadStatus rtn = eRD_CONTINUE;

    ibask(GPIBdescriptor, IbaTMO, &currentTimeout);

    ibtmo( GPIBdescriptor, T100s );
    GPIBstatus = ibrda( GPIBdescriptor, readBuffer, maxBytes );

    do {
#ifdef PREFERRED
        GPIBstatus = ibwait(GPIBdescriptor, TIMO | CMPL | END);
#else
        GPIBstatus = ibwait(GPIBdescriptor, 0);
#endif
        if( GPIBstatus & ERR )
            rtn= eRD_ERROR;
        else if( GPIBstatus & CMPL )
            rtn = eRD_OK;
        else if( bAbort )
            rtn = eRD_ABORT;
        else if((GPIBstatus & TIMO)  != TIMO )
            rtn = eRD_ERROR;
#ifdef PREFERRED
        if( rtn == eRD_CONTINUE )
            usleep(100 * 1000);
#endif
    } while( rtn == eRD_CONTINUE && (timeout -= 0.1) > 0.0 );

    if( rtn == eRD_OK )
        ibwait(GPIBdescriptor, CMPL);
    else
        ibstop( GPIBdescriptor );

    ibtmo( GPIBdescriptor, currentTimeout);
    return ( rtn == eRD_CONTINUE ? eRD_TIMEOUT : rtn );   
}


_______________________________________________
Linux-gpib-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-gpib-general