Forum: Mikrocontroller und Digitale Elektronik SAM Atmelstudio7 Interupts ohne ASF


von Elektolurch (Gast)


Lesenswert?

Hallo,

bisher war ich es gewohnt Interuptroutinen so zu schreiben:
#include <avr/interrupt.h>
ISR(isrvector) {....}

Studio findet aber interrupt.h nicht mehr. Auch eine Dateisuche findet 
nichts.
Wie macht man das bei den SAMs - ohne ASF.
Würde mich riesig freuen, wenn mir jemand auf die Sprünge helfen würde.
Ist sicher ganz einfach, wenn man weis wie...

von Adam P. (adamap)


Lesenswert?

Elektolurch schrieb:
> #include <avr/interrupt.h>

Wie der Include Ordner schon sagt, das ist für AVR µC.
1
AVR != SAM

Musst mal deine Suchmaschine befragen:
- SAM interrupt without ASF (z.B.)
oder
- SAM bare metal example

http://mwmw.ca/index.html

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

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
}

von Stephan (Gast)


Lesenswert?

Hi,

was für ein Startup File ( .c oder .s ) benutzt du?

du hast dort vielleicht sowas:
1
void Dummy_Handler(void);    
2
/* Cortex-M0+ core handlers */
3
#pragma weak NonMaskableInt_Handler   = Dummy_Handler
4
#pragma weak HardFault_Handler        = Dummy_Handler
5
#pragma weak SVCall_Handler           = Dummy_Handler
6
#pragma weak PendSV_Handler           = Dummy_Handler
7
#pragma weak SysTick_Handler          = Dummy_Handler
8
9
__root const DeviceVectors __vector_table = {
10
        __sfe("CSTACK"),
11
        (void*) &Reset_Handler,
12
        (void*) &NonMaskableInt_Handler,
13
        (void*) &HardFault_Handler,
14
        (void*) (0UL), /* Reserved */
15
        (void*) (0UL), /* Reserved */
16
        (void*) (0UL), /* Reserved */
17
        (void*) (0UL), /* Reserved */
18
        (void*) (0UL), /* Reserved */
19
        (void*) (0UL), /* Reserved */
20
        (void*) (0UL), /* Reserved */
21
        (void*) &SVCall_Handler,
22
        (void*) (0UL), /* Reserved */
23
        (void*) (0UL), /* Reserved */
24
        (void*) &PendSV_Handler,
25
        (void*) &SysTick_Handler,
26
};

dann kannst du die einfach in einer anderen Datei überschreiben.
1
// file: meineInterrups.c
2
void SysTick_Handler( void )
3
{
4
 // mach was
5
}

Das funktioniert, da die Funktionen im Startup File als 'weak' definiert 
sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.