Domanda:
Il timer watchdog è bloccato nel ciclo di riavvio? (led verde lampeggiante)
DominicM
2014-06-13 00:55:13 UTC
view on stackexchange narkive permalink

Sto cercando di impostare un modo per riavviare arduino a comando. Il codice seguente dovrebbe farlo, ma sembra che il mio arduino sia bloccato in una sorta di ciclo in cui non riesco a caricare o ottenere alcun output seriale. Il led verde (pin 13) lampeggia molto velocemente. L'unico modo per fermarlo è interrompere l'alimentazione al dispositivo, anche il pulsante di ripristino non funziona. Questo accade solo quando "R" viene ricevuto via seriale o se la funzione wdt_reset () è commentata.

  #include <avr / io.h> # include <avr / wdt.h>int ledPin = 3; void setup () {MCUSR = 0; wdt_disable (); Serial.begin (57600); Serial.println ("BOOT!"); pinMode (ledPin, OUTPUT); digitalWrite (ledPin, LOW); delay (500);} void loop () {if (Serial.available () > 0) {char cmd = Serial.read (); if (cmd == 'R') {Serial.println ("R ricevuto!"); wdt_enable (WDTO_1S); ritardo (2000); Serial.println ("1 SEC."); }} wdt_reset (); digitalWrite (ledPin, HIGH);}  

Cosa sto facendo di sbagliato?

Penso di essermi imbattuto in questo un po 'di tempo fa, per caricare un nuovo schizzo (senza il materiale del watchdog) ho tenuto premuto il pulsante di ripristino fino a poco prima che l'IDE iniziasse il suo stato di "caricamento".
Vedi anche la nota in fondo a questo post: http://ariverpad.wordpress.com/2012/02/26/resetting-the-arduino-through-software-for-fun-and-profit/
@sachleen sì, ho seguito quella scrittura ma sono un po 'confuso dove va quel codice. Presumo che non vada nello schizzo? Preferirei non modificare i file sorgente in quanto ciò influirebbe su ogni arduino che programma.
Sì, ciò modificherebbe il bootloader e influirebbe anche su altri schizzi, ma solo se stai usando il watchdog.
@sachleen Ciò significa che il bootloader dovrebbe essere nuovamente aggiornato?
Quattro risposte:
#1
+4
Nahkki
2014-06-13 02:03:12 UTC
view on stackexchange narkive permalink

Uno dei problemi più ovvi qui è che stai abilitando il timer watchdog con un ritardo di 1S e poi chiedi al microcontrollore di dormire per 2S, stampando qualcosa e poi tornando nel ciclo. Questo, in teoria, dovrebbe andare bene (il tuo wdt dovrebbe attivare un riavvio durante i 2 secondi di attesa) ma ho visto che causa problemi.

Inoltre alcuni bootloader (in particolare il bootloader Optiboot su Uno e schede più recenti ) possono avere problemi con i timer watchdog che fanno sì che il wdt rimanga abilitato dopo il ripristino anche se il ciclo di installazione lo disabilita. Per cominciare, prova ad aumentare il tempo wdt a qualcosa di più grande di 2S (dovresti essere in grado di fare WDTO_8S) e vedere se il problema persiste.

EDIT - L'OP sta usando un clone di Arduino Pro Mini. Il bootloader incluso su Arduino Pro Mini non supporta i riavvii del sistema da parte del WDT. In sostanza, su un dispositivo con un bootloader che non supporta i riavvii WDT, la scheda si riavvierà ma il timer / ripristino non causerà il ripristino continuo della scheda al riavvio. Esistono bootloader alternativi per le schede Arduino che potrebbero risolvere questo problema. Un'altra soluzione è utilizzare un metodo diverso per riavviare la scheda.

