From 7498c502cca2f8d8f95071024acab727bf7bec67 Mon Sep 17 00:00:00 2001 From: Kaj Schittecat Date: Fri, 26 Jun 2026 16:30:33 +0200 Subject: [PATCH] touch: widen task-watchdog grace to 20s to stop flash-op WDT reboots (#56) Decoded coredumps (device + the beta_16 ELFs) are all task-watchdog panics: CPU0=IDLE0 CPU1=IDLE1, core 0 in spi_flash_op_block_func. A legitimate-but-slow flash burst (SPIFFS GC, or a bulk DataStore save = thousands of writes) parks both cores with the cache disabled, starving both IDLE tasks past the ~5s default so the TWDT panics. The burst can't be chunked under the limit easily and the per-core WdtHeavyGuard only covers core 0, so re-init the TWDT with a 20s grace (still catches a genuine multi-second hang) instead. esp_task_wdt_init re-init reconfigures the running TWDT (old API on this arduino-esp32). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/main.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index d770f0b3..02e342db 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -151,11 +151,23 @@ void halt() { unsigned long last_wifi_reconnect_attempt = 0; #endif +#include "esp_task_wdt.h" // task-watchdog reconfigure — see setup() (GH #56) + void setup() { Serial.begin(115200); delay(200); Serial.println("[BOOT] setup start"); + // Widen the task-watchdog grace period. The ~5 s default trips during a legitimate-but-slow flash + // burst — a SPIFFS garbage-collect, or a bulk save (DataStore issues ~12 flash ops per contact, + // thousands for a full address book). A flash op parks BOTH cores with the cache disabled, so both + // IDLE tasks miss their reset and the watchdog panics (decoded coredumps: task_wdt CPU0=IDLE0 + // CPU1=IDLE1, core 0 in spi_flash_op_block_func). The burst can't be chunked under the limit easily + // and the per-core WdtHeavyGuard only covers core 0, so give the dog enough headroom to ride the + // burst out while still catching a genuine multi-second hang. (Fixes the random WDT reboots, GH #56.) + esp_task_wdt_init(20, true); // 20 s grace (was ~5 s), keep panic. Re-init reconfigures the + // already-running TWDT + keeps the idle-task subscriptions. + #if defined(ESP32_PLATFORM) && defined(HAS_TOUCH_UI) // Record which slot we booted from so the recovery's "Boot firmware" can return // here. Recovery-first itself is enforced by the CUSTOM bootloader (it boots