Forum: Mikrocontroller und Digitale Elektronik AVR - nach Interrupt Code überspringen


von Multi _. (multibaba)


Lesenswert?

Hallo Zusammen,

ist es möglich, dass der µC nach einem Interrupt nicht an der gleichen 
Stelle weitermacht?
Ziel ist es, dass der Watchdog bei einem Fehler eine Interruptroutine 
auslöst. Diese soll dann eine Fehlermeldung ausgeben(z.B. rote LED 
leuchtet). Danach soll der Fehlerhafte Programmteil übersprungen werden 
und der restliche Code fertig ausgeführt werden.
Ich nutze einen AMega328-p und programmiere diesen in C.

Vielen Dank!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Mein Vorschlag: ISR setzt ein Errorflag, das von jeder Routine geprüft 
wird, die übersprungen werden soll. Wenn Flag gesetzt, wird 
übersprungen.

von Falk B. (falk)


Lesenswert?

@Multi __ (multibaba)

>ist es möglich, dass der µC nach einem Interrupt nicht an der gleichen
>Stelle weitermacht?

Jain. Aber das ist im Allgemeinen nicht sinnvoll.

>Ziel ist es, dass der Watchdog bei einem Fehler eine Interruptroutine
>auslöst. Diese soll dann eine Fehlermeldung ausgeben(z.B. rote LED
>leuchtet). Danach soll der Fehlerhafte Programmteil übersprungen werden
>und der restliche Code fertig ausgeführt werden.

Dann nutze eine passende Statemachine, dann muss man nicht tricksen.

von Peter II (Gast)


Lesenswert?

also im guten ist das nicht möglich, klar könnte man mit Long jumps böse 
dinge machen, aber sinnvoll ist das nicht.

du musst dabei den Stack definiert zurücksetzen, so etwas ist in C 
einfach nicht vorgesehen.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Multi _. schrieb:
> ist es möglich, dass der µC nach einem Interrupt nicht an der gleichen
> Stelle weitermacht?

Ja schon ... Soweit ich mich erinnern kann, haben die AVR einen 
Stackpointer und der Stack liegt im RAM. Dann überschreib die 
Rücksprungsadresse einfach mit einer anderen, wo er hinspringen soll ...

Geht, ist aber unschön und würde ich nicht so machen ...

von Charly B. (charly)


Lesenswert?

klar ist das machbar, du musst nur vor beenden des interrupts
die adresse wo es weiter gehen soll auf den stack legen, ABER
ich wuerd mir gedanken machen wieso ist da ein 'fehlerhafter
Programmteil' ??????????

ich habe schon sehr viele Programme geschrieben und NIE ein WDT
benoetigt, i denke du hast da die falsche vorgehensweise und
vllcht auch die falsche 'programmiersprache' (ist meine pers. meinung)


VlG
Charly

: Bearbeitet durch User
von Mampf F. (mampf) Benutzerseite


Lesenswert?

Achja und man kann sich da fies den Stack kaputt schießen ...

Bsp:

- irgendein Programmteil pusht etwas auf den Stack
- ISR tritt ein, ändert Rücksprungsadresse
- das, was vorher gepusht wurde, wird nicht mehr vom Stack abgeholt

Der Compiler rechnet nicht damit, dass sowas passieren könnte ... Also 
lieber nicht machen, außer du initialisierst den Stack gleich danach 
neu.

von Oliver S. (oliverso)


Lesenswert?

Da stellt sich die Standardfrage aller Standardfragen: WARUM?

Wie schon geschrieben wurde, kann man das über eine Manipulation der 
Rücksprungadresse auf dem Stack machen, aber außer für einen 
Multitasking-Taskschedluer braucht man dies eigentlich selten.

Oliver

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Hallo,

also ich sehe das ganz anders, wenn ein Programm nicht richtig arbeitet, 
soll es stehen bleiben und vorher eine Meldung - LEDs - absetzen.
Besser ist es doch vorher den Code auf logische Fehler zu prüfen und 
dead locks zu vermeiden.

von Noch nicht Rentner (Gast)


Lesenswert?

Die angefragte Loesung waere eine Fehlerbehebungsstrategie durch einen 
Watchdog. Auf regelmaessiger Basis.

Eine maximal schlechte Idee. Weshalb nicht gleich den urspruenglichen 
Fehler beheben ?

von Peter D. (peda)


Lesenswert?

Multi _. schrieb:
> Danach soll der Fehlerhafte Programmteil übersprungen werden
> und der restliche Code fertig ausgeführt werden.

