Right-size nRF52 heap tiers after 2.8.0 heap-exhaustion field reports (#10898)
* Right-size nRF52 heap tiers after 2.8.0 heap-exhaustion field reports Field reports on 2.8.0 show nRF52840 devices at 99% heap (114/115 KB) within minutes of boot; operator new asserts on OOM, so these devices are one allocation from a reboot. The 2.8.0 cache sizing ladders gave nRF52 the largest non-PSRAM tiers on the assumption that a BLE-only part has a roomy heap - the arena is actually ~125 KB shared with the FreeRTOS task stacks. Per-target retiers (nRF52840 unless noted): - Traffic Management cache 1000 -> 250 entries (10 KB -> 2.5 KB); the unclassified fallthrough drops 1000 -> 400 to match the classic-ESP32 tier (also affects RP2040/RP2350) - Warm node store 200 -> 100 entries (8 KB -> 4 KB); the non-XXAA fallthrough drops 320 -> 100 so an unclassified RAM-constrained part can't boot-allocate 12.8 KB - MESSAGE_HISTORY_LIMIT 20 -> 10 (text pool 4.4 KB -> 2.2 KB), the tier classic ESP32 already ships - MAX_RX_TOPHONE 32 -> 16, shrinking the static packet pool 70 -> 54 slots (~6.6 KB of .bss returned to the heap arena) - PacketHistory hash index off arch-wide (1 KB); O(n) over 240 records is negligible at LoRa packet rates - OLEDDISPLAY_REDUCE_MEMORY arch-wide (~1 KB OLED back buffer); the five TFT variants -U it because TFTDisplay.cpp needs buffer_back for dirty-window diffing - Drop the stale "for testing" 1024-entry TMM override on T1000-E Measured on rak4631: heap arena grows 124,572 -> 131,180 B and boot allocations drop ~15.7 KB, roughly +22 KB free heap on the field-report device class. Migration: the nRF52840 warm flash ring replays through place() (LRU), so the newest 100 identities survive the shrink; the file backend rejects oversized snapshots cleanly (new test covers this). Native suites pass (536/536 Docker, 13/13 native-macos warm store); rak4631, heltec-mesh-node-t114 (TFT) and tracker-t1000-e build green. * Drop stale OLEDDISPLAY_REDUCE_MEMORY -U on t114 / mesh-solar-tft Only USE_TFTDISPLAY variants (t1, t096, wismeshtap) compile TFTDisplay.cpp and need the lib's buffer_back; t114 and mesh-solar-tft render through the meshtastic-st7789 driver, which handles the reduced-memory configuration fine - as #10894 (merged from develop) already established by defining the flag there. Remove the -U guard and the per-variant -D (redundant with the arch-wide define in nrf52_base on this branch). Both variants verified building.
This commit is contained in:
+6
-4
@@ -21,10 +21,12 @@
|
||||
// How many messages are stored (RAM + flash).
|
||||
// Define -DMESSAGE_HISTORY_LIMIT=N in build_flags to control memory usage.
|
||||
#ifndef MESSAGE_HISTORY_LIMIT
|
||||
#if defined(ARCH_ESP32) && \
|
||||
!(defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2))
|
||||
// Baseline ESP32 (non-PSRAM variants) has limited heap; reduce message history on resource-constrained builds.
|
||||
// Override with -DMESSAGE_HISTORY_LIMIT=N if needed.
|
||||
#if (defined(ARCH_ESP32) && \
|
||||
!(defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2))) || \
|
||||
defined(NRF52840_XXAA)
|
||||
// Baseline ESP32 (non-PSRAM variants) and nRF52840 (~115 KB heap arena shared with SoftDevice +
|
||||
// FreeRTOS stacks; 2.8.0 field reports hit 99% use) have limited heap; reduce message history on
|
||||
// resource-constrained builds. Override with -DMESSAGE_HISTORY_LIMIT=N if needed.
|
||||
#define MESSAGE_HISTORY_LIMIT 10
|
||||
#else
|
||||
#define MESSAGE_HISTORY_LIMIT 20
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
#ifndef MAX_RX_TOPHONE
|
||||
#if defined(ARCH_ESP32) && !(defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3))
|
||||
#define MAX_RX_TOPHONE 8
|
||||
#elif defined(NRF52840_XXAA)
|
||||
// Each slot is a ~340 B MeshPacket in the static pool (Router.cpp MAX_PACKETS_STATIC), so 32 slots
|
||||
// cost ~11 KB of .bss on the RAM-tightest platform (2.8.0 field reports: 99% heap). 16 still doubles
|
||||
// the 8 classic ESP32 has shipped with for years; drops start when a stalled phone/serial client has
|
||||
// 16 packets queued.
|
||||
#define MAX_RX_TOPHONE 16
|
||||
#else
|
||||
#define MAX_RX_TOPHONE 32
|
||||
#endif
|
||||
@@ -126,7 +132,10 @@ static inline int get_max_num_nodes()
|
||||
// Keyed on the NRF52840_XXAA build flag, not ARCH_NRF52: the latter (from
|
||||
// architecture.h via configuration.h) isn't defined this early in every include
|
||||
// chain. Backed by the raw-flash ring below LittleFS - see WarmNodeStore.h.
|
||||
#define WARM_NODE_COUNT 200
|
||||
// 100 (was 200): the RAM cache is 40 B/entry calloc'd from the ~115 KB heap
|
||||
// arena, which 2.8.0 field reports showed at 99% use; 120 hot + 100 warm
|
||||
// identities still covers meshes well past the hot cap.
|
||||
#define WARM_NODE_COUNT 100
|
||||
#elif (defined(CONFIG_IDF_TARGET_ESP32S3) && defined(BOARD_HAS_PSRAM)) || defined(ARCH_PORTDUINO)
|
||||
#define WARM_NODE_COUNT 2000 // PSRAM-equipped ESP32-S3 / native host; warm cache in PSRAM (~80 KB)
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4)
|
||||
@@ -136,10 +145,11 @@ static inline int get_max_num_nodes()
|
||||
#elif defined(ARCH_RP2040)
|
||||
#define WARM_NODE_COUNT 150 // RP2040 (264 KB) / RP2350 (520 KB): bounded so warm.dat write fits the 8s watchdog (#10746)
|
||||
#else
|
||||
// nRF52840 is handled explicitly above (200, raw-flash ring). Any other nRF52 (non-XXAA) and any
|
||||
// future non-ESP32/non-RP LittleFS part fall through to this 320 default - flag for review if such a
|
||||
// RAM-constrained nRF52 target is ever added.
|
||||
#define WARM_NODE_COUNT 320 // other LittleFS-backed parts (e.g. non-nRF52840 nRF52)
|
||||
// nRF52840 is handled explicitly above (raw-flash ring). Any other nRF52 (non-XXAA) and any future
|
||||
// non-ESP32/non-RP LittleFS part lands here. Reviewed after the 2.8.0 nRF52840 heap-exhaustion
|
||||
// reports: fail small (match nRF52840) so an unclassified RAM-constrained part can't boot-allocate
|
||||
// 12.8 KB; RAM-rich targets should opt up explicitly in their variant.
|
||||
#define WARM_NODE_COUNT 100 // other LittleFS-backed parts (e.g. non-nRF52840 nRF52)
|
||||
#endif // platform
|
||||
#endif // WARM_NODE_COUNT
|
||||
|
||||
@@ -177,11 +187,16 @@ static inline int get_max_num_nodes()
|
||||
#define TRAFFIC_MANAGEMENT_CACHE_SIZE 500 // 512 KB+ SRAM, no PSRAM (S3/C6/P4): ~5 KB heap (#10705)
|
||||
#elif defined(ARCH_ESP32)
|
||||
#define TRAFFIC_MANAGEMENT_CACHE_SIZE 400 // classic ESP32 / S2 / C3: tightest free heap, ~4 KB (#10705)
|
||||
#elif defined(NRF52840_XXAA)
|
||||
// Keyed on NRF52840_XXAA (not ARCH_NRF52) for the same include-order reason as WARM_NODE_COUNT above.
|
||||
// The 256 KB part shares its ~115 KB heap arena with SoftDevice and the FreeRTOS task stacks; 2.8.0
|
||||
// field reports hit 99% heap use with the old 1000-entry (~10 KB) cache. 250 entries (2.5 KB) still
|
||||
// tracks >2x the 120-node hot store; LRU victim recycling absorbs busier meshes.
|
||||
#define TRAFFIC_MANAGEMENT_CACHE_SIZE 250
|
||||
#else
|
||||
// nRF52 (incl. nRF52840) and RP2040/RP2350 fall through here - there is no nRF/RP branch above,
|
||||
// by design. These parts have no ESP32-style WiFi+BLE coexistence eating the heap, so the larger
|
||||
// 1000-entry (~10 KB) cache fits: nRF52840 is BLE-only on 256 KB RAM; RP2040/RP2350 have 264/520 KB.
|
||||
#define TRAFFIC_MANAGEMENT_CACHE_SIZE 1000 // nRF52 / RP2040 / RP2350 / other non-ESP32
|
||||
// RP2040/RP2350 and anything unclassified land here: match the classic-ESP32 tier rather than
|
||||
// defaulting large. RAM-rich targets should opt up explicitly in their variant.
|
||||
#define TRAFFIC_MANAGEMENT_CACHE_SIZE 400
|
||||
#endif
|
||||
#endif // TRAFFIC_MANAGEMENT_CACHE_SIZE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user