Quindi, se può causare problemi, quale metodo non causa problemi? Ho appena provato 8 secondi con 9 secondi di ritardo con gli stessi risultati. 8 secondi sarebbero comunque troppo lunghi poiché in realtà non ho bisogno di alcun ritardo dopo il comando seriale.
Una delle prime domande sarebbe: che scheda è e quale bootloader stai utilizzando? Inoltre, cosa succede con una versione più semplice del codice watchdog? Ad esempio uno che non sta leggendo un input ma sta piuttosto ripetendo un'istruzione print n volte e poi resetta? Qui (http://www.megunolink.com/how-to-detect-lockups-using-the-arduino-watchdog/) è un esempio di un utilizzo molto semplice del timer watchdog: cosa succede quando esegui qualcosa di simile ?
Sto usando arduino pro mini clone con bootloader predefinito (non sono sicuro di cosa sia). Con il campione copiato incollato dal collegamento si blocca lo stesso dopo un paio di secondi dopo l'accensione.
Un rapido google sul tuo prodotto mostra ad altri lo stesso problema. Il bootloader su Arduino Pro Mini non supporta i riavvii del sistema supportati dal timer watchdog. Essenzialmente riavviano il sistema ma non riavviano il timer causando il reset continuo della scheda al riavvio. Non ho usato un Arduino Pro mini né ho avuto molta fortuna con offbrand (niente di sbagliato in loro, solo sfortuna da parte mia) quindi non posso raccomandare un altro bootloader a mano libera ma una rapida ricerca su Google mostra che ci sono persone che lo hanno trovato un bootloader funzionante per il dispositivo che supporta WDT.
Il bootloader è necessario per il watchdog? Potrei sbarazzarmi del tutto del bootloader, a patto che posso programmarlo tramite Bluetooth che sarebbe l'opzione migliore per me.
Questo probabilmente non risolverà il tuo problema. Non è che il bootloader sia il problema: è l'implementazione del WDT nel bootloader e il modo in cui il bootloader gestisce gli eventi WDT il problema. Liberarsi del bootloader non elimina il problema: lo cambia semplicemente in modo che tu debba implementare la gestione di WDT da solo. È certamente possibile masterizzare uno schizzo su un arduino senza il bootloader ([Here] (http://www.arduino.cc/en/Hacking/Programmer) è un po 'di documentazione a riguardo.) Ma senza un bootloader non sarai in grado di caricare uno schizzo tramite bluetooth.
C'è un motivo particolare per cui stai usando un WDT per ripristinare arduino? Esistono molti altri metodi ([qui] (http://www.instructables.com/id/two-ways-to-reset-arduino-in-software/?ALLSTEPS) è un'istruzione che descrive questi metodi) che potresti usare che aggirare questo problema.
WDT è l'unica soluzione software, ma immagino che utilizzerò uno dei pin per attivare il ripristino.
#2
+2
Chupo_cro
2017-10-04 07:11:43 UTC
view on stackexchange narkive permalink

Abilitare il riavvio del sistema del timer di watchdog e attendere in un ciclo fino al ripristino è un modo legittimo di resettare SW di µC così come usare watchdog per rilevare il comportamento scorretto di µC che può essere causato da vari motivi.

Tuttavia, alcuni devono essere prese precauzioni quando si utilizza il ripristino del sistema watchdog perché su tutti gli AVR che hanno anche watchdog interrompono il watchdog con prescaler impostato a 0000 = 16 ms rimane attivo dopo la condizione di ripristino del sistema watchdog. È quindi responsabilità di un programmatore cancellare MCUSR e disabilitare il timer watchdog il prima possibile dopo il verificarsi di tale condizione. Poiché le routine LPM per l'inizializzazione delle sezioni .data e .bss possono durare più a lungo dell'intervallo di timeout del watchdog, il codice per disabilitare il watchdog deve essere inserito nella sezione .init3 e il contenuto di MCUSR può facoltativamente essere salvato per un successivo esame della sorgente di ripristino. Ecco il codice che esegue le operazioni descritte:

  uint8_t mcusr_copy __attribute__ ((section (".noinit"))); void disable_wdt (void) \ __attribute __ ((naked)) \ __attribute __ ((section (". init3"))); void disable_wdt (void) {mcusr_copy = MCUSR; MCUSR = 0x00; wdt_disable ();}  

Tuttavia, il problema può sorgere quando si utilizza un bootloader che non tiene conto della possibilità di una condizione di ripristino del sistema watchdog. In questo caso, il timeout del watchdog avverrà all'interno del bootloader (che viene eseguito per primo) prima che il codice sopra abbia la possibilità di disabilitare il timer del watchdog e µC rimarrà bloccato in un ciclo infinito di reset. Poiché la reimpostazione del µC non cancellerà il flag WDRF nel registro MCUSR (può essere cancellato solo nel software o con il ripristino all'accensione) l'unico il modo sarà quindi di accendere e caricare un nuovo codice quando il timer del watchdog non è ancora attivato dal codice precedente. WDRF nel registro MCUSR deve essere cancellato prima di wdt_disable () perché WDE non può essere cancellato se WDRF è ancora impostato - quindi l'ordine delle istruzioni nel codice sopra è molto importante. La funzione inserita nella sezione .init3 non deve essere chiamata dal codice successivo.

#3
  0
geometrikal
2014-06-15 02:51:53 UTC
view on stackexchange narkive permalink

Puoi riavviare Arduino con questo comando:

  asm volatile ("jmp 0");  
Questo fa solo il soft reset e non lo ripristinerà completamente ai valori predefiniti.
#4
  0
Albertobozal
2018-10-16 18:43:46 UTC
view on stackexchange narkive permalink

Rimuovere il flag watchdog su init è una soluzione. Sto usando optiboot 8.0 e funziona perfettamente.

  // Funzione Pototypevoid wdt_init (void) __attribute__ ((naked, used, section (". Init3"))); // Implementazione della funzionevoid wdt_init (void) {MCUSR = 0; wdt_disable (); ritorno;}  


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...