Blame

138850 Bob Green 2026-03-29 13:55:51
1
# Handling Interrupts
2
a3050c Bob Green 2026-03-29 13:57:47
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 */
3dedcc Bob Green 2026-03-29 14:01:16
7
8
}
a3050c Bob Green 2026-03-29 13:57:47
9
```
3dedcc Bob Green 2026-03-29 14:01:16
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.
d244ca Bob Green 2026-03-29 14:10:12
20
21
## Example
22
```c
23
#include <stdio.h>
24
#include <machine.h>
25
26
#define LEDS1 0xa0
27
#define LEDS2 0x50
28
29
static unsigned int ticks = 0;
30
31
void twiddle_thumbs(void);
32
33
void ISR isr(void) {
34
ticks++;
35
36
*pit_tsr = 1;
37
}
38
39
void scan() {
40
static int lednum = 2;
41
static int delta = 1;
42
43
clear_led(lednum);
44
45
lednum += delta;
46
if ((lednum < 2) || (lednum > 7)) {
47
delta = -delta;
48
lednum += delta;
49
lednum += delta;
50
}
51
52
set_led(lednum);
53
}
54
55
int main(void) {
56
unsigned char ivr = *pit_tivr;
57
58
int loop = 0;
59
60
printf("Press any key...\n");
61
62
_pit_set_counter(1000);
63
*pit_tsr = 1;
64
65
set_isr_vector(ivr, isr);
66
67
while (!_char_available()) {
68
printf("%08x\r", ticks);
69
70
loop++;
71
if (loop == 100) {
72
scan();
73
loop = 0;
74
}
75
}
76
77
_getchar();
78
}
79
```