Hallo! Ich habe leider mal wieder Schwierigkeiten, die ich nicht alleine lösen kann. Ich arbeite mit einem LPC2148 unter Eclipse mit GNU-ARM-Compiler. Ich möchte Nested Interrupts enablen. Ich habe die dazu nötigen Assemblerroutinen in mein Projekt eingebunden. Funktioniert prinzipiell alles. Leider landet mein µC bei der Befehlszeile "MSR CPSR_c, #0x1F" im Aborthandler. Ich habe allerdings im ARM Instruction Set gelesen, dass es möglich ist direkt HEX-Zahlen mit MSR zu verschieben. Das wird ja auch von vielen so genutzt. Was mir aber sehr zu denken gibt ist die Tatsache, dass mein Code nach dem # grün eingefärbt wird, was ja bei vielen IDEs bedeutet, dass es als Kommentar gesehen wird. Dementsprechend lade ich dann ja nix in CPSR_c rein und somit wäre der Absturz gerechtfertigt. Ich finde nur leider nirgends einen anderen Ansatz wie ich 0x1F direkt ins PSR bekomme. Weiß jemand eine Lösung für mein Problem? Bin für alle Tipps und Tricks dankbar! Mfg Jansus
Mit dem Stand an präsentierter Information wird das nix. Und daher bringt auch eine Wiederholung der Frage nichts.
Hmm, ja war schon bisschen mager. Sorry! Was ist denn alles von nöten, um was sagen zu können? Hier das Assembler-File, mein Startup-File ist im Anhang: .section .text ,"ax" .arm .global nested_irq_enable .global nested_irq_disable .func nested_irq_enable nested_irq_enable: /* Nested Interrupts Entry*/ STMFD SP!, {R0} /* stelle ein Register zur Verfügung*/ MOV R0, LR /* sichere darin die Returnadresse*/ MRS LR, SPSR /* sichere SPSR_irq über LR_irq*/ STMFD SP!, {LR} /* auf dem IRQ Stack*/ MSR CPSR_c, #0x1F /* Modewechsel IRQ - SYS, Freigabe IRQ*/ STMFD SP!, {LR} /* Sichere LR_sys auf dem User Stack*/ BX R0 /* Return zur IRQ-ISR*/ .endfunc .func nested_irq_disable nested_irq_disable: /* Nested Interrupts Exit*/ MOV R0, LR /* sichere Returnadresse in Register*/ LDMFD SP!, {LR} /* stelle LR_sys vom User Stack wieder her*/ MSR CPSR_c, #0x92 /* Modewechsel SYS - IRQ, Sperrung IRQ*/ LDMFD SP!, {LR} /* Wiederherstellung*/ MSR SPSR_cxsf, LR /* des SPSR_irq*/ MOV LR, R0 /* lade Rücksprungadresse*/ LDMFD SP!, {R0} /* stelle R0 wieder her*/ BX LR /* Return zur IRQ-ISR*/ .endfunc
Mein GNU-Port der NXP-Beispielsammlung ist möglicherweise hilfreich. Download von http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/lpc2k_bundle_port/index.html von Interesse dürfte v.a. der Code in Startup.S sein. Ansonsten wie Andreas Kaiser schon schrieb: zu wenig Information. Am Besten Minimalbeispiel erstellen, das das Fehlverhalten demonstriert. Mit allen notwendigen Dateien (linker-script, makefile, Quellcode) irgendwo auf einen Server legen oder als Attachment zu einem Forenbeitrag hier. Martin Thomas
In crt.s kann ich keine Initialisierung vom Sys/Usr Modus erkennen. Der Code läuft also im SVC-Modus. Wenn der Handler dann in den Sys-Modus wechselt ist kein gültiger Stack vorhanden. PS: Code ist als Anhang lesbarer, alternativ als avrasm taggen. Der Umbruch stört halt sehr.
In meinem Programm wird per Interrupt folgende Funktion aufgerufen: void extint0(void) { EXTINT = 0x00000001; nested_irq_enable(); extintcounter++; // hochzählen nested_irq_disable(); VICVectAddr = 0; } Hier die Funktion nested_irq_enable (so hier im Forum gefunden): nested_irq_enable: /* Nested Interrupts Entry*/ STMFD SP!, {R0} /* stelle ein Register zur Verfügung*/ MOV R0, LR /* sichere darin die Returnadresse*/ MRS LR, SPSR /* sichere SPSR_irq über LR_irq*/ STMFD SP!, {LR} /* auf dem IRQ Stack*/ MSR CPSR_c, #0x1F /* Modewechsel IRQ - SYS, Freigabe IRQ*/ STMFD SP!, {LR} /* Sichere LR_sys auf dem User Stack*/ BX R0 /* Return zur IRQ-ISR*/ In der Zeile MSR CPSR_c, #0x1F hängt sich mein Controller auf.
Dumme Frage: Was ist der SVC-Modus? Und wie kann ich die einzelnen Modi im Startup initialisieren? P.S.: Der nächste Code folgt ordentlich. Verprochen!
Apropos aufhängen: Debugging per JTAG ist ganz nett, aber manchmal sind LEDs als Statusanzeige hilfreicher. Speziell dann, wenn nicht sicher ist, ob das Problem genau da liegt wo es angezeigt wird, oder man möglicherweise von einer Interferenz zwischen Debugger und System geleimt wird. An dem MSR kann ich nämlich kein Problem erkennen. Aber dieser Befehl ermöglicht weitere Interrupts (eben das nesting), was den Schluss nahelegt, dass eher dort das Problem liegt.
> Dumme Frage: Was ist der SVC-Modus?
Manual Not Read Error.
RTFM.
Hmm, da hast Du mich erwischt! Hab das Manual schon gelesen. Nur nach den 3xx Seiten weiß ich auch nimmer alles. Supervisor Mode, oder? Ich habe also für den User Mode den Stack initialisiert.
1 | MSR CPSR_c, #ARM_MODE_USER|I_BIT|F_BIT /* Interrupts disabled */ |
2 | ldr SP, __stack_usr_end |
Keine Sorge, den dafür nötigen Rest habe ich auch erledigt. Leider funktionieren jetzt überhaupt keine Interrupts mehr. Ich dachte mit den Zeilen hier hätte ich Interrupts angeschaltet. [avrasm]MRS r0, CPSR BIC r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ MRS CPSR, r0 [/arvasm] Ist das jetzt nutzlos geworden? Wäre es auch denkbar, dass ich gleich bei der Initialisierung die Interrupts enable, also I_BIT und F_BIT nicht setzte? Oder ist es sinnvoller wie in den Beispielen von Martin Thomas das erst im laufenden Betrieb zu machen?
Zwei Möglichkeiten hattest du. Eine richtige, eine falsche... Im User-Mode kannst du die Interrupts nicht kontrollieren. Keine Rechte. Ich pflege Interrupts erst einzuschalten, wenn die Initialisierung durch ist. Vermeidet Überraschungen. Die meisten anderen scheinen es ebenso zu halten.
Gibt's eigentlich einen Trick um zu verhindern, dass sich OpenOCD in 90% aller Startversuche aufhängt?
Sorry. Meinte GDB. Wenn ich es starte, hängt sich entweder Eclipse auf, oder es kommt die Fehlermeldung "Stack is not available". Ziemlich frustrierend...
In einem Anflug von Funktion konnte ich mal wieder debuggen. Und siehe da, es klappt ohne Absturz! Und wiedereinmal kann ich nur sagen: Vielen Dank! Echt klasse! Hoffentlich komme ich bei zukünftigen Problemen mal selbst drauf. Gibt es eigentlich noch mehr Tücken, die sich im Startup verstecken? Wegen dem ständigen Aufhängen. Ich verwende diesen Befehlssatz (vielleicht ist das dran schuld?): target remote localhost:3333 monitor reset monitor sleep 500 monitor poll monitor soft_reset_halt monitor arm7_9 sw_bkpts enable monitor mww 0xE01FC040 0x0002 monitor mdw 0xE01FC040 break main load continue
So, habe alles neu installiert und jetzt klappt's. Ich habe nun folgendes Rätsel: Wenn ich einen Breakpoint an den Anfang meiner Interruptroutine setze, erlebe ich den Einsprung und anschließend läuft mein Programm auch völlig normal weiter. Wenn ich den Breakpoint nun weglasse, den Interrupt auslöse und dann im Debugger nachsehe, wo ich gelandet bin, stelle ich fest, dass ich im PAbortHandler stecke. Das kann doch irgendwie nicht sein, oder? Wenn es mal wieder so ein Anfängererror (vgl. Manual) sein sollte, sagt mir das bitte, aber irgendwie bin ich ratlos. Habe bisher nur C16x programmiert und solche Erlebnisse waren da irgendwie nicht an der Tagesordnung. Bin wie immer für alle Ratschläge dankbar!
Zur Ergänzung: Linkerskript im Anhang. Debugge im RAM. Flash ist leer.
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.