Guten Morgen, erstmal hoffe ich, dass ich das richtige Forum erwischt habe, ansonsten tuts mir leid. Mit der Suchfunktion habe ich auch nicht wirklich was gefunden. Meine Ausgangslage: Ich benutze z.z. den LPC2103 und den CARM Compiler von Keil, dessen support wohl eingestellt wird ( jedenfalls hab ich es so verstanden ). Nun muss die ganze Sch**** RealViewCompiler-tauglich gemacht werden, eigentlich gar kein Problem... Mein Problem: Nested Interrupts, mit dem CARM Compiler war es schön möglich auf alle Register via Inline Assembler zu zugreifen, ist aber im RealView nicht mehr möglich. Nun hab ich div. Lösungsansätze ( Link Register über Variablen oder Register sichern )probiert, aber am Ende bin ich mitm Debugger immer in der AbortException gelandet. Dass man die ganzen Register ( eigentlich nur das Link sichern muss ) ist mir klar, aber mein Sicherungsmechanismus über statische Variablen ( Stackpointer wird zerschossen bei Operating Mode-Wechsel ) scheint auch nicht die Lösung zu bringen. Hat irgendwer eine Idee, wo der Fehler evtl. liegen könnte oder gar einen Lösungsansatz ? mfg Wolfgang
Irgendwo kommt mir das alles bekannt vor, noch vom eigenen Umstieg nach RealView... Bei Assembler-Inlining unter RealView mit Vollzugriff auf alle Register hilft nur noch die Einbeziehung des Embedded Assemblers. Näheres dazu kann man der RealView Compilerbeschreibung (µVision Help oder Books Window) entnehmen. Mit C-Sourcefiles kommt man unter RealView da nicht mehr weiter, jedenfalls nicht ich. Man muß die Inline-Assembler-Sequenzen zu Funktionen umbauen und in einer Datei mit Endung ".s" unterbringen (so wie auch z.B. Startup.s oder SWI.s). Hier wird der Zugriff auf Register, insbesondere SP, LR und PC, nicht mehr blockiert. Du bist im Grunde nur wenig mehr als 3 ARM-Instructions von der Lösung entfernt, und deine Idee, Sicherung der Returnadresse, ist das A und O. Darum poste ich mal eine vollständige Lösung als Anhang (Nested_IRQ.s), direkt zum Einbinden ins µVision-Projekt. Sie basiert auf den Makros aus den Hitex-Examples. Die Funktionen brauchen jetzt 4 Byte mehr IRQ-Stack pro Schachtelung (wegen eines zusätzlich benötigten und gesicherten Arbeitsregisters) und etwas mehr Laufzeit (wegen des zusätzlichen Rücksprung-Handlings) als die Makros aus den Hitex-Examples, das ist unter Umständen zu berücksichtigen. Die Funktionen sind auf einem Keil MCB2100 Eval-Board mit LPC2129 getestet. Trotzdem: Verwendung auf eigene Gefahr! Ein Vorschlag zur weiteren Verbesserung ist jederzeit willkommen. Gruß Dietmar
Dann sag ich erstmal vielen Dank. Ich werde es heute mal ausgiebig testen. Aber was mir auf dem ersten Blick auffällt: STMFD SP!, {R0} ; stelle ein Register zur Verfügung MOV R0, LR ; sichere darin die Returnadresse hiermit sicherst du doch eigentlich die Rücksprungadresse deines Funktionsaufrufs ? Entweder hab ich den Sinn vom LinkRegister noch nicht so ganz kapiert oder mir ist der Mechanismus beim ARM7 / Realview Compiler nicht geheuer.
>STMFD SP!, {R0} ; stelle ein Register zur Verfügung >MOV R0, LR ; sichere darin die Returnadresse >hiermit sicherst du doch eigentlich die Rücksprungadresse deines >Funktionsaufrufs ? So ist es! >Entweder hab ich den Sinn vom LinkRegister noch nicht >so ganz kapiert Das Problem ist hier ein ganz spezielles, da in der Funktion ein Modewechsel statt findet. Da funktioniert das Link-Register nicht mehr wie gewohnt, es wechselt mit der Modeumschaltung, LR_sys ist also nicht gleich LR_irq. Deshalb muß die Returnadresse anderswie erhalten bleiben, und wenn eben in einem anderen Register, welches nicht vom Modewechsel abhängig ist, meinetwegen R0. Jedenfalls benötigt man ein freies Register, entweder um die Returnadresse direkt zu retten oder um nach der Modeumschaltung noch an den IRQ-Stack heranzukommen, wenn man z.B. LR und R0 vorher dort gesichert hat. Mit dem benötigten Register (von mir gewählt: R0) bin ich noch nicht ganz im Klaren, wo und inwieweit dessen ursprünglicher Wert erhalten werden muß. Darauf, daß der Interrupt R0 compilerseitig sichert, kann man nicht vertrauen, das ist stark vom Interruptcode selbst und vom Compiler abhängig. Zur Zeit, wird R0 nur über die Nesting-Ebene hinweg gesichert. Es ist möglich, daß der Compiler eine im Interrupt benötigte Variable in R0 anlegt und über den gesamten Interruptverlauf hinweg erhalten bleiben muß. Da könnte es kritisch werden, wenn die Variable vor und hinter den Nesting-Umschaltungen benötigt wird. Sinnvollerweise setzt man die beiden Funktionsaufrufe daher am besten ziemlich an den Anfang und das Ende des Interruptcodes. Ich arbeite noch daran, die beiden Funktionen dahin gehend zu optimieren. Aber schneller, kürzer, und mit weniger Stackverbrauch, wird die Sache dadurch sicher nicht mehr!
Danke nochmals :) Ja das mit dem Modewechsel und verschiedenen Register war mir schon klar, ich hatte ja das ganze schon mit dem CARM Compiler fertig und wäre schon lang durch gewesen, aber leider musste ich feststellen, dass der Support für diesen Compiler eingestellt wurde.... Und weil ich in einem Manual gelesen hatte, dass man eben das Linkregister sichern muss, also das Linkregister_irq war ich irgendwie auf der Schiene, dass hier kein Funktioncall kommen kann/darf, da ja sonst mein Lr_Irq zerschossen wird.. Daher war mein erster Ansatz über: register UINT_32 Lr_Reg __asm("r14"); ... Leider konnte man beim IENABLE nur lesenden darauf zugreifen, frag mich warum... alles andere wurde im Disassembly zu NOP oder ein kopieren von r14 auf r14 ( sinnig.. )
@Wolfgang: Etwas Reflektion, ob das funktioniert hat, wäre ja ganz nett gewesen. Ich habe die Sache mit den Nested Interrupts mal ins ARM-Forum verlagert: Beitrag "Nested Interrupts mit Keil µVision mit RealView?" Gruß Dietmar
Sorry, war jetzt einige Tage lang nicht anwesend. Funktioniert prächtig bzw. ich hab bisher keine Fehler feststellen können. Vielen Dank nochmal
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.