Erste Begegnung mit Watchdog

Oskar01

Mitglied
24. März 2008
267
0
16
Köln
Sprachen
  1. Assembler
Hallo,
wenn man im Net nach "Watchdog" sucht, findet man einen Beitrag, der offensichtlich so nicht ganz korrekt ist.
Nachdem ich mir die Mühe gemacht hatte, ihn um die deutsche Übersetzung zu ergänzen, mußte ich im Praxistest feststellen, daß er leider unvollständig bzw. teilweise sogar nicht ganz richtig ist.

Daher hier einige grundsätzliche Fakten, die am besten auch auf Seiten 48ff im Manual vom
verwendeten ATMega8515 nachzuschlagen sind.

http://www.atmel.com/dyn/resources/prod_documents/2512S.pdf

Eine allgemeine Einrichtung des Wachhundes kann durch unten angegebenen Code erzielt werden.
Wichtig: Die Interruptfreigabe muß disabled werden mit dem ASM-Befehl CLI.
Am Ende des Strings den Wachhund "an die Leine nehmen" mit dem Resetbefehl
WDR (Watchdog Reset) und dann mit ASM-Befehl SEI die globale Interruptfreigabe ermöglichen.

Code:
cli
ldi	temp,	0x18	;Watchdog enable
out	WDTCR,	temp
ldi	temp,	0x0F	;Prescaler Set
out	WDTCR,	temp
wdr
sei
rjmp	start


Der Watchdog ist im Prinzip ein autonomer Timer, der selbständig einen Reset durchführt, wird der Timer nicht im Programmverlauf in regelmäßigen Abständen auf Null gesetzt.
Dauert die Ausführung eines Programmabschnitts also zu lange zwischen den Nachlademarken (Null-Ladewerten - Watchdog Reset - ASM-Anweisung "WDR" ( nicht Südwestfunk, nein, nicht Radio Bremen)-) für den Watchdog, wird davon ausgegangen, daß der Prozessor dort "hängengeblieben" ist und nach einem Programmneustart verlangt.

Im MC ist dazu ein eigener 1-MHz-Taktgenerator, der unabhängig von der MCU-Taktfrequenz läuft.
Ist der im Prescaler voreingestellte Wert der Zeit, zu der ein Reset ausgeführt werden soll, erreicht bzw. überschritten, wird ein Impuls mit einer Taktfrequenzlänge generiert, welcher wiederum einen Resetimpuls von definierter Länge zum Reset des MC triggert. So wird dann der "Systemreset" nach "Watchdog-Manier" ausgeführt. Die verschiedenen Resetereignisse werden noch durch Setzten von bestimmten Bits im Status- und Controlregister differenziert und protokolliert.

Der Watchdog kann also, ist er nicht richtig eingerichtet, durchaus mehr schaden als nutzen, indem er dann das gesamte Programm durch Reset zum Absturz bringt. (Reset=> in der Regel Sprung an Codeanfang, Löschung der Registerinhalte, etc.)

Um ein unbeabsichtigtes "Anschlagen" des "Wachhundes" zu vermeiden, sollte im Verlaufe des Programms, insbesondere vor Zeitschleifen oder seriellen Datentransfer-Operationen dieser
Timer selbst außer Kraft gesetzt werden mit Reset des Timers, und dazu die "WDR"-Anweisungen reingeschrieben werden.

Positiv wirkt sich der Watchdog aber dann aus,
wenn "Peripherie"-Geräte aus unerfindlichen Gründen
versagen und von Zeit zu Zeit neu initialisiert werden müssen, um das Gesamtprogramm wieder zur Funktion zu bewegen. Es wird dann auch die entsprechende Initialisierungsroutine am Anfang des Programms wieder durchlaufen.

(Übrigens andere Methode zur Inaktivierung des Watchdog im Programmverlauf: "Watchdog-disable" mit Ladewert 0b00010000 oder Hex 0x10 in Register WDTCR.) Wie hier:

Code:
ldi	temp,	0x10	;Watchdog disable
out	WDTCR,	temp

Auch kann im Verlaufe eines Programms auf den Prescaler zugegriffen werden, hierbei ist allerdings zu beachten, daß diese Strings zeitkritisch sind. Es wird davon berichtet, daß diese
Anweisungen innerhalb von 4 bzw. 5 MCU-Takten unmittelbar aufeinander folgen müssen.
(Übrigens: Durch Setzen von Fuses können verschiedene Security-Level gewählt werden, die gerade diese Änderungen an den Watchdog-Einstellungen im Programmverlauf auch ihrerseits verhindern. Darauf beziehen sich auch die Modifikationen vom ATS90xx zum ATMegaxx.)

