Interrupt vector table Interrupt service routine(isr) Usr ISR Interrupt Timer I/O operations Vector number hardware handler Handler: Save registers Call routine Restore registers RET myisr() Interrupts allow devices to notify the CPU that some event has occurred A user-defined routine can be installed to execute when an arrives This routine runs at time It is not a On-board timers are a common source of s Using them requires understanding s Absolute System- Wide Priority Interrupt Level (Hard Wired) Execution OrderControlled by Hardware Execution OrderControlled by Kernel Task Priority (Programmable) 1 2 Most architectures use a single dedicated stack Interrupt stack is allocated at system start-up The stack size is controlled by the macro INT_STACK_SIZE; default value defined in configallh Must be large enough for worst-case nesting Library Routines blib All routines errnolib errnoget(), errnoset() fpparchlib fppsave(), fpprestore() intlib intcontext(), intcount(), intvecset(), intvecget() intarchlib intlock(), intunlock() loglib logmsg() lstlib All routines except lstfree() No s can run until ISR has completed ISR s are restricted from using some VxWorks facilities In particular, they can t block: Can t call semtake( ) Can t call malloc( ) (uses semaphores) Can t call I/O system routines (eg, printf( )) mathalib All routines, if fppsave()/fpprestore() are used msgqlib msgqsend() pipedrv write() rnglib All routines except rngcreate() and rngdelete() selectlib selwakeup(), selwakeupall() semlib semgive() except mutual-exclusion semaphores, semflush() siglib kill() 3 4
Lib Suspend(), Resume(), PrioritySet(), PriorityGet(),IdVerify(), IdDefault(), IsReady(),IsSuspended(),Tcb() ticklib tickannounce(), tickset(), tickget() tylib tyird(), tyitx() vxlib vxtas(), vxmemprobe() wdlib wdstart(), wdcancel() Reads and writes memory-mapped I/O registers Communicates information to a by: Writing to memory Making non-blocking writes to a message queue Giving a binary semaphore Keep ISR s short, because ISR s: Delay lower and equal priority s Delay all s Can be hard to debug Avoid using floating-point operations in an ISR They may be slow User must call fppsave( ) and fpprestore( ) Try to off-load as much work as possible to some : Work which is longer in duration Work which is less critical To log diagnostic information to the console at time: logmsg ( foo = %d\n, foo, 0, 0, 0, 0, 0); Sends a request to tlogtask to do a printf( ) for us Similar to printf( ), with the following caveats: Arguments must be 4 bytes Format string plus 6 additional arguments Use a debugging strategy which provides system-level debugging: WDB agent Emulator 5 6 Cause a trap to the boot ROM s Logged messages will not be printed Boot ROM program will display an exception description on reboot An exception occurring in an ISR will generate a warm reboot Can use sprintf( ) to print diagnostic information to memory not overwritten on reboot, if necessary STATUS intconnect (vector, routine, param) vector The vector routine The address of the user-defined ISR param Any value to be passed to this ISR Example: #include "ivh" void myisr(); if (intconnect (INUM_TO_IVEC(intNum), myisr, 0) ==ERROR) return (ERROR); INUM_TO_IVEC (intnum) Converts an number to vector in an architecture dependent manner: On-board timers the CPU periodically Timers allow user-defined routines to be executed at periodic intervals, which is useful for: Polling hardware Checking for system errors Aborting an untimely operation VxWorks supplies a generic interface to manipulate two timers: System clock Auxiliary clock (if available) 7 8
System clock ISR performs book-keeping: Increments the tick count (use tickget( ) to examine the count) Updates delays and timeouts Checks for round-robin rescheduling These operations may cause a reschedule Default clock rate is 60hz sysclkrateset (freq) Sets the clock rate int sysclkrateget( ) Returns the clock rate sysclkrateset( ) should only be called at system startup To create a watchdog timer: WDOG_ID wdcreate ( ) Returns watchdog id, or NULL on error To start (or restart) a watchdog timer: STATUS wdstart (wdid, delay, proutine,parameter) wdid Watchdog id, returned from wdcreate( ) delay Number of ticks to delay proutine Routine to call when delay has expired parameter Argument to pass to routine User interface to the system clock Allows a C routine to execute after a specified time delay Upon expiration of delay, connected routine runs As part of system clock ISR Subject to ISR restrictions To use watchdogs for periodic code execution: wdid = wdcreate(); wdstart (wdid, DELAY_PERIOD, mywdisr, 0); void mywdisr(int param) doit (param); wdstart (wdid, DELAY_PERIOD, mywdisr, param); The doit( ) routine might: Poll some hardware device Unblock some Check if system errors are present 9 10 To recover from a missed deadline: WDOG_ID wdid; void foo(void) wdid = wdcreate( ); /* Must finish each cycle in under 10 seconds */ FOREVER wdstart (wdid, DELAY_10_SEC, fooisr, 0); foodowork( ); To cancel a previously started watchdog: STATUS wdcancel (wdid) To deallocate a watchdog timer (and cancel any previous start): STATUS wddelete (wdid) void fooisr (int param) /* Handle missed deadline */ Can poll at time or time Interrupt time polling is more reliable Task time polling has a smaller impact on the rest of the system To poll at time, there are two options: Delay( ) : faster, but may drift wdstart( ) + semgive( ) : more robust 11 12
For high speed polling, use the auxiliary clock Precludes using spy, which also uses the auxiliary clock Some routines to manipulate auxiliary clock: sysauxclkconnect( ) Connect ISR to Aux clock sysauxclkrateset( ) Set Aux clock rate sysauxclkenable( ) Start Aux clock sysauxclkdisable( ) Stop Aux clock int timer_settime ( timer_t timerid, int flags, const struct itimerspec * value, struct itimerspec * ovalue ) int nanosleep ( const struct timespec * rqtp,struct timespec * rmtp ) int timer_getoverrun ( timer_t timerid ) int timer_create (clockid_t clock_id, struct sigevent * evp, time_t * ptimer ) int timer_delete ( timer_t timerid /* timer ID */ ) time_t tv_sec seconds long tv_nsec nanoseconds (0-1,000,000,000) int timer_gettime ( timer_t timerid, struct itimerspec * value ) Only one clock_id is supported, the required CLOCK_REALTIME 13 14 struct timespec it_interval timer period (reload value) struct timespec it_value timer expiration it_value: Non-zero sets the next time Zero the timer is disarmed it_interval: Non-zero a periodic (or repetitive) timer is specified Zero: once Select() socket, tserver pipe or serial port select( ) allows a to wait for activity on a set of file descriptors Requires driver support: VxWorks pipes, sockets and serial device drivers support select( ) Third party drivers may also support select( ) Also used to pend with a timeout int open (name, flags, mode) flags: O_RDONLY, O_WRONLY, O_RDWR, O_TRUNC, O_CREAT mode: Permissions for NFS device STATUS close (fd) Tasks must close files when they are no longer needed File descriptor table is fixed size int read (fd, buffer, nbytes) int write (fd, buffer, nbytes) May block; returns number of bytes read or written int ioctl (fd, command, arg) Allows execution of a device specific command Valid ioctl() commands are listed in driver help page Used by select( ) to specify file descriptors Conceptually an array of bits, with bit N corresponding to file descriptor N Bits are manipulated via a collection of macros: FD_SET (fd, &fdset) Sets the bit FD_CLR (fd, &fdset) Clears the bit FD_ISSET (fd, &fdset) Returns TRUE if the fd bit is set, else FALSE FD_ZERO (&fdset) Clears all bits 15 16
int select (width, preadfds, pwritefds, pexceptfds, ptimeout) width Number of bits to examine in preadfds and pwritefds preadfds struct fd_set pointer for the file descriptors we wish to read pwritefds struct fd_set pointer for the file descriptors we wish to write pexceptfds Not implemented ptimeout Pointer to a struct timeval, or NULL to wait forever Returns number of active devices, or ERROR aio_fildes file descriptor for I/O aio_offset offset from the beginning of the file aio_buf address of the buffer from/to which AIO is requested aio_nbytes number of bytes to read or write aio_reqprio priority reduction for this AIO request aio_sigevent signal to return on completion of an operation (optional) aio_lio_opcode operation to be performed by a lio_listio() call aio_sys VxWorks-specific data (non-posix) aio_lio_opcode Valid entries include LIO_READ, LIO_WRITE, and LIO_NOP aiopxlibinit() Initialize the AIO library (non-posix) aio_read() Initiate an asynchronous read operation aio_write() Initiate an asynchronous write operation aio_listio() Initiate a list of up to LIO_MAX asynchronous I/O requests aio_error() Retrieve the error status of an AIO operation aio_return() Retrieve the return status of a completed AIO operation aio_cancel() Cancel a previously submitted AIO operation aio_suspend() Wait until an AIO operation is done, ed, or timed out 17 18