From 0750f5182e9ff07ee1ad5737fadab6294ac30889 Mon Sep 17 00:00:00 2001 From: michaelsam94 Date: Sun, 21 Jun 2026 16:24:50 +0300 Subject: [PATCH] Fix ESP32 edge DSP watchdog priority --- CHANGELOG.md | 1 + firmware/esp32-csi-node/README.md | 1 + firmware/esp32-csi-node/main/edge_processing.c | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a2ad97e1e..b6b54608b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed +- **ESP32 edge DSP watchdog stability for 3-node tier-2 deployments (#1116).** The `edge_dsp` task now runs at FreeRTOS priority 4 instead of 5, leaving core-1 idle/watchdog service room during sustained multi-node tier-2 CSI bursts while keeping the existing per-frame and per-batch DSP yields intact. Firmware troubleshooting docs now call out the fixed behavior for v0.6.5-era 3x ESP32-S3 QFN56 watchdog crashes. - **Multistatic fusion guard interval is now operator-configurable — fixes permanent trust demotion with WiFi-synced ESP32 nodes (#1049).** Two independently-clocked ESP32-S3 boards on ESP-NOW sync drift 10–150 ms (typ. ~70 ms) — the 100 ms beacon + WiFi-MAC jitter cannot hold them within the published 60 ms default guard, so the governed-trust cycle permanently demoted to `Restricted`, suppressed all pose output, and spun the error counter to 200k+ with **no escape hatch but a container restart**. Added a **direct `WDP_GUARD_INTERVAL_US` override** (+ optional `WDP_SOFT_GUARD_US`) to `multistatic_guard_config_from_env`, so a deployment can lift the hard guard past its measured spread (e.g. `WDP_GUARD_INTERVAL_US=200000`) without having to know its exact TDM schedule. Precedence is most-specific-wins: a direct override beats the existing `WDP_TDM_SLOTS`+`WDP_TDM_SLOT_US` schedule-derived guard, which beats the 60 ms/20 ms default; the override is applied on top of whichever base is selected, the soft band is always clamped strictly below the hard guard, and a malformed/zero value is ignored (falls back to the base rather than breaking fusion). The effective guard is now logged at startup. Pinned by 6 new tests (`multistatic_guard_config_tests`): direct-override-wins / beats-TDM-derived / soft-clamped-below-hard / lowering-hard-pulls-soft-down / malformed-or-zero-falls-back / default-when-unset. `wifi-densepose-sensing-server` bin tests **449 → 455**, 0 failed; Python proof VERDICT PASS, hash unchanged (off the signal proof path). ### Security diff --git a/firmware/esp32-csi-node/README.md b/firmware/esp32-csi-node/README.md index f75d053c29..224e69e669 100644 --- a/firmware/esp32-csi-node/README.md +++ b/firmware/esp32-csi-node/README.md @@ -803,6 +803,7 @@ No physical ESP32 hardware is needed in CI. | CSI callback not firing | Promiscuous mode issue | Verify `esp_wifi_set_promiscuous(true)` in `csi_collector.c` | | WASM upload rejected | Signature verification | Disable with `wasm_verify=0` via NVS for development, or sign with Ed25519 | | High frame drop rate | Ring buffer overflow | Reduce `edge_tier` or increase `dwell_ms` | +| `edge_dsp` task watchdog with 3x ESP32-S3 tier-2 nodes | Sustained tier-2 DSP bursts on core 1 | Use firmware newer than v0.6.5; `edge_dsp` now runs at priority 4 so the idle watchdog can run under dense multi-node load | | Vitals readings unstable | Calibration period | Wait 60 seconds for adaptive threshold to settle | | OTA update fails | Binary too large | Check binary is < 1 MB; current headroom is ~6% | | Docker path error on Windows | MSYS path conversion | Prefix command with `MSYS_NO_PATHCONV=1` | diff --git a/firmware/esp32-csi-node/main/edge_processing.c b/firmware/esp32-csi-node/main/edge_processing.c index a92d0403d6..fc395fd530 100644 --- a/firmware/esp32-csi-node/main/edge_processing.c +++ b/firmware/esp32-csi-node/main/edge_processing.c @@ -1422,7 +1422,7 @@ esp_err_t edge_processing_init(const edge_config_t *cfg) "edge_dsp", 8192, /* 8 KB stack — sufficient for DSP pipeline. */ NULL, - 5, /* Priority 5 — above idle, below WiFi. */ + 4, /* Priority 4 — leave core-1 idle/WDT room under tier-2 bursts. */ NULL, dsp_core); @@ -1431,7 +1431,7 @@ esp_err_t edge_processing_init(const edge_config_t *cfg) return ESP_ERR_NO_MEM; } - ESP_LOGI(TAG, "Edge DSP task created on core %d (stack=8192, priority=5)", + ESP_LOGI(TAG, "Edge DSP task created on core %d (stack=8192, priority=4)", (int)dsp_core); return ESP_OK; }