Zwingend notwendig ist der erste String im Codebeispiel mit "Watchdog enable", insbesondere dann, wenn er durch obigen "Disable-String" irgendwann mal komplett abgeschaltet war.

Also im Register WDTCR Bit 4 gesetzt, Bit 3 auch auf "Eins", also 0b00011000 bzw. Hex 0x18 .

Code:
ldi	temp,	0x18	;Watchdog enable
out	WDTCR,	temp

Der Vorteiler (Prescaler) ist hier im Code-Beispiel durch Setzen von allen Bits WDP0 bis WDP2 im Register WDTCR auf den Maximalzeitwert von über 1 Sekunde eingestellt.

Zum Zugriff auf den Vorteiler muß nun noch das Bit 3 WDE gesetzt werden. Also String-Argument 0b00001111 bzw. Hex 0x0F,
wobei bei Einrichtung des Prescalers dieses ominöse Bit 4 von String "Watchdog-Enable" wieder auf "Null" stehen muß und nicht etwa auf "Eins".

Das scheint zunächst etwas unklar, und genau darauf bezieht sich die Fehlerquelle im eingangs erwähnten "Net"-Beitrag.

Code:
ldi	temp,	0x0F	;Prescaler Set
out	WDTCR,	temp

Oben im Codebeispiel ist's aber IMHO richtig, in der Reihenfolge korrekt angegeben und auch in der Praxis von mir getestet.


Übrigens wird - wie oben schon angeklungen - das Bit 3 im Control-und-Status-Register bei "Anschlagen" des "Wachhundes" gesetzt und kann dort auch ausgelesen werden, falls man das möchte (MCUCSR Bit WDRF).
Dieses "Watchdog-Reset-Flag" bleibt nach dem so gearteten Resetereignis erhalten, wird nur durch einen Power-On-Reset gelöscht.
Das ist beim Testlauf von Progs vielleicht eine ganz interessante Möglichkeit, evtl. Bugs aufzuspüren.

Gruß von Oskar01
 
Testprogramm

Hallo,
hier noch ein kleines Testprogramm, das es beim ATMega8515 ermöglicht,
das WDRF-Bit im MCUCSR-Control-und-Statusregister auf dem PC-Terminal per serielle Schnittstelle auszulesen.

Das Programm funktioniert so:

Beim Einschalten erscheint in der Anzeige der Buchstabe "B".
Dann eine Reihe von "J" wie, "ja", (die WDR-Anweisung wurde nicht programmiert,) also hat der Watchdog angeschlagen, und das entsprechende Flag wurde gesetzt.

Wird jetzt während des Betriebes die Reset-Taste am STK500-Board gedrückt,
bleibt die Anzeige auf "J", also Flag wird so nicht gelöscht, bestehen.

Im Verlaufe des Tests habe ich dann willkürlich mal die Spannung abgeschaltet, die serielle
Übertragung stoppt, und nach Wiedereinschalten erfolgt die Anzeige "B" und so weiter.
Das verdeutlicht, daß das WDRF-Bit tatsächlich nur durch Power-On-Reset gelöscht wird, so wie es übrigens auch im Handbuch beschrieben ist.

Zur besseren Veranschaulichung wurde noch die LED auf Port B, Bit B0
auf "low" geschaltet. Sie blinkt hell im Rhythmus des Reset - in unsymmetrischem Tastverhältnis.

So kann man einigermaßen die Auswirkung der Vorteilerwerte antesten. Ok, es kommt noch die Warteschleifenverzögerung hinzu.

Kurz blitzen auch alle anderen LEDs auf direkt nach dem Reset, da ja dann kurzzeitig der Ausgabe-Port noch auf "Low" steht, bevor der Port vollständig initialisiert ist.

Also:
alle Ports undefiniert => durch Reset definitionsgemäß erst kurz alle auf 0x00, dann:....

ldi temp, 0b11111111 ; => Hex 0xFF
out ddrb, temp ; durch Laden von Hex 0xFF Datenrichtungsregister auf Ausgang
ldi temp, 0b11111110 ; => Hex 0xFE ; nur die erste LED soll blinken,
; ; LED-Ausgabe ist "low"-active...
out leds, temp ;... beim STK-500-EVA-Board


Viel Spaß,
Oskar
 

Anhänge

  • Lesen_WDRF.txt
    2,5 KB · Aufrufe: 19
  • capture_file.TXT
    62 Bytes · Aufrufe: 10

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)