From: Michael K <vk...@ya...> - 2022-05-07 15:55:55
|
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, ¤tTimeout); 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 ); } |