Exceptions, Interrupts, and Timers
10.1 Exception Handling and Signals
Interrupt Service Routines
Timers
10-1
Exception Handling Overview
An exception is an unplanned event generated by the
CPU. Examples include: trap or breakpoint instruction,
divide by zero, floating point or integer overflow, illegal
instruction, or address error.
An exception will generate an internal interrupt.
VxWorks installs exception handlers at system startup.
These handlers will run on an exception and will try to
invoke a user-defined exception handler.
A VxWorks exception handler communicates with a user
tasks by sending a signal. The user-installed handler will
then run.
10-2
Signals
10-3
UNIX: UNIX vs. VxWorks Signals
Signal is ignored if no handler is installed.
Automatic function restarting
Can install a handler to catch SIGKILL.
No SIGCHLD, SIGPIPE, or SIGURG.
taskDelay( ) sets errno = EINTR and returns ERROR if
interrupted by a signal.
10-4
Caveats
Signals are not recommended for general intertask
communication. A signal:
May be handled at too high a priority if it arrives during a priority
inheritance.
Disrupts a tasks normal execution order. (It is better to create two
tasks than to multiplex processing in one task via signals.)
Can cause reentrancy problems between a task running its signal
handler and the same task running its normal code.
Can be used to tell a task to shut itself down.
sigLib contains both POSIX and BSD UNIX interfaces. Do
not mix them.
10-5
Registering a Signal Handler
To register a signal handler:
signal (signo, handler)
signo
Signal number.
handler
Routine to invoke when signal arrives (or
SIG_IGN to
ignore signal).
Returns the previously installed signal handler, or SIG_ERR.
The signal handler should be declared as:
void sigHandler (int sig); /* signal number */
10-6
Signals and Exceptions
Hardware exceptions include bus error, address error,
divide by zero, floating point overflow, etc..
Some signals correspond to exceptions (e.g., SIGSEGV
corresponds to a bus error on a 68k; SIGFPE corresponds
to various arithmetical exceptions).
10-7
The Signal Handler
If an exception signal handler returns:
The offending task will be suspended.
A message will be logged to the console.
Exception signal handlers typically call:
exit( ) to terminate the task, or
taskRestart( ) to restart the task, or
longjmp( ) to resume execution at location saved by setjmp( ).
@
10-8
Exceptions, Interrupts, and Timers
Exception Handling and Signals
10.2 Interrupt Service Routines
Timers
10-9
Interrupts
Interrupts allow devices to notify the CPU that some event
has occurred.
A user-defined routine can be installed to execute when
an interrupt arrives.
This routine runs at interrupt time. It is not a task.
On-board timers are a common source of interrupts.
Using them requires understanding interrupts.
10-10
Device Drivers
Use interrupts for asynchronous I/O.
Are beyond the scope of this course.
For more information:
intArchLib
Board Support Package
Programmers Guide
Tornado Users Guide
BSP Porting Kit
VxWorks Device
Driver Workshop
Tornado BSP
Training Workshop
To install user defined ISRs.
Board-specific interrupt handling.
Architecture specific interrupt info.
System mode debugging info.
Optional product for writing BSPs.
Write VMEbus and VxWorks
standard device drivers.
BSP-specific interrupt issues, such
asinterruptcontrollersandbusses.
10-11
Interrupt Handling Example (68k)
10-12
Interrupt Handling Example (PowerPC)
10-13
Displaying the Interrupt Vector Table
To show the interrupt vector table from the Browser,
choose Vector Table in the selector box (Windows), or
click on the Interrupt button (UNIX).
10-14
Interrupts and Priorities
10-15
Interrupt Stack
Most architectures use a single dedicated interrupt stack.
Interrupt stack is allocated at system start-up.
The interrupt stack size is controlled by the macro
INT_STACK_SIZE; default value defined in configAll.h.
Must be large enough for worst-case nesting.
Interrupt Stack
10-16
ISR Restrictions
No tasks can run until ISR has completed.
ISRs are restricted from using some VxWorks facilities. In
particular, they cant block:
Cant call semTake( ).
Cant call malloc( ) (uses semaphores).
Cant call I/O system routines (e.g., printf( )).
The Programmers Guide gives a list of routines which
are callable at interrupt time.
10-17
ISR Guidelines
Keep ISRs short, because ISRs:
Delay lower and equal priority interrupts.
Delay all tasks.
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 task:
Work which is longer in duration.
Work which is less critical.
10-18
Typical ISR
Reads and writes memory-mapped I/O registers.
Communicates information to a task by:
Writing to memory.
Making non-blocking writes to a message queue.
Giving a binary semaphore.
10-19
Debugging ISRs
To log diagnostic information to the console at interrupt
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.
10-20
Exceptions at Interrupt Time
Cause a trap to the boot ROMs.
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.
10-21
Exceptions, Interrupts, and Timers
Exception Handling and Signals
Interrupt Service Routines
10.3 Timers
10-22
Timers
On-board timers interrupt 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).
10-23
System Clock
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 start-up.
10-24
Watchdog Timers
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.
10-25
Creating Watchdog Timers
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
delay
pRoutine
parameter
Watchdog id, returned from wdCreate( ).
Number of ticks to delay.
Routine to call when delay has expired.
Argument to pass to routine.
10-26
Using Watchdogs
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 task.
Check if system errors are present.
10-27
Missed Deadlines
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( );
}
}
void fooISR (int param)
{
/* Handle missed deadline */
...
}
10-28
Stopping Watchdogs
To cancel a previously started watchdog:
STATUS wdCancel (wdId)
To deallocate a watchdog timer (and cancel any previous
start):
STATUS wdDelete (wdId)
10-29
Watchdog Browser
After creating, but prior to activating the watchdog, the
Browser provides minimal information:
After activating the watchdog, more useful information is
provided:
10-30
Polling Issues
Can poll at task time or interrupt time.
Interrupt time polling is more reliable.
Task time polling has a smaller impact on the rest of the system.
To poll at task time, there are two options:
taskDelay( ) : faster, but may drift.
wdStart( ) + semGive( ) : more robust.
10-31
Polling Caveats
The following code is accurate only if the system clock
rate is a multiple of 15hz:
void myWdISR ( )
{
wdStart (myWdId, sysClkRateGet()/15, myWdISR, 0);
pollMyDevice();
}
Do not set the system clock rate too high, because there
is OS overhead in each clock tick.
Use auxiliary clock to poll at high speeds.
10-32
Auxiliary Clock
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.
10-33
Summary
Using signals for exception handling:
signal( )
exit( )
taskRestart( )
longjmp( )
Interrupt Service Routines have a limited context:
No Blocking
No I/O system calls
10-34
Summary
Polling with timers:
low speed
Interrupt
time
task
time
wd timer
high speed
aux clock
taskDelay, or
wd timer + semGive
10-35