Per Interrupt aus der Hauptschleife ein-/aussteigen

Gast #340459
Lesenswert?

hi,

in meinem programm läuft normalerweise die Hauptschleife, in der
Messungen vorgenommen und abgespeichert werden.
nun möchte ich aber auf best. bytes des USART aus dieser Schleife
aussteigen bzw. dann wieder einsteigen können.
Aber im Tutorial steht was von 'Jede Interrupt-Routine muss mit reti
abgeschlossen werden, weil sich sonst der Stack zumüllt.'
Und mit reti komme ich genau wieder zurück an die Stelle in der
Hauptschleife, wo der Interrupt aufgetreten ist.

Wie kann ich trotzdem irgendwie auf die Hauptschleife Einfluss nehmen?

mfg, Johannes
Gast #340464
Lesenswert?

@ karl heinz:
was muss man den genau machen um die nicht mehr benötigten
rücksprungadressen zu elimienieren? ich hatte auch schon öfters
probleme damit und mich würde es schon interisieren wie das geht.
ich meine in asm.

luxx
Gast #340465
Lesenswert?

@luxx:

Naja, Da wo das "reti" stehen würde, einfach den PC vom Stack poppen
und dann direkt dort hin springen.

Wenn Du in C programmierst, musst Du Dir eigene Prologs und Epilogs
bauen, damit das mit dem Rest des Codes funktioniert.

Am besten erst mal in Assembler üben.
Gast #340466
Lesenswert?

Am einfachsten sind zwei pop Befehle, damit kommt der Stackpointer auf
den Zustand vor dem Interrupt. Man kann natürlich auch den Stackzähler
um zwei ändern, aber das kostet mehr Aufwand.
Das Progrmm wird durch solche üblen Tricks allerdings sehr
unübersichtlich, eine Kommunikation über Semaphore ( "Leuchtzeichen")
oder Flags, was dasselbe ist, ist die anständige Methode. Am einfachsten
über das T-Flag, wenn man nur ein Bit an Information braucht.
Gast #340467
Lesenswert?

Also das mit dem direkten Rücksprung mit (r)jmp wird früher oder später
in einem Stackoverflow enden. (Im schlimmsten Falle landet der Stack
irgendwann in den IO Registern)
Mit dem Polling ist auch keine gute Lösung. Entweder frisst sie extrem
CPU Zeit oder es wird zu selten abgefragt.
Deshalb ist es mit interupt "eleganter zu lösen"

Da du ja im Prinzip drei Fälle hast,
A)- Normale Funktion
B)- UART hat das falsche byte empfangen
C)- UART hat ein richtiges Byte empfangen

Ich würde es so machen:
UART RX Complete Interrupt aktivieren.

In der ISR dann erstala die Entscheidung ob das empfangene Byte eines
der best. Bytes ist.
Wenn nein dann reti
Wenn ja, dann zwei bytes aus dem stack poppen (irgenwohin, du brauchst
diese nicht mehr) und die gewünschte Rücksprungadresse in den den Stack
pushen. (Achtung Bytereihenfolge beachten)
Danach das machen was du mit dem best. Byte machen wolltest und am Ende
wieder nen reti.

Nun warum nicht einfach raus poppen und am ende mit (r)jmp zurück?
Zum Einem: weil oft das SEI vergessen wird.
Zum Zweiten: weil man viele Sachen von Fall B und Fall C
(wiederherstellen vom Flags und Variablen) gleichzeitig verwenden kann
und beide fälle mit Einem reti abgeschlossen werden
Zum Dritten: Viele Simulatoren auf denen man seine code vorher testet,
reagieren allerisch auf call/pop/pop/jmp und zeigen dir trotdem nen
stackoverflow an.

bis dann
Hauke

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren