/***************************************************************************/ /* example_exception.c * * Simple example of how exception/signal handling works. * * Build: * $COMMONCC -o example_exception example_exception.c $VMELIBS * * One of the #define lines below to choose the exception policy * or none of them for the default. * *#define EXAMPLE_DEFAULT * By default the bus error signal is capture mainly to do * a defined cleanup before the exit is executed. * *#define EXAMPLE_PRINT * The bus error signal will be captured and a message will * be printed to standard output but no exit() is executed. * *#define EXAMPLE_NONE * does not capture any bus error signal which will actually * by system default means a quick exit. But you can capture * the signal in your own program. * *#define EXAMPLE_CHECK * captures the bus error signal and sets a variable which * should be tested with the call VmeCheckException(). */ /***************************************************************************/ #define EXAMPLE_PRINT #include <stdio.h> #include <sys/types.h> #include <time.h> #include "Vme.h" #define VME_MAP_ADDRESS 0x10000000 #define VME_MAP_SIZE 1024*1024 /* 1 MB */ #define VME_MAP_AM 0x09 /* Extended VME address */ /***************************************************************************/ main (int argc, char *argv[]) /*--------------------------- */ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { u_long vme_address = VME_MAP_ADDRESS; int cid, signal_nr; volatile int data; int *vme_base; /*.........................................................................*/ /* Use a different VME base address if specified. */ if ((argc==2)&&(sscanf(argv[1],"%x",&vme_address)!=1)) { printf("Usage: %s <vme-base-address>\n",argv[0]); exit(1); } /* Define the exception handling policy. */ #ifdef EXAMPLE_PRINT VmeSetExceptionHandling(Vme_EXCEPTION_PRINT); #endif #ifdef EXAMPLE_NONE VmeSetExceptionHandling(Vme_EXCEPTION_NONE); #endif #ifdef EXAMPLE_CHECK VmeSetExceptionHandling(Vme_EXCEPTION_CHECK); #endif /* Open a VME channel for Programmed I/O. */ cid = VmeOpenChannel("Example1","pio"); if (cid < 0 ) exit(1); /* Map VME address space. */ vme_base = (int *)VmeMapAddress(cid,vme_address,VME_MAP_SIZE,VME_MAP_AM); if (vme_base == NULL) exit(1); /* We try to access two times a maybe wrong address * to see the result of a bus error. */ printf("Reading from VME address 0x%x \n",vme_address); Vme_D32READ(vme_base, &vme_base[0], data); #ifdef EXAMPLE_CHECK if (signal_nr=VmeCheckException()) { printf("... read failed, signal number = %d\n",signal_nr); if (signal_nr = SIGBUS) { int bus_error_type = VmeGetBusErrorType(); switch (bus_error_type) { case Vme_BUS_ERROR_TYPE_TIMEOUT: printf("... this was a timeout bus error\n"); break; case Vme_BUS_ERROR_TYPE_TIMEOUT: printf("... this was a bus error from the slave\n"); break; default: printf("... unknown bus error type (timeout or from slave)\n"); break; } } } else printf("... 0x%x read\n",data); #endif printf("Reading from VME address 0x%x again ...\n",vme_address); Vme_D32READ(vme_base, &vme_base[0], data); #ifdef EXAMPLE_CHECK if (signal_nr=VmeCheckException()) printf("... read failed, signal number = %d\n",signal_nr); else printf("... 0x%x read\n",data); #endif /* Close Vme channel. Do not forget to call this function * before you exit otherwise you might get some trouble later. */ (void)VmeCloseChannel(cid); }