ОБНОВЛЕНИЯ
- v2.1
ТЕОРИЯ
Watchdog (англ. сторожевой пёс) – отдельный таймер на микроконтроллере, который имеет собственный источник тактирования и ни от кого не зависит. По данному таймеру можно ловить прерывания и использовать их в своих целях, а также он может перезагрузить микроконтроллер в случае зависания. Внимание! WDT для перезагрузки МК поддерживают не все загрузчики! Смотрите пример с проверкой работоспособности. Обычные прерывания по вочдогу работают на всех загрузчиках.
БИБЛИОТЕКА
УСТАНОВКА
- Библиотеку можно найти и установить через менеджер библиотек по названию GyverWDT в:
- Arduino IDE (Инструменты/Управлять библиотеками)
- Arduino IDE v2 (вкладка «Library Manager»)
- PlatformIO (PIO Home, вкладка «Libraries»)
- Про ручную установку читай здесь
ДОКУМЕНТАЦИЯ
Список функций
void reset(void); // сброс void disable(void); // отключить WDT void enable(uint8_t mode, uint8_t prescaler); // включить WDT с настройками // mode: // RESET_MODE - сброс при зависании (при тайм-ауте WDT) // INTERRUPT_MODE - прерывание при зависании (при тайм-ауте WDT) // INTERRUPT_RESET_MODE - первый таймаут - прерывание, второй - сброс // prescaler: // WDT_PRESCALER_2, WDT_PRESCALER_4... WDT_PRESCALER_1024
ПРИМЕРЫ
Остальные примеры смотри в папке examples библиотеки, также примеры можно открыть из Arduino IDE/Файл/Примеры
Проверка работоспособности WDT для reset
#include "GyverWDT.h" /* Пример тестирующий поддержку всех функций watchdog на вышем устройстве > После 10 секунд отсчета программа стартует заного -> поддерживаются все функции > После таймаута устройство зависает, светодиод на D13 начинает мигать -> подерживается только INTERRUPT_MODE В случае bootloop у вас будет 10 секунд на перепрошивку устройства после подачи питания Для добавления поддержки всего функционала watchdog загрузите optiboot или откажитесь от загрузчика */ void setup() { Serial.begin(9600); Serial.println("Program started , wait 10 seconds"); delay(10000); // 10 секунд на перепрошивку в случае bootloop Watchdog.enable(RESET_MODE, WDT_PRESCALER_1024); // Режим сторжевого сброса , таймаут ~8с Serial.println("watchdog enabled"); while (1) { // Бесконечный цикл , эмуляция "зависания" if (!(millis() % 1000)) { // Каждую секунду Serial.println((uint16_t)((millis() / 1000) - 10)); // Вывести время после включения watchdog в секундах delay(10); } } } void loop() {}
WDT как источник прерываний
#include "GyverWDT.h" /* Пример использования watchdog в качестве генератора прерываний Зависимость таймаутов от делителей см. в GyverWDT.h */ void setup() { Serial.begin(9600); pinMode(13, OUTPUT); Watchdog.enable(INTERRUPT_MODE, WDT_PRESCALER_128); // Режим генерации прерываний , таймаут ~1с } void loop() { /* Загруженный цикл */ digitalWrite(13, HIGH); delay(5000); digitalWrite(13, LOW); delay(5000); } /* Прерывание watchdog */ ISR(WATCHDOG) { Serial.println("Hello from interrupt"); }
Перезагрузка при зависании
#include "GyverWDT.h" /* Пример классического применения watchdog - сброс устройства при зависании Если не вызвать Watchdog.reset() вовремя - произойдет сброс Зависимость таймаутов от делителей см. в GyverWDT.h */ void setup() { pinMode(13, OUTPUT); Watchdog.enable(RESET_MODE, WDT_PRESCALER_512); // Режим сторжевого сброса , таймаут ~4с } void loop() { /* Ваш полезный код */ digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); Watchdog.reset(); // Переодический сброс watchdog, означающий, что устройство не зависло }
Комбинированный режим (прерывание + ресет)
#include "GyverWDT.h" /* Пример использования watchdog в комбинированном режиме Может использоваться для оповещения в случае зависания Первый тайм-аут вызывает прерывание, второе - сброс Перенастройте watchdog чтобы избежать сброса Зависимость таймаутов от делителей см. в GyverWDT.h */ void setup() { Serial.begin(9600); Serial.println("Program started"); Watchdog.enable(INTERRUPT_RESET_MODE, WDT_PRESCALER_128); // Комбинированный режим , таймаут ~1c Serial.println("watchdog enabled"); while (1); // Причина зависания Serial.println("loop started"); // Этого мы не увидим из-за зависания } void loop() { /* этого кода программа не достигнет - зависание в setup */ Serial.println("hello"); delay(500); } /* Первый тайм-аут вызывает прерывание */ ISR(WATCHDOG) { // Если причина зависания программная - тут можно попытаться исправить ее */ Serial.println("warning!"); // Если исправить причину не вышло - следующий таймаут вызывает сброс // Watchdog.enable(INTERRUPT_RESET_MODE, WDT_PRESCALER_128); // Если перенастроить watchdog здесь - сброса не будет }
ПОДДЕРЖАТЬ
Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.
0
0
голоса
Рейтинг статьи