www.mikrocontroller.net

Forum: Compiler & IDEs goto bei Interrupt


Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ist es möglich, das beim Ausführen eines Interrupts ein goto auf eine 
Stelle im main ausgeführt werden kann?

Gruß
Richi

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich versteht zwar nicht was du machen willst, aber lasse es lieber 
bleiben mit dem goto - das ist nur in sehr seltenen Fällig notwendig.

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Technisch bestimmt... Praktisch fällt mir da gerade kein sinnvoller 
Grund ein...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein

Prinzipiell gibt es die Möglichkeit, in C mit setjmp (z.B. in main())
einen Zustand einzufrieren, zu dem (von einem Punkt darunter in der
Aufrufebene) wieder mit longjmp() zurückgesprungen wird.
Aber das ist ohnehin kriminell, und wird sicher nicht klappen,
wenn das longjmp() in einem Interrupt aufgerufen wird.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ist es möglich, das beim Ausführen eines Interrupts ein goto auf eine
> Stelle im main ausgeführt werden kann?

Du möchtest also, daß deine Hauptroutine irgendwo an einer unbekannten 
Stelle unterbrochen und dann wo ganz anders fortgesetzt wird? Wie solte 
das auch nur halbwegs sauber funktionieren, und vor allem:  Wozu?

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Ziel:

Wird ein bestimmter Taster(INT0) aktiviert, rappelt der Interrupt los 
und das soll Programm wieder an eine bestimmte Stelle anfangen.

Es ist sozusagen ein Resettaster, nur dass nicht von vorne sondern in 
der Mitte mit der ausführung des Programms begonnen wird.

Noch ein Tipp: Ich arbeite in C

Gruß
Richi

Autor: Gast5343245 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hinspringen mag ja noch klappen, aber wie zurueck an die richtige Stelle 
kommen?

Gast

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht mir ja nur darum, dass wieder von der "Resetstellung" begonnen 
wird, die andere Richtung wird nicht benötigt.

Autor: egast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Sprung aus der Interruptroutine nach main lässt sich zwar 
programmieren, auf dem Stack bleibt aber die Adresse des Rücksprungs 
zurück (eventuell mit weiteren Parametern). Nach einigen Sprüngen läuft 
dann der Stack über und das Programm stürzt dann ab.
Geht also so nicht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
> Es geht mir ja nur darum, dass wieder von der "Resetstellung" begonnen
> wird, die andere Richtung wird nicht benötigt.

Doch die wird benötigt :-)
Du siehst sie nur nicht.
Wenn der Interrupt aufgerufen wird, wird allerhand intern am Stack 
abgelegt. Dieser Stack muss wieder aufgeräumt werden. Wird aber die ISR 
nicht auf regulärem Wege beendet, passiert das nicht.


Mach deine Programmstruktur richtig, dann brauchst du derartige 
Klimmzüge nicht.
Im Interrupt wird eine Markierung gesetzt und im Hauptprogramm wird 
regelmässig nachgesehen ob die Markierung gesetzt wurde und wenn ja 
fährt sich das Programm wieder in seine Startkonfiguration. Dann hast du 
auch nicht das Problem, dass dir der Benutzer mit einem Tastendruck 
mitten in eine kritische Operation reinfunkt, sondern kannst gezielt und 
auch sicher auf den Tastendruck reagieren.

