ÍNDICE DE CONTEÚDO
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!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#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.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#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
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!