Example 4-1 : Opening and Using a Hypothetical VME Device
#define SPECFILE "/dev/vme/vme1a16n" typedef unsigned short int busdata; /* device data item */ typedef volatile busdata busreg; /* device register */ #define MAPSIZE 8*sizeof(vmereg) #define BUSADDR 0xff00 int vmefunc() { busreg *mapped; busdata sample; int specfd = open(SPECFILE,O_RDWR); if (-1 == specfd) return error; mapped = mmap(NULL, /* kernel pick address */ REGSIZE, /* size of mapped area */ PROT_READ|PROT_WRITE, /* protection flags */ MAP_SHARED, /* mapping flags */ specfd, /* special file */ BUSADDR) /* file offset */ if (!mapped) return error; sample = busreg[0]; /* read A16N at 0xff00 */ busreg[1] = sample; /* write A16N at 0xff02 */ }A PIO read is synchronous at the hardware level. The CPU executes a register-load instruction that does not complete until data has been returned from the device, up the system bus, to the CPU (see "CPU Access to Device Registers"). This can take 1 or 2 microseconds in a Challenge system.
A PIO write is not necessarily synchronous at the hardware level. The CPU executes a register-store instruction that is complete as soon as the physical address and data have been placed on the system bus. The actual VME write operation on the VME bus can take 1 or more microseconds to complete. During that time the CPU can execute dozens or even hundreds more instructions from cache memory.