Forum: Mikrocontroller und Digitale Elektronik AT91SAM7S256 und Nested Interrupts


von Marc X. (tuxscreen)


Lesenswert?

Hallo zusammen,

ich habe auf der Basis des Atmel CDC Beispiels ein kleines Projekt 
entwickelt, welches noch mehrere Interruptroutinen beinhaltet (UART, 
SSC, PIO-Pin).

Das Projekt nutzt den Standard startup code von Atmel, welcher meines 
Wissens nach alle Interrupts "nested" ausführt:

<code>
/* Branch to interrupt handler in Supervisor mode */
        msr     CPSR_c, #ARM_MODE_SVC | F_BIT  //| I_BIT
        stmfd   sp!, {r1-r3, r4, r12, lr}
        mov     lr, pc
        bx      r0
        ldmia   sp!, {r1-r3, r4, r12, lr}
        msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
</code>

Die Atmel-Library implementiert alle Interrupt Routinen (in C) ohne 
irgendwelche Vorkehrungen. Also kein attribute naked, interrupt oder 
irq...
Daran habe ich mich auch gehalten.

Weiterhin habe ich hier und da den Tip gefunden den Code mit der gcc 
Option (-O3) zu generieren -> auch keine Änderung.

Mein Problem ist, das nach einer gewissen Zeit scheinbar mein Stack 
defekt
ist. Die Symptome, die ich sehe, sind das mein Code in main() [hier 
läuft nur noch eine Debug-Console auf DBGU] nicht mehr ausgeführt wird. 
Der USB-Receiver hängt sich meistens auch direkt mit weg. Die Ausgaben 
der "anderen" IRQs auf den DBGU laufen jedoch. Die CPU hat also keinen 
Abort oä.

Weiteres Problem ist, das diese Effekte erst nach mehreren Stunden 
Laufzeit auftreten.

Weiteres Problem ist, das mein Code nur mit nested Interrupts lauffähig 
ist, da mir ansonsten der USB-Interrupt mehr oder minder das gesamte 
System blockiert.

Ich habe schon den gesamten Speicher mit 0xdeadbeef vollgeschrieben und 
getestet ob sich hier etwas ändert, oder sich die Stackgrenzen über 
Gebühr ändern. Kein Resultat.



Hat jemand von Euch eine Idee, was ich noch testen, programmieren oder 
ändern kann?

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Erstmal vorweg: Ich habe mit diesem Code noch nicht gearbeitet und 
bestätige auch nicht, dass das Problem ursächlich vom IRQ Handler 
hervorgerufen wird :-)

Marc Wetzel schrieb:
> Das Projekt nutzt den Standard startup code von Atmel, welcher meines
> Wissens nach alle Interrupts "nested" ausführt:

Es scheint so.

> <code>
> /* Branch to interrupt handler in Supervisor mode */
>         msr     CPSR_c, #ARM_MODE_SVC | F_BIT  //| I_BIT
>         stmfd   sp!, {r1-r3, r4, r12, lr}
>         mov     lr, pc
>         bx      r0
>         ldmia   sp!, {r1-r3, r4, r12, lr}
>         msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
> </code>

Das hier ist natürlich nur ein Auszug des IRQ handlers. Bitte beim 
nächsten Mal vollständig. Die Atmel Bibliothek ist so dämlich 
organisiert, dass man das nicht so leicht findet.

> Die Atmel-Library implementiert alle Interrupt Routinen (in C) ohne
> irgendwelche Vorkehrungen. Also kein attribute naked, interrupt oder
> irq...

Richtig, da der top-level handler den Kontext einer Funktion herstellt.

> Mein Problem ist, das nach einer gewissen Zeit scheinbar mein Stack
> defekt
> ist. [...]
> Hat jemand von Euch eine Idee, was ich noch testen, programmieren oder
> ändern kann?

Ohne Garantie auf Erfolg würde ich empfehlen, das Löschen/Setzen der I 
und F Flags vom Umschalten in SVC/IRQ zu trennen:
1
         msr     CPSR_c, #ARM_MODE_SVC | I_BIT
2
         stmfd   sp!, {r1-r3, r4, r12, lr}
3
         msr     CPSR_c, #ARM_MODE_SVC & ~I_BIT
4
         mov     lr, pc
5
         bx      r0
6
         msr     CPSR_c, #ARM_MODE_SVC | I_BIT
7
         ldmia   sp!, {r1-r3, r4, r12, lr}
8
         msr     CPSR_c, #ARM_MODE_IRQ | I_BIT

Viel Erfolg
Marcus

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.