Я использую встроенный программный сторожевой таймер Atmega328, как описано здесь .
Моя цель — ограничить выполнение части кода двумя секундами, что может привести к бесконечным вычислениям.
Это схема псевдокода:
enable watchdog (2 seconds)
run may-be-endless code
clear watchdog
run the rest
Остальная часть кода должна быть запущена, если код, который может быть бесконечным, успеет выполниться за заданное количество времени, в противном случае необходимо перезапустить всю программу.
Это код Arduino, который я загрузил в плату:
#include <avr/wdt.h>
void setup() {
Serial.begin(9600);
Serial.println("Started");
wdt_enable(WDTO_2S);
Serial.println("watchdog ON");
wdt_reset();
Serial.println("watchdog OFF");
}
void loop(){
Serial.println("loop...");
delay(1000);
}
На этом этапе ожидаемым результатом должна быть бесконечная печать loop...
сообщений после тех, что указаны в настройках ( Started
, watchdog ON
/ OFF
).
Удивительно, но вместо этого я получаю следующее:
Started
watchdog ON
watchdog OFF
loop...
loop...
loop...
Started
watchdog ON
watchdog OFF
loop...
loop...
loop...
Started
watchdog ON
watchdog OFF
loop...
loop...
[...]
По-видимому, сторожевой таймер устанавливается, но не может быть очищен. Почему?
wdt_reset()
не отключает сторожевой таймер, он просто сбрасывает свой таймер, задерживая истечение срока действия.
Вы, наверное, хотите
wdt_disable()
Тем не менее, ваш общий подход может быть не самым разумным - позволить сторожевому таймеру истечь, может быть умно, но это также довольно тяжело по сравнению с такими подходами, как использование обычного прерывания таймера или ограничение вашего кода. Обычно сторожевой таймер предназначен для непредвиденных ошибок.
Чтобы отключить сторожевой таймер, вызовите wdt_disable() . Все wdt_reset()
, что нужно сделать, это сбросить тайм-аут сторожевого таймера, что в вашем случае избыточно: вы просто включаете его двумя строками выше. wdt_reset()
не выключает сторожевой таймер (в отличие от вашего серийного вывода).
Этуарду
wdt_disable
раньше, это было так просто. Меня отвлекли несколько руководств, которые я прочитал, в которых говорилось, что этоwdt_reset
так, а также документация была для меня немного двусмысленной.