Autor: Wolfgang Schmidt (wsm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei jedem Rücksprung mir Goto bleib die beim Interrupt gespeicherte 
Rücksprungadresse auf dem Stack und der Stäck ist irgendwann voll=läuft 
über.

Deine Struktur ist falsch.

Schreibe alles! was beim Interrupt gemacht werden soll in! dein 
IRQ-Programm.

wsm

Autor: Toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Sichere Methode den Stack zum Überlauf zu bringen!!!!!

Der Interrupt legt los, springt ins Main, macht dort irgendwas und 
dann???

Auf dem Stack liegen doch die geretten Register und die Rückkehradresse!
Was geschieht mit denen? Irgendwann steht der Stackpointer am Anschlag!

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dann hast du
> auch nicht das Problem, dass dir der Benutzer mit einem Tastendruck
> mitten in eine kritische Operation reinfunkt

Genau das will ich aber!!!

Kann man denn nicht in der Interruptrutine das, was diese zuvor in den 
Stack geschrieben hat löschen, und dann springen?

Autor: egast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am besten in der ISR ein Flag setzen, welches im Hauptprogram abgefragt 
wird und dann die gewünschte Aufgabe ausführt

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach meinem Verständnis von setjmp/longjmp bei gcc merkt sich dieser 
tatsächlich ein Stack-Frame, zu dem er bei longjmp zurückkehrt, wobei 
der Teil darunter "discarded" wird.

So verrückt die Idee ist, sie könnte klappen,  Was nicht klappen wird, 
ist die Wieder-Freigabe des Interrupts (das I-Flag).  Ich denke nicht, 
dass C sich darum kümmert.

Dennoch sträuben sich bei mir sämtliche Nackenhaare.  So etwas lässt 
sich auch sauber lösen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
>> Dann hast du
>> auch nicht das Problem, dass dir der Benutzer mit einem Tastendruck
>> mitten in eine kritische Operation reinfunkt
>
> Genau das will ich aber!!!

Dann programmiere in diese kritische Operation die entsprechende Abfrage 
des Merkers hinein und dokumentiere so ausdrücklich, dass du das an 
dieser Stelle erlaubst.

By the way:
Mit kritischer Operation meine ich nicht eine etwas länger andauernde 
Operation. Mit kritischer Operation meine ich zb das zeitliche 
Widerabschalten von Lampen die wegen einem Multiplex eigentlich mit 
zuviel Strom für den Dauerbetrieb angefahren werden. Wenn nach dem 
Einschalten das Abschalten nicht nach einer definierten Zeitdauer 
erfolgt, dann gibt es einen Hardware-Schaden. Und jetzt rate mal, was 
wohl passiert wenn deine ISR aufgerufen wird, wenn zwar schon 
eingeschaltet, aber noch nicht abgeschaltet wurde und sich dein Programm 
irgendwo hin verkrümelt und erst mal seine Zeit damit verplempert zb das 
LCD neu zu initialisieren.
Oder eine Pumpe wird eingeschaltet und muss definiert wieder 
ausgeschaltet werden oder ...
Das meint man mit kritischen Operationen: Operationen die unter allen 
Umständen hintereinander ausgeführt werden müssen. Egal was passiert.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann man denn nicht in der Interruptrutine das, was diese zuvor in den
> Stack geschrieben hat löschen, und dann springen?

Man kann theoretisch die Rücksprung-Adresse durch eine andere 
überschreiben. Allerdings wird das trotzdem nicht richtig funktionieren, 
weil dein Hauptprogramm ja nicht darauf vorbereitet ist, daß da von 
außen irgendwo mitten rein gesprungen wird.
Lass es bleiben. Es ist ein Hack übelster Sorte.

Autor: Wolfgang Schmidt (wsm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stackinhalte können in asm mit pop zurückgeholt werden.

Also einfach den überflüssigen Stackinhalt zurück-popen.

Es stellt sich nur die Frage, wieviel byte dies sind und ob auch noch 
Register gepusht wurden?

wsm

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ständige Abfragen wäre eine Notlösung, finde ich aber doof.
Denn wenn ich in jeder Zeile zuerst eine Abfrage tätigen muss, ist das 
nicht gerade Arbeitsunaufwändig.

Ich will einfach nur eine art Resettaster, nur dass das Programm dann 
nicht neu gestartet sondern an einer anderen stelle weiter macht.

Gruß
Richi

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
man könnte aber auch den Return adresse auf dem Stack mit der Adresse 
vom goto ziel überschreiben. Am ende der ISR springt er dann an die 
gewünschte stelle. (ich würde es aber selber bestimmt nicht so machen)

Autor: Wolfgang Schmidt (wsm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@richi

.... das kannst du doch auch mit case o.ä erreichen

wsm

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
> Das ständige Abfragen wäre eine Notlösung, finde ich aber doof.
> Denn wenn ich in jeder Zeile zuerst eine Abfrage tätigen muss, ist das
> nicht gerade Arbeitsunaufwändig.

Halb so wild.
In einem durchschnittlichen Programm sind das viel weniger Stellen als 
du jetzt denkst. Und von "Bei jeder Zeile" kann ja im Regelfall nicht 
die Rede sein. Bei Schleifen muss man ein wenig abwägen, wie lange die 
Schleife laufen wird und den Tastenabbruch mit in die Schleifenbedingung 
mit einbauen, aber abgesehen davon: Es reicht völlig, wenn dein Programm 
zeitlich gesehen, so alle 1ms den Merker abfragt. 1ms ist für einen µC 
eine halbe Ewigkeit. Für den Menschen hingegen, der den Taster drückt, 
ist das unglaublich kurz. Und ob dein µC 1ms früher oder später auf den 
'Notaus' reagiert, spielt so gut wie keine Rolle, weil dein Bediener den 
Tastendruck sowieso nicht genau genug timen kann.

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber was ist wenn mein Programm nicht durchschnittlich ist?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
> Aber was ist wenn mein Programm nicht durchschnittlich ist?

Warum bloss wundert mich dieser Erwiderung nach dieser Fragestellung 
nicht mehr :-)

Na was hast du denn so Spezielles, dass es sich nicht lohnt den Saustall 
erst mal aufzuräumen anstelle da noch ein Schäuflein draufzulegen?

Hmm. Irgendwie beschleicht mich da jetzt so ein komisches Gefühl :-)

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich suche einfach nur nach einer einfacheren Lösung.
Aber anscheinend gibt es keine.

Gruß
Richi

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe den Eindruck, daß dein Programm schon den falschen Ansatz 
benutzt und du jetzt unter den Konsequenzen davon leidest. Ich kann mir 
irgendwie nicht vorstellen, daß dein Programm so speziell und 
ungewöhnlich ist, daß es nun wirklich gar nicht anders geht.

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht ja mit der "ständig Abfragen Methode".

Aber wenigstens weiß ich, dass es jetzt nicht wirklich anders geht.

Danke an alle Mitwirkenden!

Gruß
Richi

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich will einfach nur eine art Resettaster, nur dass das Programm dann
>nicht neu gestartet sondern an einer anderen stelle weiter macht.

Was wohl "nicht neu gestartet" und "eine Art Resettaster" bedeuten mag? 
Wie auch immer: mgl. Würgaround - zumindest ohne *jump-Gemurks: In 
"INT0"-ISR: Watchdog-Timer (sofern vorhanden) einschalten (wenn nicht 
schon an), Endlosschleife in ISR bis Watchdog-Auslösung -> 
Watchdogs-Reset d. HW. Zu Beginn von main() Reset-Ursache in einem der 
Register des bis dato nicht genannten Controllers  abfragen: if 
(reset_ursache_watchdog) andere_stelle(); // sonst halt nicht "andere 
stelle"...

Aber statt solch einem Krampf "Noch ein Tipp": Zustandsautomat. Dann 
reicht eine Statusabfrage in der Hauptschleife, die zwar auch "ständig 
augerufen" wird, aber nur einmal zu implementieren ist. Nicht lange in 
den State-Functions hertrödeln (analog ISRs), dann wird der Tastendruck 
bzw. die Änderunge des in der "INT0"-ISR gesetzten Flags auch schnell 
erkannt.

>Aber was ist wenn mein Programm nicht durchschnittlich ist?

Kann aber natürlich sein, dass ein Zustandautomat für das "nicht 
durchschnittliche" Programm zu durchschnittlich ist...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> Nach meinem Verständnis von setjmp/longjmp bei gcc merkt sich dieser
> tatsächlich ein Stack-Frame, zu dem er bei longjmp zurückkehrt, wobei
> der Teil darunter "discarded" wird.

Natürlich balanciert setjmp/longjmp den Stack aus, wie alle 
C-Funktionen.
Im AVR-GCC restauriert es auch den Interrupt-Enable-Status.
In C braucht man sich um den Stack nicht zu kümmern, der Compiler ist in 
der Pflicht, ihn sauber zu halten.

> So verrückt die Idee ist, sie könnte klappen

Sie klappt. Trotzdem wird es nur selten verwendet, da es die 
Programmstruktur zerstört. D.h. solche Programme sind unübersichtlich, 
fehlerträchtig und schwer wartbar, erweiterbar.

Es ist natürlich nicht schlimm, wenn irgendwelche Berechnungen abgewürgt 
werden.
Dafür gehen aber fast alle Hardwarezugriffe in die Hose. Z.B. I2C, UART, 
SPI mögen sowas garnicht, wenn Pakete zerstört werden und halb 
gesetzte/gelesene 16Bit-Timer, ADCs können die wunderlichsten Effekte 
bewirken.

Ich muß auch zustimmen, ich habs noch nie gebraucht.

Reaktionen innerhalb 300ms auf nen Tastendruck werden vom Menschen als 
sofort empfunden. Es ist also unsinnig, um 10ms zu kämpfen und man kann 
ruhig alle gerade laufende Prozesse geordnet abschließen.

Ich arbeite oft mit einer Mainloop, deren maximale Durchlaufzeit <200ms 
ist. D.h. ein Notaus muß nur einmalig in der Mainloop abgefragt werden.
Länger als 200ms dauernde Sequenzen werden über einen Sequenzer 
(Statemachine) häppchenweise durchlaufen.
Natürlich wird die Taste mit einem Timerinterrupt entprellt und gemerkt, 
kann also nicht verloren gehen, wenn jemand nur 100ms kurz draufhaut.


Peter

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wobei 200ms bei einem Notaus schon lang sind. Vielleicht reichts noch 
für die subjektive Wahrnehmung, dass nach dem Tastendruck "sofort" was 
passiert. Spätestens im Schadensbild ist die Verzögerung dann aber je 
nach Umständen objektiv feststellbar.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der mechatroniker schrieb:
> Wobei 200ms bei einem Notaus schon lang sind. Vielleicht reichts noch
> für die subjektive Wahrnehmung, dass nach dem Tastendruck "sofort" was
> passiert. Spätestens im Schadensbild ist die Verzögerung dann aber je
> nach Umständen objektiv feststellbar.

Das glaub ich nicht.
Kein Mensch kann innerhalb von 200ms auf eine Fehlersituation mit einem 
Druck auf Notaus reagieren.
Das dauert seine Zeit und da spielen dann 200ms mehr 'Reaktionszeit' 
auch keine große Rolle mehr, wenn die Maschine vorher schon 2 Minuten 
gequalmt hat.

(Wobei 200ms schon extrem lang sind. Wenn man sich nicht allzu 
ungeschickt anstellt, dann ist diese Zeit locker auf 20ms oder weniger 
zu drücken)

Ich glaube eher, wir haben wieder mal die Situation:
Verbocktes Programm, dass irgendwann hängt. Sprich: ein Programmfehler. 
Und der 'Notaus' soll jetzt wieder mal alles richten.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  der mechatroniker (Gast)

>Wobei 200ms bei einem Notaus schon lang sind.

Notaus per Software? Hust besser nicht . . .

MFG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Fairness halber muss man allerdings sagen, dass der TO nie von einem 
Notaus gesprochen hat.
Es geht um einen 'Resettaster'.

Autor: Ohne Aufwand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich ein goto aus einem Interrupt irgendwohin springen wollte, dann 
mache ich das!

Stackpointer neu setzen, I-Flag löschen und was sonst noch in den 
Grundzustand gebracht werden muß. Fertig.
Warum sollte ich mich zieren? Wenn ich ein Gerät auschalten will, dann 
mache ich das auch, wann ich will.

Autor: Ohne Aufwand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur:
>Wenn ich ein goto
Wenn ich mit einem goto ...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne Aufwand schrieb:
> Warum sollte ich mich zieren? Wenn ich ein Gerät auschalten will, dann
> mache ich das auch, wann ich will.

Du darfst gerne Deinen Tintendrucker mitten im Druckjob ausschalten.
Denn Du bist es, der den eingetrockneten Druckkopf wechseln muß.

Du darfst auch gerne Deinen PC ohne Shutdown ausschalten und Dich über 
zerstörte Daten auf der Festplatte freuen.

Man darf immer das tun, was man will, wenn man die Folgen in Kauf nimmt.

Man kann aber auch einfach vernünftig handeln und sich dann über die 
vermiedene Fehlfunktion und den gesparten Ärger freuen.


Peter

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne Aufwand schrieb:
> Wenn ich ein goto aus einem Interrupt irgendwohin springen wollte, dann
> mache ich das!
>
> Stackpointer neu setzen, I-Flag löschen und was sonst noch in den
> Grundzustand gebracht werden muß. Fertig.
> Warum sollte ich mich zieren? Wenn ich ein Gerät auschalten will, dann
> mache ich das auch, wann ich will.

Kannst Du.
Aber wenn ich Dein Chef bin, dann mache ich auch mit Dir was ich will 
...

Autor: lalala (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist du denn sein Chef? Fänd ich lustig...

Autor: Klaus Falser (kfalser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lalala schrieb:
> Bist du denn sein Chef? Fänd ich lustig...

OK, Deutschproblem

Wenn ich Dein Chef wäre, usw ...

Autor: Ohne Aufwand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Bist du denn sein Chef? Fänd ich lustig...

Ich auch, dann hätte er nämlich ein Problem :-)

Warum seid Ihr bloß so ängstlich? Wenn dies nicht als Frage aufgetaucht 
wäre, sondern von einem Platzhirsch in der Codesammlung, dann wäre es 
die geniale Lösung gewesen.
Und plötzlich geht es nicht mehr um eine allgemeine µC Frage, sondern 
gleich um einen Tintendrucker oder eine Festplatte, womöglich noch um 
ein Flugzeug, was dann natürlich auf eine Millionenstadt abstürzt...

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Themenersteller könnte ja freundlicherweise mal was von seinem Code 
posten. Manche würden aber anscheinend eher ihre Freundin verkaufen, als 
das zu tun... ;-)

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> dann wäre es die geniale Lösung gewesen.


Nein, mit Sicherheit nicht!

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne Aufwand schrieb:
> Wenn ich ein goto aus einem Interrupt irgendwohin springen wollte, dann
> mache ich das!

Würde ich auch machen. Nur wollte ich das noch nie, weil es bisher immer 
ohne solch eine Dampfhammermethode ging.

Und wenn ich da in der Beschreibung was von Taste am INT0 lese, 
woraufhin sofort ganz schnell was passieren sollen müsste, kann ich 
jetzt schon sagen (wie alle vor mir auch), daß das nicht notwendig ist. 
Weder sofort noch ganz schnell (nach Mikrocontrollermaßstäben) noch 
überhaupt.

Das ist die falsche Lösung zur falschen Antwort auf die falsche Frage.

Oliver

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich ein goto aus einem Interrupt irgendwohin springen wollte, dann
> mache ich das!

Und durch welchen genialen Trick umgehst du das Problem der 
Stack-Inkonsistenzen? Denk dir mal ein Stück Code in Assembler-Form. 
Irgendwo steht ein Push, später mal das dazugehörige Pop. Nun wird genau 
dazwischen der Interrupt ausgelöst, der verursacht einen Sprung an eine 
ganz andere Stelle im Programm, und das Pop wird nie ausgeführt. Und das 
ist noch die einfache Variante, denn in C hast du nicht mal mehr die 
Kontrolle über Stack und Register. Diese werden vom Compiler automatisch 
verwaltet.

>> Bist du denn sein Chef? Fänd ich lustig...
>
> Ich auch, dann hätte er nämlich ein Problem :-)

