|
Communicating with the Kernel |
Top Previous Next |
|
In general, high-level interrupt handlers must not call Diamond functions, such as those found in stdio.h, chan.h, sema.h, event.h, and timer.h. Often, however, a handler needs to restart a thread that is waiting for an interrupt. Three special functions that can be called from a high-level interrupt handler (and only from a high-level interrupt handler) are provided for this:
Always make sure that all semaphores and events used by interrupt handlers have been initialised appropriately before attaching the handler to an interrupt.
When an ordinary thread needs to wait for an interrupt it can simply wait for a semaphore to be signalled or an event to be set. For example:
#include <sema.h> static SEMA int_sema; // global to handler and waiting thread
void interrupt my_handler(void) { i_sema_signal(&int_sema); }
main() { sema_init(&int_sema, 0); // BEFORE attaching interrupt . . . attach my_handler to interrupt as described above for (;;) { sema_wait(&dint_sema); // Wait for a block of data . . . process device data } }
As well as optionally signalling semaphores and setting events, handler code can freely read and write the contents of memory. Just remember to declare variables that are shared with the rest of an application as volatile (this is not necessary for semaphores and events).
Don’t be tempted into making user threads wait for interrupts by polling flags in memory though: use semaphores or events instead. In general you should avoid polling because it starves other tasks and threads of CPU cycles. Even devices that transfer only a small amount of data per interrupt can be efficiently dealt with if the handler buffers up data in memory and only signals the user thread when a complete block of data has been processed.
The folder <3L>Diamond\edition\Sundance\c6000\examples\interrupts\attachfn contains sample code that handles interrupts using events and semaphores. The examples both set up timer 1 to interrupt once per second. Each second, when the hardware interrupts, the interrupt handler signals a semaphore or sets an event. This wakes the main thread, which prints a message. The message includes the current value of a counter variable updated by the handler.
| |||||||||||||||