mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-08-05 18:29:41 +00:00
Stops the TASK_WDT(6) reset loop that was firing every ~50-90s of
post-setup runtime on the graft (and on pre-graft pyxis). Decoded
backtrace pinned the cause to ESP-IDF's WiFi ppTask doing
pm_tx_data_done_process and starving the CPU0 idle task — a
WiFi-stack-internal that has nothing to do with user code.
Two attempts, both useful to record:
1. sdkconfig.defaults: set CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n.
Doesn't take effect — Arduino-ESP32 ships its framework PRE-BUILT
with the original sdkconfig (CPU0=y, timeout=5s) baked in.
sdkconfig.defaults overrides only apply if you rebuild the framework
from source. Kept the .defaults change for documentation; the
runtime escape uses esp_task_wdt_init.
2. esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(0)) at boot.
Doesn't stick — Arduino-ESP32's runtime re-subscribes CPU0 idle
on the next loop iteration since CHECK_IDLE_TASK_CPU0 is still
set in the prebuilt config.
Final fix: esp_task_wdt_init(60, false). 60s timeout (was 30s) AND
panic=false (warnings logged, no reset). This makes WDT a soft
indicator instead of a hard reset trigger — appropriate while the
underlying WiFi-pm-starvation issue lives in ESP-IDF, not pyxis.
Verified runtime:
- 3 minutes continuous uptime, zero aborts/panics/resets
- 5 propagation nodes discovered from the network
(LXMF protocol layer working end-to-end on the graft)
- Heap stable around 46KB free, low-water 37KB
- 165KB UART log captured (vs prior ~30KB before reset)
This means pyxis on top of attermann/microReticulum @ 0.3.0 +
torlando-tech/microReticulum:pyxis-fixes-on-0.3.0 is now
**runtime-stable** — first time the graft has run uninterrupted
long enough to actually use.
Future: revisit panic=true once we can prove the WDT culprit is
moved to ESP-IDF's tracker (or pyxis is updated to a framework that
fixes the WiFi pm starvation). Until then, log-only avoids false
positives.
108 lines
4.3 KiB
Plaintext
108 lines
4.3 KiB
Plaintext
# Required for Arduino framework
|
|
CONFIG_FREERTOS_HZ=1000
|
|
|
|
# Flash configuration for 8MB
|
|
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
|
|
|
# Enable Bluetooth with NimBLE (uses ~100KB less RAM than Bluedroid)
|
|
CONFIG_BT_ENABLED=y
|
|
CONFIG_BT_NIMBLE_ENABLED=y
|
|
CONFIG_BT_BLUEDROID_ENABLED=n
|
|
|
|
# NimBLE role configuration - enable both central and peripheral for mesh
|
|
CONFIG_BT_NIMBLE_ROLE_CENTRAL=y
|
|
CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y
|
|
CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y
|
|
CONFIG_BT_NIMBLE_ROLE_OBSERVER=y
|
|
|
|
# NimBLE connection settings
|
|
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=3
|
|
CONFIG_BT_NIMBLE_MAX_BONDS=10
|
|
|
|
# NimBLE GATT settings
|
|
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=517
|
|
CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31
|
|
|
|
# Increase task stack size for stability
|
|
CONFIG_BT_NIMBLE_TASK_STACK_SIZE=8192
|
|
|
|
# Coexistence with WiFi
|
|
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
|
|
|
|
# Enable C++ exceptions (required for microReticulum)
|
|
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
|
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
|
|
|
|
# Enable PSRAM (8MB external RAM) for zero heap fragmentation
|
|
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
|
CONFIG_SPIRAM=y
|
|
CONFIG_SPIRAM_MODE_OCT=y
|
|
CONFIG_SPIRAM_SPEED_80M=y
|
|
|
|
# Configure malloc to use PSRAM
|
|
CONFIG_SPIRAM_USE_MALLOC=y
|
|
# Allocations smaller than this go to internal RAM (bytes)
|
|
# Lowered from 4096 to 64 to move Bytes allocations (16-200 bytes) to PSRAM
|
|
# This reduces internal heap fragmentation at cost of slightly slower access
|
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=64
|
|
# Reserve this much internal RAM for DMA/ISR (bytes)
|
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
|
|
|
# ============================================================================
|
|
# Boot Time Optimizations
|
|
# These settings reduce boot time. See BOOT_OPTIMIZATIONS.md for details.
|
|
# ============================================================================
|
|
|
|
# Disable PSRAM memory test at boot (~2 seconds saved for 8MB PSRAM)
|
|
# The memory test verifies PSRAM integrity but is redundant for stable hardware.
|
|
# To re-enable for debugging: comment out this line or set to y
|
|
CONFIG_SPIRAM_MEMTEST=n
|
|
|
|
# Reduce bootloader log verbosity (saves serial output time)
|
|
# Bootloader messages are rarely needed in production
|
|
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
|
CONFIG_BOOTLOADER_LOG_LEVEL=2
|
|
|
|
# Skip ROM bootloader output (saves serial time)
|
|
CONFIG_BOOT_ROM_LOG_ALWAYS_OFF=y
|
|
|
|
# ============================================================================
|
|
# FreeRTOS Timer Service Task
|
|
# Default 2048 is too small when NimBLE/WiFi timer callbacks run
|
|
# ============================================================================
|
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096
|
|
|
|
# ============================================================================
|
|
# Task Watchdog Timer (TWDT)
|
|
# Detects task starvation and deadlock conditions on user-code core (CPU1).
|
|
# 30s timeout accommodates SPIFFS flash I/O during identity persistence
|
|
# (writing 40-50 destinations to flash takes 5-15s with GC/erase).
|
|
#
|
|
# CPU0 IDLE watchdog INTENTIONALLY DISABLED:
|
|
# ESP-IDF runs the WiFi controller, lwIP TCP/IP stack, and system timer
|
|
# tasks on CPU0. Under heavy network load (busy TCP frames, mDNS, multicast
|
|
# WiFi traffic) those tasks can starve the CPU0 idle task for >30s without
|
|
# any user-code involvement. Triggering an `abort` because lwIP is busy is
|
|
# false-positive — it doesn't mean any pyxis task is misbehaving. We keep
|
|
# the watchdog on the loopTask (added explicitly via esp_task_wdt_add in
|
|
# main.cpp:1421) and on CPU1 idle, which together cover the core where
|
|
# all user code runs. Surfaced 2026-05-05 by the post-graft `task_wdt_isr`
|
|
# abort decoded to esp_vApplicationIdleHook on core 0; pre-graft pyxis
|
|
# was hitting the same pattern (~57s reset cadence).
|
|
# ============================================================================
|
|
CONFIG_ESP_TASK_WDT_EN=y
|
|
CONFIG_ESP_TASK_WDT_TIMEOUT_S=30
|
|
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
|
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
|
|
|
|
# ============================================================================
|
|
# Core Dump — writes CPU state + backtrace to flash on crash
|
|
# Read with: espcoredump.py info_corefile -t raw -c 0x7F0000 -s 0x10000 <port>
|
|
# ============================================================================
|
|
CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y
|
|
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
|
|
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
|
|
CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64
|