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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.