Hallo Zusammen,
Ich bin gerade dabei den Watchdog zum ertsen Mal nicht abzuschalten.
Bisher stellt sich noch nicht das gewünschte Ergebnis ein.
Nur damit ich es richtig verstanden habe:
Statt den Watchdog mit WDTCTL = WDTPW + WDTHOLD auszuschalten setze ich
am Anfang der main() irgendein Intervall WDTCTL = WDTPW + WDTIS0 und
dann später im Code mit
WDTCTL = WDTPW + WDTCNTCL den Counter zurück.
Hat sich das Programm aufgehängt geschieht dies nicht und es wird ein
Reset ausgeführt, oder ?
Mit diesen Einstellungen macht mein Program gar nix mehr. Ich denke mal,
dass ich da irgendwas falsch verstanden habe...
Gruß
Seb
>am Anfang der main() irgendein Intervall WDTCTL = WDTPW + WDTIS0
Am besten noch ein WDTCNTCL mit rein damit du wirklich bei 0 startest.
>und dann später im Code mit WDTCTL = WDTPW + WDTCNTCL den Counter zurück.
"Später" solltest du aber genau berechnen, nicht das du den richtigen
Zeitpunkt verpasst :)
>Hat sich das Programm aufgehängt geschieht dies nicht und es wird ein>Reset ausgeführt, oder ?
Ja.
>Mit diesen Einstellungen macht mein Program gar nix mehr. Ich denke mal,>dass ich da irgendwas falsch verstanden habe...
Dann berechne mal ob du den Counter rechtzeitig zurücksetzt.
>Mit diesen Einstellungen macht mein Program gar nix mehr. Ich denke mal,>dass ich da irgendwas falsch verstanden habe...
So trivial der Watchdog erscheinen mag... die Tücke liegt doch manchmal
im Detail ;-)
Die sichere Vorgehensweise ist sicherlich den WDT in der aller ersten
Anweisung in main() wie gewohnt erst mal zu deaktivieren:
1
WDTCTL=WDTPW+WDTHOLD;
Dann erfolgen alle Initialisierungen, die für Deine Applikation
erforderlich sind. Erst bevor Deine eigentliche Hauptprogrammschleife
beginnt, den WDT aktivieren:
1
WDTCTL=WDTPW+WDTISx+WDTCNTCL;
und natürlich sicherstellen, dass das Zurücksetzen des WDT
1
WDTCTL=WDTPW+WDTCNTCL;
immer vor Ablauf des WDT-Intervalls geschieht.
>Hat sich das Programm aufgehängt geschieht dies nicht und es wird ein>Reset ausgeführt, oder ?
Ein PUC um genau zu sein, kein POR!
Zur Tücke:
Wenn Du viele Variablen angelegt hast und Dein Compiler meint, er müsse
diese alle erst initialisieren und dazu einen startup-code generiert,
dann wird dieser startup-code vor Deiner main() ausgeführt. Dauert
dies länger als das WDT-Intervall, dann läuft Dein µC von einem PUC in
den nächsten, ohne jemals in der main() vorbeizukommen. In dem Falle,
kannst Du nur den startup-code manuell modifizieren (WDT da drin
ausschalten) oder weniger Variablen initialisieren lassen.
Ok, es beruhigt mich schonmal, dass ich ein paar Sachen richtig
verstanden habe. Danke für eure Antworten, weil:
1. Habe ich den genauen Zeitpunkt nicht berechnet.
und
2. Gibt es tatsächlich eine Reihe von Variablen.
Jetzt werde ich mal weitertüfteln und mich ggf. nochmal melden.
Gruß
Seb
Hallo Stefan,
Eigentlich habe ich alle deine Vorschläge berücksichtigt und trotzdem
habe ich das Problem, dass mein Programm mit Watchdog unzuverlässiger
ist als ohne. Das Programm wird zwar zurückgesetzt, jedoch viel öfter
als mir lieb ist. :-)
Habe als Referenz den ACLK und ein Intervall von WDTIS0 (4 sek) gewählt.
Auch längere Intervalle brachten keine Besserung.
Nehme ich den watchdog wieder raus ist alles paletti und ich bekomme
meine Daten alle 100 ms ausgegeben.
Trotzdem brauche ich die Sicherheit, dass sich im Falle eine Falles das
Programm zurücksetzt.
Irgendwie bin ich da etwas überrascht und stehe nun aufm Schlauch.
Gruß
Seb
>Das Programm wird zwar zurückgesetzt, jedoch viel öfter>als mir lieb ist. :-)
Hört sich jetzt so an, als ob es gewollt sei, dass der WDT das Programm
zurücksetzt... das ist nicht der Sinn dabei!
Ohne weitere Informationen kann ich Dir leider auch nicht weiter helfen!
Häng doch mal Dein Programm als formatierten Code an, mit µC-Typ und
ACKL-Quelle (32kHz?)
Nein nein, so ist das natürlich nicht gewollt. Ich wollte damit nur
sagen, dass der watchdog zwar bei Problemen richtig reagiert, aber das
Programm einfach nicht mehr dazu kommt seine normalen Aufgaben zu
erfüllen.
ACLK ist 32 kHz
Programm ist insg. sehr groß. Werde vielleicht mal ein paar wichtige
Fragmente rausschneiden.
Seb wrote:
> Nein nein, so ist das natürlich nicht gewollt. Ich wollte damit nur> sagen, dass der watchdog zwar bei Problemen richtig reagiert, aber das> Programm einfach nicht mehr dazu kommt seine normalen Aufgaben zu> erfüllen.>> ACLK ist 32 kHz>> Programm ist insg. sehr groß. Werde vielleicht mal ein paar wichtige> Fragmente rausschneiden.
Was soll das bringen? Du musst dir halt überlegen, wie lang einzelne
Programmteile dauern, wenn sie richtig abgearbeitet werden. Danach dann
immer den Hund treten. Wenn das nicht passiert, hat sich das Programm
festgefahren.
Vielleicht habe ich mich missverständlich ausgedrückt, aber genau das
will ich ja erreichen.
Das Programm braucht im Normalfall Bruchteile einer Sekunde, um seine
Aufgabe zu erledigen. Ohne watchdog klappt dies zumeist auch wunderbar
(und länger als eine Minute).
Wenn ich den Hund dann wie oben erwähnt einstelle und in der main_loop
den Counter zurücksetzen lasse, kommt es fast immer zu einem verfrühten
reset des Programmes, obwohl eigentlich 4 Sekunden (ohne Zurücksetzen
des Counters) bis zu einem reset gewartet werden sollen.
So, sitze nun wieder am watchdog und das Problem bleibt das Gleiche. Der
PUC wird zu schnell ausgeführt, ergo setze ich den Timer wohl nicht
schnell genug zurück. Habe schon einige Einstellungen ausprobiert und
auch mal den Referenztakt geändert, aber das Ergebnis bleibt gleich.
Der Programmausschnitt ist gekürzt, um Übersichtlichkeit beizubehalten.
Refrenztakt ist der ACLK (32Khz). Habe ich nun mit WDTIS0 eine
"watchdog-Zeit" von 4 s eingestellt ?
1
//Interrupts initialisieren
2
3
// Initialisierung der Variablen nach Modulen:
4
5
// Variablen....
6
7
8
9
voidmain(void)
10
{
11
12
WDTCTL=WDTPW+WDTHOLD;// Watchdog stoppen
13
14
15
// Initialisierung aller nötigen Funktionen und Module :