Forum: Compiler & IDEs IRQ Handler als Methode mit STM32?


von Stefan (Gast)


Lesenswert?

Hallo,

Mit dem AVRGCC kann ich wie folgt eine statische Methode an einen IRQ 
binden:

    static void serviceRoutine() __asm__("__vector_5") 
__attribute__((_signal_, _used_, _externally_visible_));

Geht so ein Konstrukt auch mit dem armgcc, im vorliegenden Fall mit 
einem STM32F030?

Stefan

von Jim M. (turboj)


Lesenswert?

Die Cortex M brauchen keine extra Deklaration für IRQ Handler, da geht 
das einfach über den Namen.

Das bedeutet leider auch das eine statische C++ Methode nicht direkt 
tut.
Du hast jetzt 2 Alternativen:

1. Funktionsaufruf der statischen Mehtode im eigentlichen Handler

2. Änderung der Verktortabelle - meist im Assembler deklariert - auf den 
korrekten Namen der statischen C++ Methode. Keine Ahnung wie das genau 
aussehen muss.


Ich würde eher zu 1 tendieren. Das ergibt eine zusätzliche Branch 
Instruktion, wenn die eine Rolle spielen würde hast du andere Probleme.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Einfach über den Namen. Der startup code von ST legt für jeden 
Vectortable-Eintrag ein weak symbol an. Sprich die Funktion gibt es dann 
schon und taucht auch in der Vector table als default auf, aber wenn Du 
Deine eigene definierst, dann nimmt der Linker Deine Implementierung.

Dem entsprechend findest Du auch die Namen aller ISR im Startup code. 
Die Funktionen haben C ABI und kein namemangling, solltest Du den code 
also mit einem C++ compiler übersetzen, musst Du die Funktion 
entsprechen mit extern "C" deklarieren.

Das kann man so eigentlich auf alle ARM controller übertragen.

von Axel S. (a-za-z0-9)


Lesenswert?

Das hängt entscheidend von deiner IDE/Toolchain ab. Bzw. davon, was der 
Startup-Code treibt. Wenn der Linker modern genug ist, um weak symbols 
zu unterstützen, dann ist das erwartbare Verhalten, daß die Vektor- 
tabellen mit Symbolen mit "magischen" Namen gefüllt werden. Also z.B. 
"sys_tick_handler" oder "tim2_isr". Gleichzeitig wird eine dummy-ISR 
implementiert und weak symbol aliases für alle diese magischen Namen 
registriert.

Wenn dein Programm nun eine Funktion mit einem derartigen Namen 
implementiert, dann findet der Linker das Symbol und ersetzt das 
gleichnamige weak symbol damit. Alle anderen Vektoren verweisen 
entsprechend auf die Dummy-Implementierung des Frameworks.

Langer Rede kurzer Sinn: du mußt die magischen Funktionsnamen heraus- 
finden und einfach passende C-Funktionen schreiben.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Axel S. schrieb:
> Langer Rede kurzer Sinn: du mußt die magischen Funktionsnamen heraus-
> finden und einfach passende C-Funktionen schreiben.

Diese stehen normalerweise in der startup-Datei, also zum Beispiel 
startup_stm32f4xx.S oder startup_stm32f10x.S:
1
                // External Interrupts
2
    .long    WWDG_IRQHandler                   // Window WatchDog
3
    .long    PVD_IRQHandler                    // PVD through EXTI Line detection
4
    .long    TAMP_STAMP_IRQHandler             // Tamper and TimeStamps through the EXTI line
5
    .long    RTC_WKUP_IRQHandler               // RTC Wakeup through the EXTI line
6
    .long    FLASH_IRQHandler                  // FLASH
7
    .long    RCC_IRQHandler                    // RCC
8
    .long    EXTI0_IRQHandler                  // EXTI Line0
9
    .long    EXTI1_IRQHandler                  // EXTI Line1
10
    .long    EXTI2_IRQHandler                  // EXTI Line2
11
    .long    EXTI3_IRQHandler                  // EXTI Line3
12
    .long    EXTI4_IRQHandler                  // EXTI Line4
13
    .long    DMA1_Stream0_IRQHandler           // DMA1 Stream 0
14
    ...
15
                // External Interrupts
16
    def_irq_handler    WWDG_IRQHandler                   // Window WatchDog
17
    def_irq_handler    PVD_IRQHandler                    // PVD through EXTI Line detection
18
    def_irq_handler    TAMP_STAMP_IRQHandler             // Tamper and TimeStamps through the EXTI line
19
    def_irq_handler    RTC_WKUP_IRQHandler               // RTC Wakeup through the EXTI line
20
    def_irq_handler    FLASH_IRQHandler                  // FLASH
21
    def_irq_handler    RCC_IRQHandler                    // RCC
22
    def_irq_handler    EXTI0_IRQHandler                  // EXTI Line0
23
    def_irq_handler    EXTI1_IRQHandler                  // EXTI Line1
24
    def_irq_handler    EXTI2_IRQHandler                  // EXTI Line2
25
    def_irq_handler    EXTI3_IRQHandler                  // EXTI Line3
26
    def_irq_handler    EXTI4_IRQHandler                  // EXTI Line4
27
    def_irq_handler    DMA1_Stream0_IRQHandler           // DMA1 Stream 0
28
    usw. usw.

: Bearbeitet durch Moderator
von W.S. (Gast)


Lesenswert?

Axel S. schrieb:
> Langer Rede kurzer Sinn: du mußt die magischen Funktionsnamen heraus-
> finden und einfach passende C-Funktionen schreiben.

..und sie mit dem passenden Attribut __irq versehen - bzw. dem 
GCC-Äquivalent zu diesem Attribut.

Sonst hält sich der Compiler nämlich an die 
Register-Verwendungs-Standards und rettet nicht alle Register. Das wird 
kribbelig, wenn bei M4F Gleitkomma sowohl im Basisprogramm als auch im 
Interrupt-Handler verwendet wird.

W.S.

von Jim M. (turboj)


Lesenswert?

W.S. schrieb:
> Sonst hält sich der Compiler nämlich an die
> Register-Verwendungs-Standards und rettet nicht alle Register. Das wird
> kribbelig, wenn bei M4F Gleitkomma sowohl im Basisprogramm als auch im
> Interrupt-Handler verwendet wird.

Das macht bei Cortex M nicht der Compiler, sondern der Prozessor selbst 
im Exception Entry. Und ja, auch bei Gleitkomma im M4F. Daher ist _irq 
für M-Profil Prozessoren überflüssig.

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.