Hallo. Ich will, dass ich über einen interrupt etwas ausführe und dann aber nicht dorthin zurückspringe wo ich war sondern woanders hin. Hab mir das so gedacht ich könnte doch den Befehlszeiger, der beim auslösen des interrupts auf dem stack abgespeichert wird, mit pop befehlen "löschen" und mit push befehlen einen neuen wert auf den Stack tun. beim reti befehl springt er dann zur neuen Adresse. 1.Geht das so?? oder ist es einfacher den zeiger vom Stapel zu holen (2 mal pop) und am ende des interrupts mit sei die interrupts aktivieren und mit ijmp zur adresse in Z springen?? 2.Wenn ja in welcher reihenfoge müssen die high und low bytes auf den stack?? Danke im voraus. Gruß M.H.
M. H. schrieb: > 1.Geht das so?? Ja. > oder ist es einfacher den zeiger vom Stapel zu holen (2 > mal pop) und am ende des interrupts mit sei die interrupts aktivieren > und mit ijmp zur adresse in Z springen?? Wie du möchtest. > 2.Wenn ja in welcher reihenfoge müssen die high und low bytes auf den > stack?? Low zuerst, http://www.avr-asm-tutorial.net/avr_de/testjmp.html
ok. noch was muss ich nicht low(blabla*2) etc schreiben. Weil wenn ich z.B. ein LCD ansteuere und daten aus dem flash hole ( mit lpm) muss ich dass doch so machen.
Hi
>ok. noch was muss ich nicht low(blabla*2) etc schreiben.
Nein. Das ist eine 'Word'-Adresse.
MfG Spess
In C kann man das mit einem longjmp machen. Bloß hat das 1.000.000 Pferdefüße, sodaß in der Praxis niemand sowas macht, der bei Verstand ist. Sobald Dein Programm auch nur etwas größer als superwinzig wird, weißt Du nämlich nicht mehr, welchen Prozeß Du da gerade killst. Laß es z.B. ein LCD im 4-Bit Mode sein. Du killst es nach dem ersten Nibble und fürderhin zeigt es nur noch Bockmist an. Und so gibt es noch 1.000.000 Beispiele von Tasks, denen man nicht einfach die CPU unterm Hintern wegziehen darf. Die gebräuchliche Methode ist daher, ein Flag zu setzen. Dieses Flag signalisiert der gerade aktiven Task, sich geordnet zu beenden und zum Main zurück zu kehren. Oder es bewirkt einfach, das Ergebnis des letzten Task zu verwerfen. In der Regel kommt es bei einem Abort nicht auf die ms an, d.h. man läßt den aktuellen Task einfach zuende laufen. Peter
Vorsicht mit dem Entladen der Rücksprungadresse. Der ATmega256x hat 3-byte-PC. Hat mich mal böse erwischt.
Hm würd ich an deiner Stelle nicht machen, so ein Verhalten wird schnell unübersichtlich.
>Ich will, dass ich über einen interrupt etwas ausführe und dann aber >nicht dorthin zurückspringe wo ich war sondern woanders hin. Nein, Du willst damit ein Problem lösen und glaubst mangels Erfahrung, dass dies eine gute Lösung sei. Das ist sie aber sehr wahrscheinlich nicht, im Gegenteil. Auf jeden Fall handelst Du Dir mit diesem Konstrukt den Albtraum jedes Entwicklers ein, nämlich ein abstruses, unklares Programmdesign. Tipp: Das zugrundeliegende Problem beschreiben und nach der besten Lösung dafür fragen :-)
Hi Warum jetzt noch mal ins gleiche Horn tröten? Wenn man weiß was man macht, ist das durchaus legitim. Und diese Aussage resultiert nicht aus mangelnder Erfahrung. MfG Spess
spess53 schrieb: > Wenn man weiß was man > macht, ist das durchaus legitim. Die Erfahrung zeigt aber, daß diejenigen, die diese Frage stellen (und die kam hier schon öfter), üblicherweise nicht mal ansatzweise wissen, was sie da tun. Oliver
Wenn man weiss, was man macht stellt man die Frage nicht so. Das uebliche Vorgehen in dieser Richtung ist einen Scheduler zu schreiben. Sonst macht das keinen Sinn.
Was ist denn so unwichtig, dass man die Ausführung einfach so abbrechen kann? Das bräuchte man dann ja erst gar nicht ausführen ;-) Die Methode ist auf jeden Fall sehr dreckig/schlecht. Beispielsweise braucht das Beschreiben von einer 16-bit Adresse durchaus mehrere CKs
Hi >Die Erfahrung zeigt aber, daß diejenigen, die diese Frage stellen (und >die kam hier schon öfter), üblicherweise nicht mal ansatzweise wissen, >was sie da tun. Richtig. Aber manchmal ist selbst auf die Schn... zu fallen lehrreicher als tausend Hinweise. MfG Spess
spess53 schrieb im Beitrag #1746704 > Warum jetzt noch mal ins gleiche Horn tröten? Wenn man weiß was man > macht, ist das durchaus legitim. so lange man nur an irgend einer Stelle außerhalb der ISR was auf den Stack packt (und sei es nur durch Funktionsaufrufe), ist das Ganze tödlich. Wenn immer wieder mal weggesprungen ist, bevor der Stack wieder abgeräumt wurde, dann ist man irgend wann am Ende des Rams angekommen und läuft in einen Adressbereich, bei dem die CPU den den Zugriff mit Absturz quittiert.
Hi >so lange man nur an irgend einer Stelle außerhalb der ISR was auf den >Stack packt (und sei es nur durch Funktionsaufrufe), ist das Ganze >tödlich. >Wenn immer wieder mal weggesprungen ist, bevor der Stack wieder >abgeräumt wurde, dann ist man irgend wann am Ende des Rams angekommen >und läuft in einen Adressbereich, bei dem die CPU den den Zugriff mit >Absturz quittiert. Ach. Allerdings gehört das nicht in die Kategorie 'man weiss, was man macht'. Stackmanipulation ist bei höheren Progrmmiersprachen eigentlich eher die Regel. Warum sollte man es in Assembler dann nicht machen. Im Anhang mal ein sinnvolles Beispiel. MfG Spess
spess53 schrieb: > Stackmanipulation ist bei höheren Progrmmiersprachen eigentlich eher die > Regel. Das ist jetzt aber eine andere Baustelle > Warum sollte man es in Assembler dann nicht machen. Im Anhang mal > ein sinnvolles Beispiel. Aber selbst dein Beispiel manipuliert nicht die Rücksprungadresse. Die lässt man normalerweise tunlichst in Ruhe. Vuvuzelatus hat es exakt auf den Punkt gebracht.
Hi >Aber selbst dein Beispiel manipuliert nicht die Rücksprungadresse. Die >lässt man normalerweise tunlichst in Ruhe. Aber selbsverständlich wird die Rücksprungadresse manipuliert. Der UP-Aufruf gibt den 'String' der nachfolgenden 'db'-Direktive auf einem Display aus und das Programm geht nach dem 'db' weiter call print_str .db "abcde",0 und hier geht es weiter MfG Spess
spess53 schrieb: > Hi > >>Aber selbst dein Beispiel manipuliert nicht die Rücksprungadresse. Die >>lässt man normalerweise tunlichst in Ruhe. > > Aber selbsverständlich wird die Rücksprungadresse manipuliert. Der > UP-Aufruf gibt den 'String' der nachfolgenden 'db'-Direktive auf einem > Display aus und das Programm geht nach dem 'db' weiter OK. Das hab ich so übersehen. Hast du recht. Trotzdem ist dieser Fall nicht mit dem vergleichbar, den der Threadersteller im Sinn hatte. Ein Interrupt returniert dorthin zurück wo er herkam. Nur in ganz wenigen Ausnahmefällen kann man davon abgehen (weil zb. ein kompletter Systemreset notwendig ist). Und da greift dann etwas, was weiter oben schon angesprochen wurde: Wer weiß was er tut, braucht hier nicht fragen Wer hier fragen muss, hat noch nicht die Übersicht um zu wissen was er sich einhandelt.
spess53 schrieb: > Warum sollte man es in Assembler dann nicht machen. Im Anhang mal > ein sinnvolles Beispiel. Naja, hier würde es aber auch ein simples pop der Adresse vom Stack reichen + ein ijmp am Ende, ganz ohne Stackverbiegung. Wenn man aus einem Interrupt die Rücksprungadresse verbiegen will gibt es eigentlich nur zwei Möglichkeiten: 1) Stackpointer reset (da eh alles im Eimer ist) + rjmp, "Ziel" muß dabei ein Codetewil sein der nicht mit ret zurückkehrt... 2) sei + rjmp und das "Ziel" muß eine Funktion sein die per ret zurückkehrt. Fall 2 kann sinnvoll sein, wenn man nach einem Interrupt auf jeden Fall eine bestimmte Funktion ausführen will ohne die Interupts weiter zu sperren und dann erst wieder an die Ursprüngliche Stelle zurückzukehren. Ist aber höchst zweifelhaft, da man sich bei hoher Interruptfrequenz zwangsläufig weitere Probleme aufhalst.
Hi >Naja, hier würde es aber auch ein simples pop der Adresse vom Stack >reichen + ein ijmp am Ende, ganz ohne Stackverbiegung. Damit 'verbiegst' du aber Register. Und genau das soll vermieden werden. MfG Spess
spess53 schrieb: > Damit 'verbiegst' du aber Register. Und genau das soll vermieden werden. Mist du hast recht... Also in diesem Fall einfach den Z-Pointer als Arbeitsregister definieren ;)
Läubi .. schrieb: > Mist du hast recht... Also in diesem Fall einfach den Z-Pointer als > Arbeitsregister definieren ;) Und es hilft bei einem Interrupt genau wie, dass das als Scratchregister definiert ist? Läubi .. schrieb: > 2) sei + rjmp und das "Ziel" muß eine Funktion sein die per ret > zurückkehrt. Und damit hast du dann sauber die Flags zerstört, wenn das in einem Interrupt gemacht wird. Andreas
Eigentlich wie immer, wenn man versucht, besonders "trickreich" zu programmieren, es gibt jede Menge Teufel im Detail, die alle Schlange stehen, um einem auf den Fuss zu hüpfen. Es gibt sicher Einzelfälle, wo es mal nicht anders geht (Kontextswitch im Scheduler z.B.), ohne wirkliche Not sollte man sowas aber eher nicht machen. Andreas
Hi Manchmal ist es schön, euren Worten zu lauschen, während der Fragesteller längst zum Tagesthema abgewandert ist :) Gruß oldmax
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.