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) <noreply@anthropic.com>
This commit is contained in:
Kaj SchittecatandClaude Opus 4.8 committed 2026-06-26 16:30:33 +02:00
1 parent bbb7d31975
commit 7498c502cc
1 file changed
+12
+12
View File
@@ -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