www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupts


Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Dietmar (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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!

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.. )

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Dietmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, war jetzt einige Tage lang nicht anwesend. Funktioniert prächtig 
bzw. ich hab bisher keine Fehler feststellen können.

Vielen Dank nochmal

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.