|
Example of a Handler |
Top Previous Next |
|
The following is an example of a low-level interrupt handler for a hypothetical device attached to interrupt 6. This handler needs to write to a device-specific register at 0x03fe00004 to acknowledge the interrupt and disable the device. Writing to 0x03fe00000 allows the device to generate interrupts when ready.
Note that the return from k_event_set goes directly to the next interrupt handler.
.title "interrupt 6 handler" .text
INT_CLEAR .set 0x03EF0004 ; write 0 to acknowledge
.def _interrupt6
;------------------------------------------; ; on entry: a11 = kernel pointer ; ; a2 = &event ; ; b11 = address of next icb ; ; Interrupts are ENABLED ; ; on exit: b11 = address of next handler ; ; a2 = arg for next handler ; ; free regs:a0, a1, a3, a4, b0, b1, b3, b4 ; ;------------------------------------------;
_interrupt6: ldw *+a11[-1], b1 ; pointer to k_event_set mv a2, a4 ; argument for i_event_set ldw *+b11[1], b3 ; return address (next handler) ldw *+b11[2], a2 ; next argument ldw *+b11[0], b11 ; next handler ICB b b1 ; call k_event_set (&return) ldw *a4, b0 ; contents of event word mvkl INT_CLEAR, a0 mvkh INT_CLEAR, a0 ; address INT_CLEAR zero a1 stw a1, *a0 ; acknowledge interrupt
;-----------------------------; ; NOTE: i_event_set corrupts: ; ; b0, a1, a4, b4 ; ;-----------------------------;
This handler could be attached and used as follows:
extern void interrupt6(void); // the interrupt handler static struct c6xint_ICB ICB6; static event Event6 = EVENT_NO; // initialised event extern cregister unsigned int IER;
#define DEV_ENABLE *(volatile int *)0x03EF0004
...
ICB6.Handler = interrupt6; ICB6.Arg = &Event6;
c6xint_attach_handler(6, &ICB6);
IER |= (1<<6); // enable interrupt 6
for (;;) { Event6 = EVENT_NO; DEV_ENABLE = 1; // enable the device event_wait(&Event6); // the interrupt has occurred – deal with it ... }
|