From f5e2b5474b3120797dd55db1c2b36c25e135dbc2 Mon Sep 17 00:00:00 2001 From: rUv Date: Mon, 18 May 2026 17:05:35 -0400 Subject: [PATCH] =?UTF-8?q?release:=20ESP32-S3=20firmware=20v0.6.5=20?= =?UTF-8?q?=E2=80=94=20Tmr=20Svc=20stack=20+=20OTA=20init=20refactor=20(#6?= =?UTF-8?q?28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes wrapped for the v0.6.5-esp32 release tag: 1. **`sdkconfig.defaults` adds `CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=8192`**. The fix was already in `sdkconfig.defaults.template` (ADR-081, prevents "stack overflow in task Tmr Svc" bootloop when adaptive_controller emits feature_state from inside a Timer Svc callback). It was MISSING from the canonical `sdkconfig.defaults` file used by the build, so any fresh build picked up the 2 KiB FreeRTOS default and bootlooped on hardware. Verified on COM7: with the fix, no panics in 30 s of operation; without it, "***ERROR*** A stack overflow in task Tmr Svc has been detected." followed by sustained bootloop. 2. **`ota_update.c` extracts `ota_load_psk_from_nvs()` and calls it from both `ota_update_init()` and `ota_update_init_ex()`.** `main.c:230` uses the `_ex` variant, but only `ota_update_init()` was loading the PSK from NVS. Result: `s_ota_psk` stayed empty regardless of NVS contents, so the RuView#596 fail-closed posture rejected every request — but the diagnostic warning never printed at boot, leaving operators no signal about why their OTA uploads were 403'ing. Verified on COM7: W (3126) ota_update: NVS namespace 'security' not found — OTA upload endpoint will REJECT all requests until provisioned. Fail-closed per RuView#596. 3. **`version.txt`: 0.6.4 → 0.6.5**, paired with the v0.6.5-esp32 tag so the firmware-ci version-guard job (RuView#505 fix-marker) stays happy. Both validations done end-to-end on hardware (COM7, ESP32-S3 8MB, provisioned with --edge-tier 2 to also incidentally re-verify #438 is not reproducible on current main). --- firmware/esp32-csi-node/main/ota_update.c | 21 +++++++++++++++++++-- firmware/esp32-csi-node/sdkconfig.defaults | 8 ++++++++ firmware/esp32-csi-node/version.txt | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/firmware/esp32-csi-node/main/ota_update.c b/firmware/esp32-csi-node/main/ota_update.c index f95ba1e6..eed5c667 100644 --- a/firmware/esp32-csi-node/main/ota_update.c +++ b/firmware/esp32-csi-node/main/ota_update.c @@ -251,9 +251,16 @@ static esp_err_t ota_start_server(httpd_handle_t *out_handle) return ESP_OK; } -esp_err_t ota_update_init(void) +/** + * Load the OTA PSK from NVS into the module-local s_ota_psk cache and log + * the resulting posture. Called by both ota_update_init() and + * ota_update_init_ex() so the per-boot diagnostic prints no matter which + * entry point main.c uses — historically only ota_update_init() loaded the + * PSK, which left ota_update_init_ex() with an empty s_ota_psk and an + * invisible fail-closed posture (RuView#596 follow-up). + */ +static void ota_load_psk_from_nvs(void) { - /* ADR-050: Load OTA PSK from NVS if provisioned. */ nvs_handle_t nvs; if (nvs_open(OTA_NVS_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) { size_t len = sizeof(s_ota_psk); @@ -268,11 +275,21 @@ esp_err_t ota_update_init(void) ESP_LOGW(TAG, "NVS namespace '%s' not found — OTA upload endpoint will REJECT all " "requests until provisioned. Fail-closed per RuView#596.", OTA_NVS_NAMESPACE); } +} +esp_err_t ota_update_init(void) +{ + /* ADR-050: Load OTA PSK from NVS if provisioned. */ + ota_load_psk_from_nvs(); return ota_start_server(NULL); } esp_err_t ota_update_init_ex(void **out_server) { + /* ADR-050: Load OTA PSK from NVS if provisioned. main.c uses this + * variant (not ota_update_init), so without this call s_ota_psk + * stayed empty forever and the fail-closed posture was invisible + * in serial logs. */ + ota_load_psk_from_nvs(); return ota_start_server((httpd_handle_t *)out_server); } diff --git a/firmware/esp32-csi-node/sdkconfig.defaults b/firmware/esp32-csi-node/sdkconfig.defaults index 9d2ca761..9ba4494b 100644 --- a/firmware/esp32-csi-node/sdkconfig.defaults +++ b/firmware/esp32-csi-node/sdkconfig.defaults @@ -34,3 +34,11 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 # Extra WiFi IRAM placement (defense-in-depth for RuView#396 SPI cache race) CONFIG_ESP_WIFI_EXTRA_IRAM_OPT=y + +# ADR-081: adaptive_controller runs emit_feature_state + stream_sender +# network I/O inside Timer Svc callbacks, exceeding the 2 KiB default. +# Without this, the device bootloops with +# "***ERROR*** A stack overflow in task Tmr Svc has been detected." +# Was present in sdkconfig.defaults.template but missing here — fixed +# in the v0.6.5-esp32 release. +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=8192 diff --git a/firmware/esp32-csi-node/version.txt b/firmware/esp32-csi-node/version.txt index d2b13eb6..e0ea44c1 100644 --- a/firmware/esp32-csi-node/version.txt +++ b/firmware/esp32-csi-node/version.txt @@ -1 +1 @@ -0.6.4 +0.6.5 \ No newline at end of file