Elektolurch schrieb:
> Wie macht man das bei den SAMs - ohne ASF.
Es gibt leider bei den ARMs kein so völlig einheitliches Vorgehen.
Anders als bei AVR-GCC ist es hier sehr üblich, dass jeder seinen
eigenen Startup-Code und seine eigenen Linkerscripts im Projekt
mitführt. Diese beiden Teile müssen naturgemäß stark aufeinander
abgestimmt sein (der Startup-Code benötigt Symbole, die im Linkerscript
definiert werden, um zum Beispiel .bss auszunullen oder .data aus dem
Flash zu füllen).
Die Interruptvektortabelle spielt hier in der gleichen Liga. Sie liegt
bei Cortex-M per definitionem auf den ersten Adressen des zum Booten
benutzten Speicherbereichs (also bspw. dem Flash), und sie beginnt mit
dem Initialwert für den Stackpointer (den man typischerweise von einem
Symbol aus dem Linkerscript bekommt), gefolgt von den Einsprungpunkten
für den Reset-Vektor, die Exception-Handler und danach allen
Interruptvektoren.
Üblich ist es, bspw. über eine weak-Deklaration einen Interruptvektor
als "catch-all" vorab in alle Slots zu installieren. Die Applikation
kann dann eine Funktion gleichen Namens linken lassen, der überschreibt
diesen Eintrag beim Linken.
Atmel liefert in seinen Device Packs Headerdateien sowie Startup-Code
für seine MCUs mit aus. Die kannst du entweder direkt benutzen oder als
Vorlage für deine eigene Variante. Ich hänge dir mal ein paar Beispiele
an. Wenn du die Beispiele wie hier verwendest, dann wäre bspw. die ISR
für UART0 sowas wie:
1 | void UART0_Handler(void)
|
2 | {
|
3 | uint32_t uart_irq_cause;
|
4 |
|
5 | /*
|
6 | * The interrupt is acknowledged by reading the status register. This
|
7 | * clears the interrupt at the UART level.
|
8 | */
|
9 | uart_irq_cause = UART0->UART_SR;
|
10 |
|
11 | if (uart_irq_cause & UART_SR_RXRDY)
|
12 | {
|
13 | uint8_t c = UART0->UART_RHR;
|
14 |
|
15 | // handle received character
|
16 | }
|
17 | if (uart_irq_cause & UART_SR_TXEMPTY)
|
18 | {
|
19 | if (tx_buffer_empty())
|
20 | {
|
21 | // no more work
|
22 | UART0->UART_IDR = UART_IDR_TXEMPTY;
|
23 | }
|
24 | else
|
25 | {
|
26 | uint8_t c = get_next_char();
|
27 | UART0->UART_THR = c;
|
28 | }
|
29 | }
|
30 | // handle UART exception conditions here
|
31 | }
|