Hallo zusammen,
ich benutze einen AT90CAN128 und habe ein Problem mit dem Watchdog.
Falls das Programm hängen bleibt soll der Mikrocontroller sich neu
starten.
Bei der Initialisierung aktiviere ich den Watchdog mit 250ms Timeout:
wdt_enable(WDTO_250MS); // Watchdog Timeout = 250ms
Da ich in der Hauptschleife einige Delays habe würde ich den Watchdog
Reset gerne in einem Interrupt ausführen.
wdt_reset();
Der Grund wieso ich den WDT-Reset in einem Interrupt ausführn ist weil
während den geplanten Delays in der Hauptschleife kein Timeout ausgelöst
werden darf. (Globale Interrupts während Delays immer aktiviert)
Nun das ganze funktioniert eigentlich. Wenn ich das Programm mit einem
Taster in eine Endlosschleife bringe (nur zu Testzwecken) resetet der
Controller. Leider resetet er dann auch noch weiter nachdem ich den
Taster nicht mehr drücke. Kann mir keinen Reim darauf bilden.
Hat jemand eine Idee wo mein Fehler liegt?
Danke für Tipps.
Gruss Dominik
Was soll das Triggern im Interrupt bringen? Damit kanst du nur
überprüfen ob dein Timerinterrupt noch arbeitet.
Mach eine Hauptschleife im Programm die ziklisch abgearbeitet wird und
am Ende dieser den Trigger.
Delays kann man auch realiesieren ohne den ganzen Programmablauf zu
stoppen.
Dominik W. schrieb:> Hat jemand eine Idee wo mein Fehler liegt?
Möglicherweise gelangt das Programm nach einem Watchdog-Reset nicht mehr
schnell genug an die Stelle, wo der Watchdog erstmals wieder getriggert
wird.
Watchdog im Interrupt sollte man besser bleiben lassen, denn ein
Interrupt kann auch unbehelligt weiter laufen, wenn das Hauptprogramm
schon lange abgestürzt ist.
Hier und dort wird in Application Notes schon mal empfohlen, den
Watchdog im Interrupt zurück zu setzen. Dann sind die Schreiber der
Application Notes ahnungslos, und reiten den Anwender ins Verderben. Das
diskutierten wir kürzlich noch bei einem STM32, weil es dort angeblich
so empfohlen wurde.
Wenn du deinen WDT in der Timer-ISR rücksetzt, stellst du damit nur
sicher, dass sich diese ISR nicht aufhängt. Wenn im Hauptprogramm
irgendwas schief läuft und der Controller sich in einer Schleife
befindet, aus der er nicht rauskommt, hilft der WDT da überhaupt
nichts...
Ingo
Wenn der Watchdog eingeschaltet ist, bleibt er an, solange die
Stromversorgung eingeschaltet ist. Auch ein Reset schaltet ihn nicht ab
(was ich seltsam finde).
Darum solltest Du ganz am Anfange des Programms zuerst den Watchdog
abschalten, dann die Initialisierungsroutinen durchlaufen, und ihn dann
wieder einschalten.
Oder Du sorgst dafür, dass die Initialisierungsroutinen den Watchdog
schnell genug zurück setzt. Zum Beispiel, indem Du die Initialisierung
in mehrere kleine Schritte terlegst, die nicht zu lange dauern. Etwas
so:
1
intmain(){
2
watchdog_einschalten;
3
watchdog_reset;
4
init_teil1;
5
watchdog_reset;
6
init_teil2;
7
watchdog_reset;
8
init_teil3;
9
while(1){
10
watchdog_reset;
11
eingänge_anfragen;
12
ereignisse_behandeln;
13
}
14
}
Eine gedrückt gehaltene Taste sollte keine Endlos-Warteschleife
auslösen. Da hast Du offensichtlich ein Programm-Konzept gewählt, dass
mit Watchdogs nicht vereinbar ist. Hier im Forum gibt es schon reichlich
Beispiele, wie man Tasten ohne Endlos-schleifen abfragt und entprellt.
Programme mit Watchdog sollten nur eine einzige Endlosschleife haben,
und das ist das Hauptprogramm. Alles Andere sollten nur Reaktionen auf
Ereignisse sein. In diesem Sinne wäre das Drücken der Taste ein Ereignis
und das Loslassen wäre ein zweites Ereignis.
1
uint8_ttaste_jetzt;
2
uint8_ttaste_vorher;
3
4
intmain(){
5
while(1){
6
taste_jetzt=taste_abfragen();
7
if(taste_jetzt==1undtaste_vorher==0){
8
// Taste wurde gerade gedrückt
9
tuwas;
10
}
11
elseif(taste_jetzt==0undtaste_vorher==1){
12
// taste wurde gerade losgelassen
13
tuwas_anderes;
14
}
15
taste_vorher=taste_jetzt;
16
}
17
}
Entprellung habe ich hier mal ausgelassen, damit es nicht
unübersichtlich wird.
Auch Zeitliche Ereignisse müsstest Du so behandeln. Wenn z.B. nach dem
Drücken des Taster eine LED kurz 5s lang an gehen soll, dann geht das
so:
1
uint8_ttaste_jetzt;
2
uint8_ttaste_vorher;
3
uint16_tvolatilesystemzeit;// z.B Timer der jede Sekunde hochzählt
4
uint16_tled_aus_zeit;
5
6
intmain(){
7
while(1){
8
taste_jetzt=taste_abfragen();
9
10
if(taste_jetzt==1undtaste_vorher==0){
11
// Taste wurde gerade gedrückt
12
schalte_led_an;
13
led_aus_zeit=systemzeit+5;
14
}
15
16
if(systemzeit>led_aus_zeit){
17
// LED soll jetzt wieder aus gehen
18
schalte_led_aus;
19
}
20
21
taste_vorher=taste_jetzt;
22
}
23
}
Die Systemzeit wäre eine Variable, die von einem Timer-Interrupt jede
Sekunde um 1 erhöht wird. Die ISR habe ich der Übersicht halber hier
ausgelassen.
Ich denke, so kriegst Du das hin.
> Watchdog im Interrupt sollte man besser bleiben lassen,> denn ein Interrupt kann auch unbehelligt weiter laufen,> wenn das Hauptprogramm schon lange abgestürzt ist.
Ich wage sogar zu behaupten, dass dies fast immer zutrifft. Deswegen ist
es Sinnlos.
Nen WD-Reset braucht man eigentlich nur, wenn man das logische, bzw.
timingmässige Zusammenspiel der Codesegmente nicht wirklich versteht.
Ansonsten sollte man jeden Zweig so programmieren, daß ein Ausbremsen
durch Input-Aktionen bzw. ein Aufhängen ausgeschlossen ist, oder
zumindest über eine ERROR-Routine abgefangen und lokalisiert wird. Dann
kann man ggf. auch gezielt debuggen und entschärfen.
Sauberer Code hängt sich nirgendwo auf. Statt warten, und/oder unnötig
in Schleifen pollen, kann man gezielt INTs nutzen, um spontan auf einen
prioritären Event zu reagieren... D.h. es ist besser man reagiert nur
auf Flankenwechsel, statt auf Pegelzustände.
> D.h. es ist besser man reagiert nur auf Flankenwechsel
Sag ich ja. Und wenn man sich dran gehalten hat, ist es auch leicht, den
Watchdog-Reset an einer Sinvollen Stelle unter zu bringen.
Praktisch habe ich allerdings die Erfahrung gemacht, dass
Mikrocontroller (egal welche Modellreihe) absolut stabil laufen, sofern
Schaltung und Programm fehlerfrei sind. Dann braucht man keinen
Watchdog.
Wenn ein Mikrocontroller sich aufhängt, hat man irgendwo etwas falsch
gemacht.
Schutz gegen Aussetzer in der Stromversorgung erreicht man besser durch
den Brown-Out Detektor.
Michael Sch. schrieb:> Nen WD-Reset braucht man eigentlich nur, wenn man das logische, bzw.> timingmässige Zusammenspiel der Codesegmente nicht wirklich versteht.
Wenn man ein perfekter Programmierer ist, der alle möglichen und
insbesondere auch die vermeintlich unmöglichen Situationen vorhersieht,
und sich die verbaute Hardware ebenfalls in allen nur erdenklichen
Lebenslagen perfekt verhält, dann braucht man keinen Watchdog. Aber wie
oft findet man eine solche Konstellation schon?
Die Erkenntnis, dass der Rechner sich ab und zu resettet, hilft
allerdings nicht, den Programmfehler zu finden. Ganz im Gegenteil.
Dazu kommt, dass das ganze System für den Fall ausgelegt sein muss.
Wenn mit beim Reset das Garagentor auf den Kopf knallt, freue ich mich
nicht. Oder wenn die Uhr im Laufe einiger Wochen immer ungenauer wird,
weil der Antriebsmotor ab und zu kurz stehen bleibt, dann bin ich nicht
zufrieden. Oder wenn mein Handy hin und wieder eigenmächtig Gespräche
unterbricht, habe ich keinen Spass. Oder wenn Im Büro die Lichter
ausgehen, weil die Lichtsteuerung sich zurückgesetzt hat, herrscht
Unruhe im Büro.
Stefan Frings schrieb:> Die Erkenntnis, dass der Rechner sich ab und zu resettet, hilft> allerdings nicht, den Programmfehler zu finden. Ganz im Gegenteil.
Es behauptet m.W. niemand, dass ein Watchdog das Allheilmittel für alle
Lebenslagen ist. Es ist ein Notnagel, mehr nicht. Wie oben schon gesagt,
perfekte Technik ist mir auch lieber.
Beispiel für Watchdog: Man baut eine Heizungssteuerung. Ein Brenner, der
tagelang durchläuft weil sich die Steuerung verhakt hat, fördert zwar
die Wirtschaft, ist aber nicht im Interesse des Bewohners. Der will,
dass (1) nichts abbrennt und (2) nichts einfriert.
Wenn sich die Steuerung durch einen Watchdog resettet, dann bricht
vielleicht eine Aktion ab, aber die erwähnten Kriterien lassen sich mit
hoher Wahrscheinlichkeit einhalten. Einer Fehlersuche steht das nicht
unbedingt im Weg, wenn man dran gedacht hat, die Aktivitäten und
Sensorinformationen zu protokollieren.
Ein nicht ganz perfekte Lösung mit Notnagel für seltene unvorhergesehene
Fälle ist mir jedenfalls lieber, als eine angeblich perfekte Lösung, bei
der widrigenfalls ein Neubau ansteht. Denn erfahrungsgemäss zeichnen
sich perfekte Lösungen nur dadurch aus, dass man den Problemfall
entweder noch nicht hatte oder unter den Teppich kehrte. Was nicht
heisst, dass der Einsatz des Notnagels zu Regel werden sollte.
Danke für die vielen Ideen und Tipps.
Wahrscheinlich hat Stefan Frings mit seiner Annahme recht das der
Watchdog bei der Initialisierung zuerst (wieder) abgeschaltet werden
muss.
@Stefan Frings: Ein Taster führt natürlich nicht zu einer
Endlosschleife. Ich habe das absichtlich programmiert um den Watchdog zu
testen! Das macht sonst keinen Sinn.
Delays sollte man natürlich nicht über die Hauptschleife lösen, sondern
über Timer. Bei mir ist es etwas speziell. Bei einem normalen Durchlauf
gibt es keine Delays. Nur bei speziellen Vorgängen wie Relais schliessen
und anschliessend Spannung überprüfen.
Ich werde mir nochmal überlegen wie ich den Watchdog bei mir
implementiere.
Danke nochmal für die Antworten.
Gruss Dominik
Das System funktioniert übrigens prima und sollte so programmiert sein
das es sich nicht aufhängen kann.
Trotzdem es sind fast 3000 Zeilen Code. Es handelt sich um die Steuerung
von einem 30kW Elektrokart (Eigenbau). Der Watchdog soll einfach
zusätzlich Sicherheit bringen.
Wahrscheinlich wäre es sinnvoll alle zeitlichen Vorgänge (Relais
schliessen, Vorladen, etc) mithilfe von Timern zu lösen und dann einen
WDT_Reset in er Hauptschleife zu implementieren.
Dominik W. schrieb:> Der Watchdog soll einfach> zusätzlich Sicherheit bringen.
Das Problem ist aber, dass du genau dieses mit einem Watchdog-Reset im
Timer-Interrupt aushebelst.
> Wahrscheinlich wäre es sinnvoll alle zeitlichen Vorgänge (Relais> schliessen, Vorladen, etc) mithilfe von Timern zu lösen und dann einen> WDT_Reset in er Hauptschleife zu implementieren.
Jetzt geht die Reise in die richtige Richtung!
Hallo,
die Idee, auch die ISR darauf zu prüfen, ob sie noch ausgeführt wird,
ist ja keineswegs falsch, auch wenn das hier manche verächtlich als
Dummheit abtun (gehört hier wohl zum "guten" Stil, Lösungen anderer als
Idiotie zu bezeichnen). Nur muss eben die Hauptschleife auch und vor
allem abgesichert werden, also bräuchte man 2 Watchdogs, was es meines
Wissens nirgends gibt.
Ich löse das daher mit Flags, die in main gesetzt und in den ISRs
zurückgesetzt werden, passiert das nicht, wird ebenfalls ein Neustart
ausgelöst. Somit wird main durch den Watchdog und die ISRs durch main
gecheckt.
Übrigens ist es überhaupt kein Problem, in main delays zu verwenden, man
muss nur dafür eine allgemeingültige und natürlich sauber programmierte
delay-Routine verwenden, in der ausreichend oft der Watchdog getriggert
wird.
Gruss Reinhard
Michael Sch. schrieb:> Nen WD-Reset braucht man eigentlich nur, wenn man das logische, bzw.> timingmässige Zusammenspiel der Codesegmente nicht wirklich versteht.
Du vergißt äußere Einflüsse auf den Prozessor, wie z.B. Höhenstrahlung
Michael Sch. schrieb:> Nen WD-Reset braucht man eigentlich nur, wenn man das logische, bzw.> timingmässige Zusammenspiel der Codesegmente nicht wirklich versteht.
Das ist die Stellungnahme von jemandem, der sich selbst für unfehlbar
hält, und seine eigene Software für von vornherein fehlerfrei. Kommentar
überflüssig.
Gruss Reinhard
Hi
>...und seine eigene Software für von vornherein fehlerfrei.
Nicht von vorn herein. Aber irgendwann muß sie es sein. Und erst dann
kann man sie über den Einsatz des Watchdogs Gedanken machen.
Dominik W. (Gast) schrieb:
>Falls das Programm hängen bleibt soll der Mikrocontroller sich neu>starten.
Ein Programm bleibt nicht einfach so hängen. Das hat immer einen Grund.
Und diesen Grund muss man finden und beseitigen, nicht mit einem
Watchdog kaschieren.
MfG Spess
Der Watchdog wird oft hoffnungslos überschätzt und seine Programmierung
unterschätzt.
Wenn z.B. auf eine 8Bit-Variable 16bittig zugegriffen wird, wird die
nachfolgende Variable mit Mumpitz geladen und Dein MC rechnet mit
Mumpitz weiter. Den Watchdog interessiert das in keinster Weise.
Oder eine fehlende atomare Kapselung.
Usw. usw. ...
Ein Watchdog schützt also nicht gegen schlampiges Programmieren.
Ein Watchdog ist nur sinnvoll bei erhöhten Sicherheitsanforderungen.
Aber dann ist es witzlos, ihn irgendwie einzufügen.
Man implementiert ihn erst, nachdem die Applikation fertig programmiert
ist. Er ist quasi eine vollkommen eigenständige Aufgabe, die nochmal
eine komplette Planung benötigt.
Überlegt man nicht sorgfältig, welche Fehler auftreten können und wie
man sie mit dem Watchdog erkennen könnte, kann man sich die Arbeit mit
dem Watchdog auch gleich ganz sparen. Er hat dann in etwa die
zusätzliche Sicherheit, wie ein eingefügtes NOP.
Peter Dannegger schrieb:> Oder eine fehlende atomare Kapselung.
Das kommt ja noch hinzu, z.B. beim Siemens/Infineon SAB80C517A oder
C515. Die Watchdog-Sequenz besteht aus zwei Befehlen, die nicht
auseinander gerissen werden dürfen, auch kein NOP oder was anderes
dazwischen sein darf. Also: Vor der Sequenz Interrupts global sperren,
und nachher wieder frei geben. Wie bei größeren Variablen, die im
Interrupt und im Hauptprogramm verwendet werden.
In mancher Software ist es wohl reiner Zufall, daß da nichts passiert.
Womit man wieder beim Thema bugfreie Software ist. Die kann ja z.B. ein
Jahr lang auf dem Prüfstand einwandfrei spielen. Das heißt aber eben
nicht auch bugfrei, wenn sich zufällig mal nichts ins Gehege kommt.
Na ja, es gibt verschiedenes, der eingebaute Watchdog ist so ein gutes
Mittelding, hilft bei erhöhten Sicherheitsanforderungen auch nicht.
Meine SAB80C517A haben erstaunlicherweise sogar noch einen
Oszillator-Watchdog auf dem Chip. Der hält den Chip an, und fährt die
Ports in einen definierten Zustand, wenn der Quarz aus fällt, bspw. in
stark vibrierenden Anwendungen. Das Programm startet erst wieder, wenn
sich der Quarztakt stabilisiert hat. Oder auch nicht, wenn man das per
Software selbst bestimmt. Die Dinger wurden eine Weile mal massenweise
in Autos verbaut. Dann habe ich hier auch noch einen externen Watchdog
liegen, der an zwei µC-Pins kommt. Der hat ein internes RC-Glied für die
Zeitkonstante, was sehr sicher ist, eine Art retriggerbares Monoflop.
In alter Literatur habe ich immer wieder solche Beispiele und
Schaltbilder.
Dominik W. schrieb:> Falls das Programm hängen bleibt soll der Mikrocontroller sich neu> starten.
Dafür ist ein Watchdog da.
> Da ich in der Hauptschleife einige Delays habe würde ich den Watchdog> Reset gerne in einem Interrupt ausführen.
Schwachsinn. Damit kann der Watchdog genau das nicht mehr leisten, wofür
er da ist: die Auswirkungen von unvorhergesehenen Softwarefehlern zu
begrenzen.
Du hast ein Softwaredesignproblem. Lange delays haben (außer für Lehr-
und Testzwecke) nirgendwo irgendetwas zu suchen, auch nicht in der
Hauptscheife. So einfach ist das.
Also behebe dein Designproblem und du hast auch kein Problem mehr mit
dem Watchdog.