Forum: Mikrocontroller und Digitale Elektronik Arduino Nano Watchdog Boot Loop


von Benedikt S. (benedikt_s)


Lesenswert?

Hallo Zusammen,

Ich habe mittlerweile eine etwas umfangreicheres Arduino Programm (board 
China Arduino nano clone MEGA328P AU1511)geschrieben welches 
selbstständig länger laufen soll. Daher würde ich gerne den Watchdog 
verwenden um ein lockup zu verhindern.

Ich habe den Watchdog nach dieser Anleitung.
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_Watchdog
implementiert.

Der Watchdog resetet den µC auch wenn die Zeit überschritten ist leider 
häng der Arduino nach dem watchdogrestet scheinbar in einem bootloop 
fest, es passiert nichts mehr nur die LED bilnkt.

Da der Watchdog presaceler warscheinlich auf den minimalen Wert zurück 
gesetzt wird.

Hier ist eine Lösung für dieses Problem beschrieben: 
https://andreasrohner.at/posts/Electronics/How-to-make-the-Watchdog-Timer-work-on-an-Arduino-Pro-Mini-by-replacing-the-bootloader/

Ich habe aber eigentlich keine Lust den Bootloder zu flashen, darum die 
Frage gibt es eine andere Möglichkeit dieses Problem zu beheben ?

P.s. Wenn ich den Arduino per Resetbutton restete funktioniert alles.

: Bearbeitet durch User
von Sascha (Gast)


Lesenswert?

Ich denke nicht.

Der Bootloader wartet eine gewisse Zeit beim Start um zu gucken ob der 
Benutzer flashen will.
Erst danach wird das eigentlich Programm ausgeführt.

Wenn der Watchdog Timer schneller volläuft als die Bootloader 
Warteperiode ist, passiert der Bootloop.

Da deine Software an der Stelle gar nicht ausgeführt wird, hast du keine 
Chance daran was zu ändern.

Aber es gibt die Möglichkeit (siehe Datenblatt Seite 53ff) dass der WD 
keinen System Reset sondern einen Interrupt ausführt. In diesem 
Interrupt könntest du dann erst den WD abschalten (siehe besondere 
Abschaltprozedur) und dann den Reset selbst veranlassen (Falls das geht, 
reicht es dafür, zum Reset_vect zu springen?).

von U. C. (Gast)


Lesenswert?

Sascha schrieb:
> In diesem Interrupt könntest...
Es gibt keinerlei Garantie, das der an die Reihe kommt.

von Sascha (Gast)


Lesenswert?

Deswegen fing mein Post ja auch mit "Ich denke nicht." an. Aber 
ausprobieren kann auch nicht schaden.

von Stefan F. (Gast)


Lesenswert?

Du musst den Watchdog nicht unbedingt per Fuse aktivieren. Du kannst ihn 
auch am Anfang deines Programms per Software aktivieren (WDE). Dann 
stört der Bootloader nicht.

von Wolfgang A. (Gast)


Lesenswert?

Benedikt S. schrieb:
> Der Watchdog resetet den µC auch wenn die Zeit überschritten ist leider
> häng der Arduino nach dem watchdogrestet scheinbar in einem bootloop
> fest, es passiert nichts mehr nur die LED bilnkt.

Und wenn die Zeit nicht überschritten wird also wenn der Watchdog so 
langsam eingestellt wird dass er die Wartezeit übersteht?

von Benedikt S. (benedikt_s)


Lesenswert?

Hallo zusammen,

Danke für die Hinweise.

