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
Du setzt im Interrupt einfach eine (globale) Variable (bei c als volatile deklarieren) und fragst diese dann in der Mainloop ab, Gruß Andreas
Du hast 3 Möglichkeiten: - die von Andreas - In der Hauptschleife einfach das Interrupt-Flag zu überprüfen und gar keine ISR zu erlauben - wenn in Assembler: beim Interruptvektor direkt mit (R)JMP zu dem Teil zu springen
danke euch, ich denke eine lösung wird dann schon passen ^^
> - wenn in Assembler: beim Interruptvektor direkt mit (R)JMP zu dem > Teil zu springen Das ist keine Lösung. Zumindest nicht für einen Neuling der noch keine Ahnung hat, was er da alles am Stack anrichtet und welche Schritte er unternehmen muss um das wieder alles ins Lot zu bringen.
@ 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
@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.
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.
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
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.