
Jeder kennt es von Computern und Smartphones: Ab und an treten Softwarefehler auf, die zu einer Fehlfunktion oder Verzögerung führen. Das laufende Betriebssystem erkennt diesen Umstand und bricht den betreffenden Prozess ab bzw. startet das System neu.
Bei Geräten basierend auf Android wird meist ein sog. Soft Reboot durchgeführt, d.h. es wird nur das OS neu geladen, während die komplette Hardware durchgehend mit Strom versorgt wird. (Eine Eingabe der PIN für die SIM-Karte ist in den meisten Fällen nicht erforderlich)
Windows-PCs verabschieden sich bekannterweise mit einem Bluscreen, der Benutzer muss manuell neustarten.
Wie schaut das o.g. Szenario nun bei Mikrocontrollern aus? Da diese selbstverständlich auch softwaregesteuert sind, kann sich auch hier etwas “aufhängen”, nur eben nicht in einem komplexem Ausmaße wie bei einer grafischen Oberfläche mit vielen einzelnen, parallelen Prozessen, sondern eher so, dass eine if-Abfrage in einer Endlosschleife endet, oder ein Sensor am I2C-Port eine kurze Störung hatte und so weiter.
Passiert genau dies, erhält man keinen Bluescreen als Rückmeldung, der Mikroprozessor bemerkt es ja nicht einmal. Warum? Weil keine einzige Codezeile eine Überwachung definiert, extern übernimmt das auch kein Schaltkreis, ein Mikocontroller handelt nicht autonom und “denkt” sich dementsprechend nichts dabei, ob er für die Ausführung einer Abfrage eine Millisekunde benötigt oder 10 Sekunden.
Heikel wird es dann, wenn der Wert eines Temperatursensors periodisch auf eine SD-Karte geschrieben wird, ein Tastenfeld auf eine Eingabe wartet oder eine Spannung überwacht werden soll, die Funktion der CPU ist unentbehrlich.
Die Liste, welche Auslöser für eine Verzögerung eintreten könnten, ist lang und das meiste lässt sich nunmal nicht gänzlich verhindern, es besteht jedoch die Möglichkeit, das Einfrieren des Mikrocontrollers zu erkennen.
Der Watchdog Timer
Das geschieht mit dem Watchdog bzw. Watchdog-Timer, das ist bei den ATmega48/88/168/328 ein zusätzlicher on-chip Oszillator mit 128 kHz Taktfrequenz.
Dieser Timer hat wie die anderen in einem AVR auch einen einstellbaren Vorteiler, um die Zeit bis zum Overflow festzulegen, ist dieser Punkt erreicht, löst der Watchdog einen Reset aus und der Mikrocontroller startet neu.
Da das im laufenden Betrieb den Programmablauf und die Funktionalität extrem einschränkt, sollte der Timer nur auslösen, wenn es wirklich nötig ist. Man muss also zusammenrechnen, wie lange die Hauptschleife (main, loop) im schlimmsten Falle für einen Durchgang braucht und setzt den Watchdog Timer eine Zeitstufe über diesen Wert.
Zusätzlich muss dieser bei Erreichen des Endes der Main-Loop “entschärft” werden, damit er nicht mitten im zweiten Durchgang auslöst.
Syntax
Als erstes muss die Header-Datei importiert werden, funktioniert natürlich auch mit der Arduino-IDE:
1 |
#include <avr/wdt.h> |
Anschließend wird der Timer im setup()-Teil aktiviert (standartmäßig ist er deaktiviert), gleichzeitig wird auch die Zeit bis zum Auslösen übergeben, alle möglichen Werte habe ich unten aufgelistet:
1 2 3 4 5 6 7 8 9 10 |
wdt_enable(WDTO_15MS); //15 ms wdt_enable(WDTO_30MS); //30 ms wdt_enable(WDTO_60MS); //60 ms wdt_enable(WDTO_120MS); //120 ms wdt_enable(WDTO_250MS); //250 ms wdt_enable(WDTO_500MS); //500 ms wdt_enable(WDTO_1S); //1 s wdt_enable(WDTO_2S); //2 s wdt_enable(WDTO_4S); //4 s --> Funktioniert nicht bei ATMega 8 wdt_enable(WDTO_8S); //8 s --> Funktioniert nicht bei ATMega 8 |
Am Ende der Hauptschleife sorgt dieser Befehl dafür, dass der Zählstand des Watchdogs auf 0 zurückgesetzt wird.
1 |
wdt_reset(); |
Wichtig ist aber noch: Der Watchdog verhindert nicht das Einfrieren, wenn der Code selbst unsauber programmiert ist!
Soll der Watchdog wieder deaktiviert werden, geht das über diesen Befehl:
1 |
wdt_disable(); |
[:en]Jeder kennt es von Computern und Smartphones: Ab und an treten Softwarefehler auf, die zu einer Fehlfunktion oder Verzögerung führen. Das laufende Betriebssystem erkennt diesen Umstand und bricht den betreffenden Prozess ab bzw. startet das System neu.
Bei Geräten basierend auf Android wird meist ein sog. Soft Reboot durchgeführt, d.h. es wird nur das OS neu geladen, während die komplette Hardware durchgehend mit Strom versorgt wird. (Eine Eingabe der PIN für die SIM-Karte ist in den meisten Fällen nicht erforderlich)
Windows-PCs verabschieden sich bekannterweise mit einem Bluscreen, der Benutzer muss manuell neustarten.
Wie schaut das o.g. Szenario nun bei Mikrocontrollern aus? Da diese selbstverständlich auch softwaregesteuert sind, kann sich auch hier etwas “aufhängen”, nur eben nicht in einem komplexem Ausmaße wie bei einer grafischen Oberfläche mit vielen einzelnen, parallelen Prozessen, sondern eher so, dass eine if-Abfrage in einer Endlosschleife endet, oder ein Sensor am I2C-Port eine kurze Störung hatte und so weiter.
Passiert genau dies, erhält man keinen Bluescreen als Rückmeldung, der Mikroprozessor bemerkt es ja nicht einmal. Warum? Weil keine einzige Codezeile eine Überwachung definiert, extern übernimmt das auch kein Schaltkreis, ein Mikocontroller handelt nicht autonom und “denkt” sich dementsprechend nichts dabei, ob er für die Ausführung einer Abfrage eine Millisekunde benötigt oder 10 Sekunden.
Heikel wird es dann, wenn der Wert eines Temperatursensors periodisch auf eine SD-Karte geschrieben wird, ein Tastenfeld auf eine Eingabe wartet oder eine Spannung überwacht werden soll, die Funktion der CPU ist unentbehrlich.
Die Liste, welche Auslöser für eine Verzögerung eintreten könnten, ist lang und das meiste lässt sich nunmal nicht gänzlich verhindern, es besteht jedoch die Möglichkeit, das Einfrieren des Mikrocontrollers zu erkennen.
Der Watchdog Timer
Das geschieht mit dem Watchdog bzw. Watchdog-Timer, das ist bei den ATmega48/88/168/328 ein zusätzlicher on-chip Oszillator mit 128 kHz Taktfrequenz.
Dieser Timer hat wie die anderen in einem AVR auch einen einstellbaren Vorteiler, um die Zeit bis zum Overflow festzulegen, ist dieser Punkt erreicht, löst der Watchdog einen Reset aus und der Mikrocontroller startet neu.
Da das im laufenden Betrieb den Programmablauf und die Funktionalität extrem einschränkt, sollte der Timer nur auslösen, wenn es wirklich nötig ist. Man muss also zusammenrechnen, wie lange die Hauptschleife (main, loop) im schlimmsten Falle für einen Durchgang braucht und setzt den Watchdog Timer eine Zeitstufe über diesen Wert.
Zusätzlich muss dieser bei Erreichen des Endes der Main-Loop “entschärft” werden, damit er nicht mitten im zweiten Durchgang auslöst.
Syntax
Als erstes muss die Header-Datei importiert werden, funktioniert natürlich auch mit der Arduino-IDE:
1 |
#include <avr/wdt.h> |
Anschließend wird der Timer aktiviert (standartmäßig ist er deaktiviert), gleichzeitig wird auch die Zeit bis zum Auslösen übergeben, alle möglichen Werte habe ich unten aufgelistet:
1 2 3 4 5 6 7 8 9 10 |
wdt_enable(WDTO_15MS); //15 ms wdt_enable(WDTO_30MS); //30 ms wdt_enable(WDTO_60MS); //60 ms wdt_enable(WDTO_120MS); //120 ms wdt_enable(WDTO_250MS); //250 ms wdt_enable(WDTO_500MS); //500 ms wdt_enable(WDTO_1S); //1 s wdt_enable(WDTO_2S); //2 s wdt_enable(WDTO_4S); //4 s --> Funktioniert nicht bei ATMega 8 wdt_enable(WDTO_8S); //8 s --> Funktioniert nicht bei ATMega 8 |
Am Ende der Hauptschleife sorgt dieser Befehl dafür, dass der Zählstand des Watchdogs auf 0 zurückgesetzt wird.
1 |
wdt_reset(); |
Wichtig ist aber noch: Der Watchdog verhindert nicht das Einfrieren, wenn der Code selbst unsauber programmiert ist!
Soll der Watchdog wieder deaktiviert werden, geht das über diesen Befehl:
1 |
wdt_disable(); |
Stevie