Und woher soll der Interrupt wissen, daß er einen fehlerhaften Code 
unterbrochen hat?
Er könnte z.B. eine Math-Lib (Division), LCD-Lib usw. unterbrochen 
haben, die fehlerfrei sind.

Und woher soll er wissen, wohin er springen soll?
Ein Programm besteht ja in der Regel aus vielen Tasks.

Die longjump-Lib funktioniert auch aus Interrupts, aber ich habe sie 
noch nie gebraucht.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter D. schrieb:
> Und woher soll der Interrupt wissen, daß er einen fehlerhaften Code
> unterbrochen hat?

 Weil das eine Watchdog-ISR ist.
 Trotzdem ist für diese Frage nur eine Antwort richtig:
 *** Nein, in C macht man so etwas nicht !!! ***

 Wenn schon, dann wird nur ein Flag in der ISR gesetzt, der in
 main geprüft wird.

von holger (Gast)


Lesenswert?

> Wenn schon, dann wird nur ein Flag in der ISR gesetzt, der in
> main geprüft wird.

Da stellt sich dann die Frage wie der Code in die main kommen
soll wenn er in einer Endloschleife festhängt? Sonst würde
ja vermutlich der Watchdog auch nicht beissen.

von Multi _. (multibaba)


Lesenswert?

holger schrieb:
>> Wenn schon, dann wird nur ein Flag in der ISR gesetzt, der in
>> main geprüft wird.
>
> Da stellt sich dann die Frage wie der Code in die main kommen
> soll wenn er in einer Endloschleife festhängt? Sonst würde
> ja vermutlich der Watchdog auch nicht beissen.

Ist es evtl. sinnvoll, während des Interrupts den "Fehlerort" im EEPROM 
zu speichern und dann den watchdog reseten zu lassen? Dann wäre man in 
der Main und könnte den Programmteil mit dem Fehler überspringen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

holger schrieb:
> Da stellt sich dann die Frage wie der Code in die main kommen
> soll wenn er in einer Endloschleife festhängt? Sonst würde
> ja vermutlich der Watchdog auch nicht beissen.

 Ich habe vorhin etwas zu schnell geantwortet und mich noch dazu ein
 bisschen unklar ausgedrückt.

Multi _. schrieb:
> Ziel ist es, dass der Watchdog bei einem Fehler eine Interruptroutine
> auslöst. Diese soll dann eine Fehlermeldung ausgeben(z.B. rote LED

 Watchdog kriegt keine eigene ISR sondern springt den Reset-Vektor
 an (wie bei alten MEGA8).
 Und somit kann man in der main() zuerst WDRF im MCUCSR Register
 prüfen.

 Falls es zu einem WD-Reset kommen kann, setzt man beim Eintritt in
 die verdächtige Routine einen bit in z.B. ErrFlag, dieser bit wird
 beim verlassen der Routine wieder zurückgesetzt.
 Wenn der Watchdog zuschlägt, bleibt dieser bit in ErrFlag aber gesetzt,
 deswegen prüft man bei Neustart ob der WDRF gesetzt ist, falls ja,
 wird der ErrFlag geprüft und man weiss sofort ob es zu einem Fehler
 gekommen ist und wo dieser Fehler aufgetreten ist.
 Dementsprechend kann eine rote LED aufleuchten oder die MEGA kann
 sich z.B. selbst in die Luft sprengen...

: Bearbeitet durch User
von Ralf G. (ralg)


Lesenswert?

Marc V. schrieb:
> oder die MEGA kann sich z.B. selbst in die Luft sprengen...

... und dann wird er es sich nämlich stark überlegen, ob er nochmal 
einen Fehler macht! :)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Ralf G. schrieb:
> ... und dann wird er es sich nämlich stark überlegen, ob er nochmal
> einen Fehler macht! :)

 Yep, that's the general idea.

von A. S. (Gast)


Lesenswert?

Multi _. schrieb:
> Ist es evtl. sinnvoll, während des Interrupts den "Fehlerort" im EEPROM
> zu speichern und dann den watchdog reseten zu lassen?

Ja, das ist alles möglich. Es wäre jedoch einfacher, das Problem zu 
beschreiben als nach Details einer unkonventionellen Lösung zu fragen.

Wenn Leute fragen, wie sie ein Pony zum Mond befördern können, stellt 
sich am Ende heraus, das sie eigentlich graue Steine sammeln wollen. 
Warum auf dem Mond und wofür das Pony wissen sie selbst nicht.(verkürzt 
nach M.A.K.)

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
Noch kein Account? Hier anmelden.