Você já teve problemas com travamento do microcontrolador e teve que reiniciá-lo manualmente? Vamos ajudá-lo a resolver este problema e deixar seu sistema embarcado muito mais confiável e robusto para criação de protótipos e produtos que fiquem em locais de difícil acesso. Neste texto apresentamos sobre o Watchdog Timer, com aplicação no ESP32.
Basicamente, um Watchdog Timer serve para seu sistema não permaneça travado caso ocorra alguma falha de software ou hardware e normalmente conta com um sistema independente de clock. Quase todos microcontroladores atuais contam com watchdog interno, mas para projetos e produtos mais robustos, pode ser necessário adição de watchdogs externos.
O ESP32 conta com 3 Hardware Watchdogs (HW WDT), um em cada grupo de timer e um no domínio RTC, sendo este o principal e único capaz de reiniciar completamente o ESP32.
- 4 estágios com ações e tempos independentes.
- Proteção contra escrita.
- 32 bits.
Especificamente dentro do ecossistema da IDF (incluindo Arduino Core), há três tipos de watchdogs implementados (baseados nos HW WDT) que podemos configurar facilmente, que são:
Interrupt Watchdog: Watchdog dedicado para análise de interrupções, como por exemplo o Switch Context do FreeRTOS que é responsável pelo gerenciamento de quais tarefas serão executadas. Quando você desabilita as interrupções do sistema, é ele que poderá reiniciar o ESP32. É habilitado por padrão com timeout de 300 ms e baseado no HW WDT 1.
Task Watchdog: Watchdog dedicado para análise de tarefas do FreeRTOS, como por exemplo verificar se todas suas tarefas estão sendo executadas corretamente. Este watchdog é muito interessante, pois permite que nenhuma de suas tarefas fiquem travadas, garantindo que todas estejam sendo executadas com certa frequência. É habilitado por padrão nas IDLE_TASK com timeout de 5 seg e baseado no HW WDT 0. Também pode ser habilitado ou desabilitado (reconfigurado) durante a execução do seu código.
RTC Watchdog: Watchdog dedicado para análise completa do sistema, sendo capaz de reiniciar completamente todo o ESP32. Este watchdog contém seu próprio domínio e clock (RTC_SLOW_CLK) separados do domínio digital, por isso também pode ser utilizado em Deep Sleep. É habilitado por padrão com 9 seg apenas para monitoramento do bootloader (antes da execução do app_main()), entretanto, você pode configurá-lo para continuar ativo após o bootloader e utilizá-lo em seu código, sendo o mais confiável que há internamente do ESP32. É ativo logo nas primeiras instruções do código de bootloader, sendo ativado antes de 1us após a inserção de alimentação no sistema.
Nesse artigo, abordaremos sobre o uso do Task WDT e RTC WDT, vamos fazer alguns testes!
Task Watchdog timer
Este watchdog timer é dedicado para análise individual das tarefas do FreeRTOS, garantindo que todas tarefas monitoradas não travem por elas mesmas ou por outra de maior prioridade (starvation). Quando uma tarefa não o alimenta até o tempo limite, o “Panic Handler” é invocado, que por padrão, reinicia o ESP32.
Cada tarefa monitorada precisa alimentar o watchdog, ou seja, se qualquer uma das tarefas monitoradas não alimentá-lo no tempo limite, irá reiniciar o ESP32. Vamos testar!
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_task_wdt.h>
#include <esp_log.h>
void t1(void*z)
{
esp_task_wdt_add(NULL); //Habilita o monitoramento do Task WDT nesta tarefa
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
esp_task_wdt_reset();//Alimenta o WDT
ESP_LOGI("t1", "OK");
}
}
void t2(void*z)
{
esp_task_wdt_add(NULL); //Habilita o monitoramento do Task WDT nesta tarefa
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
ESP_LOGI("t2", "OK");
}
}
void app_main()
{
esp_task_wdt_init(2, true); //Inicia o Task WDT com 2seg
xTaskCreate(t1, "t1", 2048, NULL, 1, NULL);
xTaskCreate(t2, "t2", 2048, NULL, 1, NULL);
}
Nesse código, há 2 tarefas em execução atribuídas ao Task WDT (t1 e t2) sendo que a “t2” não está alimentando corretamente o watchdog timer, ocasionando reinício do sistema. Observe na figura abaixo que é escrito qual tarefa ocasionou o reinício e quais estavam executando no momento do reinício.
RTC Watchdog
Este watchdog timer é dedicado para análise completa do ESP32, garantindo que todo sistema não fique travado, como por exemplo através de ruídos de alimentação, falha de CPU e etc.
A IDF o utiliza (por padrão) apenas durante o bootloader e é desativado antes do app_main(), entretanto, nós podemos habilitá-lo para permitir controle do usuário. Para isso, basta ativá-lo em “menuconfig > bootloader config > Allows RTC WDT disable in user code”.
Habilitando esta opção, ele não é mais desabilitado antes do app_main() e continuará rodando, ou seja, se você não alimentá-lo, irá reiniciar completamente todo o ESP32.
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <soc/rtc_wdt.h>
#include <esp_log.h>
void app_main()
{
while (1)
{
rtc_wdt_feed(); //Alimenta o RTC WDT
ESP_LOGI("Teste", "OK");
vTaskDelay(pdMS_TO_TICKS(900));
}
}
O código acima efetua a alimentação do RTC WDT antes do seu tempo limite (1000 ms), porém, se você aumentar o delay ou comentar a linha de alimentação, causará o reinício do ESP32.
Conclusão: Watchdog Timer
É sempre importante manter o watchdog timer habilitado em todos seus projetos. Há inúmeros métodos para implementar os watchdogs internos do ESP32 e garantir que seu projeto ou produto não ficará travado por falhas de software ou hardware, mas não se esqueça, ele não resolve a causa do problema, sendo utilizado apenas como uma emergência. Você sempre deve resolver a causa dos travamentos do seu sistema e não utilizar o watchdog como uma simples saída.
Saiba mais sobre ESP32
ESP32 – conhecendo os pinos de Strapping





show!
Parabéns pelo post, eles são sempre relevantes.
Muito Bom. Vou passar a utilizar o RTC.
Muito Bom, vou passar a utilizar o RTC
Muito útil. Vou passar a utilizar o RTC
José, artigo muito bom! Parabéns!