feat(firmware): enable task watchdog on camera/reporter/loop tasks

30s TWDT subscribes all three long-running tasks and panics on hang.
The reporter task's retry loop explicitly feeds between attempts so
the 3-try sequence (worst case 52s) does not itself trip the dog.
Reset reason on next boot is visible via esp_reset_reason() which
EVT_BOOT already logs.
This commit is contained in:
2026-04-23 13:49:05 -07:00
parent 8f8ad0b1b0
commit 7b546d0ed7
2 changed files with 18 additions and 3 deletions

View File

@@ -11,6 +11,7 @@
#include "event_log.h"
#include "net_guard.h"
#include <esp_system.h>
#include <esp_task_wdt.h>
// LED on GPIO2 (TimerCamera-F built-in LED) — verify against board schematic
// Factory reset: hold GPIO37 (BOOT button) for 5 seconds
@@ -53,6 +54,7 @@ static void check_factory_reset() {
ESP.restart();
}
delay(50);
esp_task_wdt_reset();
}
}
@@ -60,6 +62,7 @@ static void check_factory_reset() {
static void task_camera(void*) {
static uint8_t frame[CV_PIXELS]; // static: avoids 9KB on task stack
int last_logged_track_id = 0; // diagnostic: log each new track once
esp_task_wdt_add(nullptr);
while (true) {
if (camera_capture_96(frame)) {
if (xSemaphoreTake(s_cv_mutex, pdMS_TO_TICKS(100)) == pdTRUE) {
@@ -86,15 +89,18 @@ static void task_camera(void*) {
}
}
vTaskDelay(pdMS_TO_TICKS(CAM_INTERVAL_MS));
esp_task_wdt_reset();
}
}
// Hourly reporter task — runs on core 0
static void task_reporter(void*) {
uint32_t last_report_ts = 0; // 0 = not initialized yet
esp_task_wdt_add(nullptr);
while (true) {
vTaskDelay(pdMS_TO_TICKS(10000)); // check every 10s
esp_task_wdt_reset();
uint32_t now = (uint32_t)(time(nullptr));
if (now < 1700000000UL) continue; // NTP not synced
@@ -203,11 +209,17 @@ void setup() {
s_cv_mutex = xSemaphoreCreateMutex();
// Task watchdog: 30s timeout, panic on trigger so we reboot and log
// via esp_reset_reason() in EVT_BOOT on the next boot.
esp_task_wdt_init(30, /*panic=*/true);
esp_task_wdt_add(nullptr); // subscribe the Arduino loopTask
xTaskCreatePinnedToCore(task_camera, "cam", 8192, nullptr, 2, nullptr, 1);
xTaskCreatePinnedToCore(task_reporter, "rep", 8192, nullptr, 1, nullptr, 0);
}
void loop() {
esp_task_wdt_reset();
ArduinoOTA.handle();
check_factory_reset();
net_guard_tick();