Bist du so ein problematischer Mitarbeiter?

> Warum seid Ihr bloß so ängstlich?

Weil es gelinde gesagt eine blöde Idee ist.

> Wenn dies nicht als Frage aufgetaucht wäre, sondern von einem
> Platzhirsch in der Codesammlung, dann wäre es die geniale Lösung
> gewesen.

Nein, wäre es nicht. Man wäre vom "Platzhirsch" enttäuscht gewesen.

> Und plötzlich geht es nicht mehr um eine allgemeine µC Frage, sondern
> gleich um einen Tintendrucker oder eine Festplatte, womöglich noch um
> ein Flugzeug, was dann natürlich auf eine Millionenstadt abstürzt...

Du hast mit gen Vergleichen begonnen.

Autor: Ohne Aufwand (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Und durch welchen genialen Trick umgehst du das Problem der
>Stack-Inkonsistenzen?

Wenn man nach main springt, sollte es die nicht geben.
Lediglich bei 8051 sollte man noch eine Funktion aufrufen, die mit RETI 
endet, damit seine altertümliche Interruptbearbeitung wieder ins Lot 
kommt.

>Du hast mit gen Vergleichen begonnen.

Mea maxima culpa, obwohl ich das nicht nachvollziehen kann. Kannste ja 
Deinem Lehrer pätzen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn man nach main springt,

... und vor dem Interrupt auch schon in main war ...

> sollte es die nicht geben.

Sollte vielleicht nicht, aber könnte trotzdem.

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Ich springe, solange ich will!"

Dann schliesse den verdammten Taster an den verdammten Reset an und alle 
Fragen sind geklärt.

Autor: I. E. (anfaenger69)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke es gibt eine einfache Lösung mit nur ein paar Zeilen:

Es wird in der IRQ Routine einfach ein EEPROM Speicherplatz mit einem 
0xFF beschrieben und ein Reset im Programm (in der IRQ Routine noch 
selbst) ausgelöst.

Am Anfang vom main() wird zuerst im EEPROM nachgeschaut, ob 0xFF drinnen 
steht. Wenn ein 0xFF drinnen steht, dann wurde der Neustart durch den 
IRQ ausgelöst, dann wird dieser Speicherplatz gelöscht (eine 0x00 rein 
geschrieben) und zu einer bestimmten Stelle gesprungen - wie Richi es 
gewünscht hat.

Wenn irgendwas anderes drinnen steht, dann ist es ein normaler Reset 
gewesen und es geht im main() einfach weiter, als ob nichts gewesen 
wäre. Aber an dieser Stelle dann sollte danach auch erst wieder 
vorsichtshalber eine 0x00 hinein geschrieben werden - aus folgendem 
Grund:

Nur beim ersten einschalten wird das EEPROM im undefinierten Zustand 
sein.
Man kann es so lassen und es einfach ein zweites mal einschalten 
(spätestens dann steht durch die oben genannte Stelle eine 0x00 
drinnen).

Oder man beschreibt den EEPROM Inhalt schon mit dem STK500/600/Ponyprog 
usw. Dann wird auch das erste einschalten keine Fehlabfrage wegen 
undefiniertem Zustand sein.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Am Anfang vom main() wird zuerst im EEPROM nachgeschaut, ob 0xFF drinnen
>steht. Wenn ein 0xFF drinnen steht, dann wurde der Neustart durch den
>IRQ ausgelöst, dann wird dieser Speicherplatz gelöscht (eine 0x00 rein
>geschrieben) und zu einer bestimmten Stelle gesprungen - wie Richi es
>gewünscht hat.

Vor Anfang von main hat der startup-Code aber schon alle Variablen neu 
initialisiert. So ganz einfach irgendwo im Programm weitermachen geht 
damit nur, wenn keinerlei Daten aus dem Leben vor dem Reset benötigt 
werden (was eher unwahrscheinlich ist). Die könnte man zwar auch ins 
EEPROM retten, ebenso könnte man die Abfrage auf Warmstart in den 
startup-code verlegen, aber so oder so wird das alles extrem 
kompliziert.

Oliver

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:

> Vor Anfang von main hat der startup-Code aber schon alle Variablen neu
> initialisiert.

Kann man verhindern.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann vieles, aber wozu?  Zu 99,9% ist ein unnötig kompliziertes 
Programmkonzept das Problem, dass es zu lösen gilt.

Autor: Ohne Aufwand (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
>Man kann vieles, aber wozu?  Zu 99,9% ist ein unnötig kompliziertes
>Programmkonzept das Problem, dass es zu lösen gilt.

Wenn jemand so etwas vorhat, würde ich nicht gleich immer Dummheit 
unterstellen. Es gibt µCs, die haben diverse Vektoren für Kaltstart 
(reset), Warmstart (2.reset), Wachhund (watchdog) und obendrein noch 
NMI. Abhängig vom jeweiligen Ereignis, kann man komplett neu 
initialisieren, oder an einer Stelle aufsetzen, die nicht den kompletten 
RAM-Inhalt löscht oder i/o-Pins neu konfiguriert.

Wenn ich an meine Monitorprogramme für diverse µC zurückdenke, da gab es 
immer eine harte Abbruchmöglichkeit (z.B.) NMI oder Ctrl-C, um ein 
hängendes Programm abzubrechen (mit Register dump) und dennoch nicht 
über Reset alles auf 0 zu setzen.
Es kommt eben darauf an, was man machen will.

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.