Blame
|
1 | # Handling Interrupts |
||||||
| 2 | ||||||||
|
3 | This actually is very simple. gcc provides the means to mark a function as an interrupt service routine, namely prefixing a function with `__attribute__(interrupt)`. So, something like this: |
||||||
| 4 | ```c |
|||||||
| 5 | __attribute__((interrupt)) duart_interrupt(void) { |
|||||||
| 6 | /* Handle the interrupt */ |
|||||||
|
7 | |||||||
| 8 | } |
|||||||
|
9 | ``` |
||||||
|
10 | But there's a macro in `machine.h` to help, so you could replace the above with: |
||||||
| 11 | ```c |
|||||||
| 12 | #include <machine.h> |
|||||||
| 13 | ||||||||
| 14 | ISR duart_interrupt(void) { |
|||||||
| 15 | /* Handle the interrupt */ |
|||||||
| 16 | ||||||||
| 17 | } |
|||||||
| 18 | ``` |
|||||||
| 19 | gcc knows that functions declared using either of the above methods should end with the `rte` rather than `rts` instruction. |
|||||||
|
20 | |||||||
| 21 | ## Example |
|||||||
| 22 | ```c |
|||||||
| 23 | #include <stdio.h> |
|||||||
| 24 | #include <machine.h> |
|||||||
| 25 | ||||||||
| 26 | static unsigned int ticks = 0; |
|||||||
| 27 | ||||||||
|
28 | void twiddle_thumbs(void); |
||||||
| 29 | ||||||||
|
30 | void ISR isr(void) { |
||||||
| 31 | ticks++; |
|||||||
| 32 | ||||||||
| 33 | *pit_tsr = 1; |
|||||||
| 34 | } |
|||||||
| 35 | ||||||||
| 36 | void scan() { |
|||||||
| 37 | static int lednum = 2; |
|||||||
| 38 | static int delta = 1; |
|||||||
| 39 | ||||||||
|
40 | /* create simple visual effect with some of the leds */ |
||||||
|
41 | clear_led(lednum); |
||||||
| 42 | ||||||||
| 43 | lednum += delta; |
|||||||
| 44 | if ((lednum < 2) || (lednum > 7)) { |
|||||||
| 45 | delta = -delta; |
|||||||
| 46 | lednum += delta; |
|||||||
| 47 | lednum += delta; |
|||||||
| 48 | } |
|||||||
| 49 | ||||||||
| 50 | set_led(lednum); |
|||||||
| 51 | } |
|||||||
| 52 | ||||||||
| 53 | int main(void) { |
|||||||
| 54 | unsigned char ivr = *pit_tivr; |
|||||||
| 55 | ||||||||
| 56 | int loop = 0; |
|||||||
| 57 | ||||||||
| 58 | printf("Press any key...\n"); |
|||||||
| 59 | ||||||||
| 60 | _pit_set_counter(1000); |
|||||||
| 61 | *pit_tsr = 1; |
|||||||
| 62 | ||||||||
|
63 | set_isr_handler(ivr, isr); |
||||||
|
64 | |||||||
|
65 | /* Wait for a keypress */ |
||||||
|
66 | while (!_char_available()) { |
||||||
| 67 | printf("%08x\r", ticks); |
|||||||
| 68 | ||||||||
| 69 | loop++; |
|||||||
| 70 | if (loop == 100) { |
|||||||
| 71 | scan(); |
|||||||
| 72 | loop = 0; |
|||||||
| 73 | } |
|||||||
| 74 | } |
|||||||
| 75 | ||||||||
| 76 | _getchar(); |
|||||||
| 77 | } |
|||||||
| 78 | ``` |
|||||||