Prevenire blocchi di esecuzione con il timer watchdog ESP32
I microcontrollori sono spesso utilizzati in ambienti caratterizzati da transitori sulle linee d’alimentazione, interferenze elettromagnetiche e scariche elettrostatiche.
Queste condizioni possono causare la corruzione delle istruzioni in esecuzione a causa delle interferenze elettromagnetiche accoppiate al bus, che possono portare a un esecuzione errata delle istruzioni.
In questi ambienti, un watchdog timer è una preziosa periferica che può essere usata in caso di uno stallo del processore resettandolo per farlo ritornare in uno stato noto.
Il watchdog timer è un semplice contatore, configurato nella fase di setup del microcontrollore tramite dei registri interni, è utilizzato per resettare un dispositivo programmabile, dopo un intervallo di tempo specifico.
In un sistema dove non sono presenti dei problemi e il codice è stato scritto correttamente, il software periodicamente azzera il contatore, facendo ripartire il watchdog timer.
Se il software o il dispositivo non dovesse funzionare correttamente, oppure il codice rimane bloccato in un loop infinito, il software non potrà riavviare il watchdog timer prima che il suo conteggio arrivi al massimo valore preconfigurato, A questo punto, il watchdog resetterà il microcontrollore.
È evidente che il reset del microcontrollore non deve includere azioni che devono essere eseguite solo all’accensione iniziale. Pertanto, dobbiamo progettare il nostro sistema in modo che il reset non causi malfunzionamenti.
Il timer watchdog utilizza l’oscillatore a cristallo ad alta precisione del microcontrollore.
Il funzionamento del watchdog è indipendente dal microcontrollore è una periferica interna al chip.
L’utilizzo principale di un timer watchdog è quello di sorvegliare il sistema da eventuali blocchi di esecuzione del codice.
Dobbiamo considerare che non sempre il reset del microcontrollore può risolvere problemi come un danno alla memoria dei dati.
E’ possibile comunque scrivere un codice che esegua una autodiagnosi delle periferiche delle proprie periferiche, questo argomento sarà approfondito in un futuro articolo.
Il microcontrollore ESP32 supporta diversi tipi di watchdog, ma i due più importanti sono l’Interrupt Watchdog Timer (IWDT) e il Task Watchdog Timer (TWDT).
Queste due tipologie di watchdog possono essere abilitati nel setup del progetto, ma solo il TWDT può anche essere attivato nel loop del progetto.
Codice
#include <esp_task_wdt.h> //3 secondi watchtdog #define WDT_TIMEOUT 3 void setup() { Serial.begin(115200); Serial.println("configuriamo il watchdog..."); esp_task_wdt_init(WDT_TIMEOUT, true); //abilitiamo il watchdog esp_task_wdt_add(NULL); } int i = 0; int last = millis(); void loop() { // resettiamo il watchdog ogni 2 secondi, per solo 5 volte alla sesta volta l'ESP32 si deve resetatre if (millis() - last >= 2000 && i < 5) { Serial.println("Resettiamo WDT..."); esp_task_wdt_reset(); last = millis(); i++; if (i == 5) { Serial.println("l'ESP32 deve resettarsi dopo 3 secondi"); } } }
#include <esp_task_wdt.h>
Questa libreria fornisce le funzionalità per il watchdog timer (task watchdog timer).
#define WDT_TIMEOUT 3
La macro definisce la costante chiamata “WDT_TIMEOUT” con il valore di 3.
Questa costante sarà utilizzata per impostare il tempo di timeout per il watchdog timer.
Il tempo di timeout specifica il tempo in secondi per il quale il watchdog farà scattare l’interrupt e il reset del microcntrollore.
In questo caso, verrà impostato a 3 secondi.
esp_task_wdt_init(WDT_TIMEOUT, true)
Inizializza il watchdog timer.
Questa funzione accetta due argomenti:
- WDT_TIMEOUT: Questo è il tempo di timeout specificato dalla costante che abbiamo visto in precedenza.
- true: Specifica se il watchdog timer deve essere attivato o meno. Se viene impostato su “true”, il watchdog timer del task è attivato e inizierà il suo conteggio.
esp_task_wdt_add(NULL);
registra il task corrente al watchdog timer del task (TWDT).
Ogni volta che il task viene eseguito, è importante che richiami periodicamente la funzione “esp_task_wdt_reset()” per impedire al TWDT di raggiungere il suo periodo di timeout.
In caso contrario, si verificherà un timeout TWDT e il task verrà terminato.
esp_task_wdt_reset()
è usata per resettare il conteggio del TWDT per il task corrente, garantendo che il TWDT non termini il task a causa di un blocco indesiderato e che il sistema continui a funzionare correttamente.
if (millis() – last >= 2000 && i < 5) {
Serial.println(“Resettiamo WDT…”);
esp_task_wdt_reset();
last = millis();
i++;
if (i == 5) {
Serial.println(“l’ESP32 deve resettarsi dopo 3 secondi”);
}
Con queste istruzioni simuliamo un blocco del codice e verifichiamo il reset dell’ESP32 dopo cinque inizializzazioni del contatore di watchdog.
Conclusioni
Se avete delle domande non esitate a contattarmi nel form di seguito.
Buon lavoro.