From: Michael K <vk...@ya...> - 2022-08-07 21:08:40
|
I think I found out the problem. (this is a bug in the library) When you call ibrda, the timeout is not cached by the routine. If you immediately change the timeout following the call, the async process has not yet accessed it and so gets the new (changed) value. See the example below... if I delay the change of timeout by 10ms, it works. If I use the same delay but after the timeout change if fails. The library must cache the timeout when the ibrda or ibwrta call is made (and pass this through to the async process). [michael@dirac ~]$ ./asyncReadTest 100ms delay AFTER changing timeout for ibwaitGPIB failure waitingGPIB status 8100[michael@dirac ~]$ ./asyncReadTest -b100ms delay BEFORE changing timeout for ibwaitGPIB wait timeout (0.000)GPIB wait timeout (0.010)GPIB wait timeout (0.020)GPIB wait timeout (0.030)GPIB wait timeout (0.040)GPIB read complete (2630 characters)Complete OKGPIB status 2100[michael@dirac ~]$ // $ gcc -o asyncReadTest asyncReadTest.c -lgpib #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h> #include <gpib/ib.h> #define GPIB_CONTROLLER_INDEX 0#define GPIB_DEVICE_PID 16#define ERROR -1#define READ_BUF_SIZE 4000#define TIMEOUT 10.0#define GPIB_SET_EOI 1#define TIMEOUT_10S 10.0#define FALSE 0#define TRUE 1 int main( int argc, char **argv){ int GPIBstatus; int GPIBdescriptor; char readBuffer[ READ_BUF_SIZE ]; double timeElapsed = 0.0; char *sQuery = "OUTPLEAS;"; int bDelayBeforeTimeoutChange = FALSE; if( argc > 1 && strcmp( argv[1], "-b" ) == 0 ) { printf( "100ms delay BEFORE changing timeout for ibwait\n" ); bDelayBeforeTimeoutChange = TRUE; } else { printf( "100ms delay AFTER changing timeout for ibwait\n" ); bDelayBeforeTimeoutChange = FALSE; } GPIBdescriptor = ibdev( GPIB_CONTROLLER_INDEX, GPIB_DEVICE_PID, 0, T30ms, GPIB_SET_EOI, 0 ); if ( GPIBdescriptor == ERROR ) { fprintf( stderr, "Failed to open device %d\n", GPIB_DEVICE_PID); goto error; } GPIBstatus = ibwrt( GPIBdescriptor, sQuery, strlen( sQuery ) ); if ( GPIBstatus & ERR ) { fprintf( stderr, "GPIB write failure\n"); goto error; } ibtmo( GPIBdescriptor, TNONE ); GPIBstatus = ibrda( GPIBdescriptor, readBuffer, READ_BUF_SIZE ); if ( GPIBstatus & ERR ) { fprintf( stderr, "GPIB aync read failure\n"); goto error; } if( bDelayBeforeTimeoutChange ) { usleep( 20 * 1000 ); ibtmo( GPIBdescriptor, T10ms ); } else { ibtmo( GPIBdescriptor, T10ms ); usleep( 20 * 1000 ); } do { // Wait for read completion or timeout GPIBstatus = ibwait(GPIBdescriptor, TIMO | CMPL | END); if( (GPIBstatus & TIMO) == 0 ){ if( GPIBstatus & ERR ){ fprintf( stderr, "GPIB failure waiting\n"); goto error; } if( GPIBstatus & CMPL ){ fprintf( stderr, "GPIB read complete (%d characters)\n", ibcnt); break; } if( GPIBstatus & END ){ fprintf( stderr, "GPIB read complete (EOI) (%d characters)\n", ibcnt); break; } } fprintf( stderr, "GPIB wait timeout (%.3f)\n", timeElapsed); timeElapsed += 0.01; } while ( (GPIBstatus & TIMO) && timeElapsed < TIMEOUT_10S ); if( timeElapsed < TIMEOUT_10S ) fprintf( stderr, "Complete OK\n" ); else fprintf( stderr, "10 second timeout\n" );error: fprintf( stderr, "GPIB status %04x\n", ibsta);} On Thursday, August 4, 2022 at 05:33:17 PM EDT, Frank Mori Hess <fm...@gm...> wrote: On Sat, May 7, 2022 at 11:56 AM Michael K via Linux-gpib-general <lin...@li...> wrote: > What is the correct way to use ibrda and ibwait together in this scenario ? It's been a while, but I believe you can set the timeout for the read before ibrda, then change the timeout for the wait before calling ibwait. |