Interrupt and exception handlers

In eCos a distinction is made between exceptions and interrupts.

exceptions

are the result of some action by the currently executing code. Examples of exceptions are divide by zero, illegal instruction, bad memory access, etc.

interrupts

are the result of a signal source which is conceptually asynchronous with the currently executing code. Examples of interrupts sources are the real-time clock, external and on chip peripherals and so forth.

This distinction is made in the eCos hardware abstraction layer (HAL) to provide a cleaner and more portable mechanism for installing interrupt handlers and exception handlers. Individual hardware platforms can have different ways of naming and handling interrupts, which is why this abstraction layer was chosen.

Interrupts and exceptions are both associated with vectors, which are labeled by vector numbers (see the section called Exception handling in Chapter 5 and the section called Interrupt handling in Chapter 5).

There are distinct spaces for exception and interrupt vectors. These are called "exception vector numbers" and "interrupt vector numbers". System calls which install exception handlers use the exception vector number, and the system calls which install interrupt handlers use the interrupt vector number to specify which interrupt or exception should be handled by the handler.

The details of the vector layout depend on the microprocessor and interrupt controller, and are documented in the relevant API sections.

Interrupt handlers are actually a pair of functions, one of which (the interrupt service routine, or ISR) is executed immediately and runs with that interrupt disabled. Since interrupts are disabled for the duration of the ISR, the ISR should be very brief and should not use any system services.

After the ISR exits, but before the kernel scheduler is invoked again, a delayed service routine (DSR) will be invoked. It executes with scheduling disabled, but with interrupts enabled, so that further invocations of the same DSR can be queued. The DSR can use some producer-side system calls, but it should be carefully crafted to avoid using any call that might put its thread to sleep. One of the few examples of safe calls is cyg_semaphore_post(); the non-blocking versions of some system calls are also safe. A call that is unsafe is cyg_mutex_lock(), since it will block if the mutex is already locked by another thread.

Finally, eCos has a formalism for installing low level handlers which bypass the kernel mechanisms described above. A program can install a vector service routine (VSR) which will be invoked instead of the kernel's usual exception or interrupt handling. The VSR will typically be written in assembly language.

VSRs are associated with vector numbers in the exception space, just like exception handlers (although there are some variations — architectures in which there are no exceptions in the eCos sense). The main difference between VSRs and exception handlers is that VSRs bypass the kernel's usual mechanisms.