Wenn ich Tabelle 11.1 in diesem 
DB(http://www.atmel.com/images/atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet_complete.pdf) 
richtig deute ist

WDTON 1 WDE 1 WDIE 1 genau das was ich möchte
1
WDTCSR = (1<<WDCE) | (1<<WDE) | (1<<WDIE)|(1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0);
zusammen mit
1
ISR(WDT_vect) {
2
wdt_disable();
3
}

Sollte tuen was ich möchte aber leider klappt es nicht, der reset wird 
nicht ausgelöst.
Ich denke das ich einen Fehler mit dem  WDCE bit mache.

Könnt ihr mir weiter helfen ?

P.s. @Wolfgang A. die WDP bits werden leider beim reset auf 0000 zurück 
gesetzt dies entspricht 16ms

: Bearbeitet durch User
von Einhart P. (einhart)


Lesenswert?

Du hast die Lösung schon gefunden: Optiboot. Damit geht's.

von Sascha (Gast)


Lesenswert?

Du musst beim Ändern von WD Bits einen speziellen Vorgang ausführen, der 
verhindern soll dass man den versehentlich abschaltet.

Du musst WDCE setzen, dann ein Bit wie WDE ändern und die Hardware setzt 
WDCE dann automatisch wieder auf 0.
Du hast 4 CPU Takte Zeit, die Bits zu ändern die du ändern willst.

So wie ich das sehe, machst du das richtig. Allerdings:

"
The Watchdog always on (WDTON) fuse, if programmed, will force the 
Watchdog Timer to System Reset mode.
With the fuse programmed the System Reset mode bit (WDE) and Interrupt 
mode bit (WDIE) are locked to 1
and 0 respectively.
"

heisst: Die Bits lassen sich nicht ändern wenn die Fuse gesetzt ist.

Das Interrupt-Verhalten kannst du scheinbar nur erreichen, wenn die Fuse 
nicht programmiert ist und du den WD per Software aktivierst (Zu Beginn 
deiner main()).

von Stefan F. (Gast)


Lesenswert?

Du fängst den Watchdog ja auch per Interrupt ab und deaktivierst ihn 
dann auch noch in der ISR.

Lass die ISR doch ganz weg, wenn du einen Reset haben willst.

von U. C. (Gast)


Lesenswert?

Einhart P. schrieb:
> Du hast die Lösung schon gefunden: Optiboot. Damit geht's.
Sehe ich auch so...

Oder ganz auf den Bootloader verzichten...

von Sascha (Gast)


Lesenswert?

Er will den Reset ja, aber im Moment des Reset soll der WD deaktiviert 
werden, damit das beim Bootloader nicht zum Loop führt.

Denn nach dem WD Reset sind die Prescaler Bits alle auf 0, was 16ms 
entspricht.

Wenn das hier nicht funktioniert wäre ich auch für einen anderen 
Bootloader, ist schließlich ein Bug und kein Feature wenn der Bootloader 
nicht zusammen mit dem WD funktioniert.

von Benedikt S. (benedikt_s)


Lesenswert?

Sascha hat mein Problem exakt zusammen gefasst.

Ich habe das Problem so leider nicht lösen können und werde mir einfach 
aus einem anderen Arduino eine Programmer basteln, ich sollte sowieso 
einen haben kann man bestimmt immer mal gebrauchen.

von Stefan F. (Gast)


Lesenswert?

Ach so. Dann müsste er die ISR verwenden, dort den Watchdog aus schalten 
und dann einen Reset auslösen. Ich glaube, das geht nicht nur mit 
Software. Aber vielleicht, indem man einen Output Pin mit dem Reset 
Eingang verbindet und den dann in der ISR auslöst.

von Sascha (Gast)


Lesenswert?

Laut Datenblatt sollte das gehen. Es gibt einen Modus, wo erst ISR und 
dann System Reset ausgelöst wird. In genau dieser Reihenfolge.

von U. C. (Gast)


Lesenswert?

Sascha schrieb:
> Laut Datenblatt sollte das gehen. Es gibt einen Modus, wo erst ISR und
> dann System Reset ausgelöst wird. In genau dieser Reihenfolge.

Das wissen wir/ich!
Aber das geht doch am Sinn und Zweck eines WDT vorbei. Zumindest in 
diesem Fall.
Hier sollen Programmhänger gefangen werden. Und da ist eine ISR keine 
Hilfe, weil nicht garantiert werden kann, dass sie auch aufgerufen wird. 
Und wenn das nicht garantiert werden kann, ist sie keine Hilfe, beim 
Verhindern des WDT Reset.
(doppelt hält besser)

Daraus folgt, sie ist flüssiger als Wasser: Überflüssig.

von Benedikt S. (benedikt_s)


Lesenswert?

Ich habe mir eben einen ISP aus einem Anderen Nono gebastelt.

Ich kann damit auch die normalen Arduino Bootloader Flashen.

Ich verwende sowohl von der Arduino IDe als von optiboot die Aktuellste 
version und Als OS Win 10.

Wenn ich aber den optibootloader flashen möchte bekomme ich eine 
Nulpointerexception:

java.lang.NullPointerException
  at 
cc.arduino.packages.uploaders.SerialUploader.burnBootloader(SerialUpload 
er.java:314)
  at 
processing.app.Editor.lambda$handleBurnBootloader$42(Editor.java:2754)
  at java.lang.Thread.run(Thread.java:745)
Fehler beim Brennen des Bootloaders.

Könnte ich die HEX Datei des bootloaders auch über das Atmel Studio mit 
einem Arduino als ISP flashen ? Wenn ja wie ?

von U. C. (Gast)


Lesenswert?

Benedikt S. schrieb:
> Könnte ich die HEX Datei des bootloaders auch über das Atmel Studio mit
> einem Arduino als ISP flashen ? Wenn ja wie ?

Das geht auch "zufuß" mit avrdude.
Beachte, dass evtl. auch die Fuses passend gesetzt werden wollen.

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.