stm32wl(mem): fix getFreeHeap() underreporting on dynamic sbrk heap
mallinfo().fordblks counts only free bytes within the committed arena. On STM32WL (newlib sbrk heap) the arena grows lazily from _end toward SP, so fordblks reads near-zero at early boot even when ~48 KB of addressable space remains. This caused NodeDB::isFull() to fire prematurely and evict nodes on a freshly booted device. Fix getFreeHeap() to include uncommitted sbrk headroom (SP - sbrk(0)) so the returned value reflects true available memory throughout the boot lifecycle. Introduce MESHTASTIC_DYNAMIC_SBRK_HEAP as an opt-in build flag (set in stm32.ini) so the fix is gated to platforms with a dynamic sbrk heap rather than a static heap. Future platforms with the same heap model can opt in by adding this flag. Signed-off-by: Andrew Yong <me@ndoo.sg> Assisted-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Chloe Bethel
co-authored by
Chloe Bethel
parent
026213aab7
commit
0ee5777c15
+17
-5
@@ -10,8 +10,20 @@
|
||||
#include "memGet.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef ARCH_STM32WL
|
||||
#if defined(MESHTASTIC_DYNAMIC_SBRK_HEAP)
|
||||
#include <malloc.h>
|
||||
#include <unistd.h> // sbrk
|
||||
|
||||
// Returns the uncommitted sbrk headroom: addressable space between the current heap
|
||||
// break and the stack pointer that has not yet been committed to the arena.
|
||||
// Currently used on: ARCH_STM32WL
|
||||
static uint32_t sbrkHeadroom()
|
||||
{
|
||||
uint32_t sp;
|
||||
__asm volatile("mov %0, sp" : "=r"(sp));
|
||||
uint32_t heap_end = (uint32_t)sbrk(0);
|
||||
return (sp > heap_end) ? (sp - heap_end) : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
MemGet memGet;
|
||||
@@ -28,9 +40,9 @@ uint32_t MemGet::getFreeHeap()
|
||||
return dbgHeapFree();
|
||||
#elif defined(ARCH_RP2040)
|
||||
return rp2040.getFreeHeap();
|
||||
#elif defined(ARCH_STM32WL)
|
||||
#elif defined(MESHTASTIC_DYNAMIC_SBRK_HEAP) // Currently: ARCH_STM32WL
|
||||
struct mallinfo m = mallinfo();
|
||||
return m.fordblks; // Total free space (bytes)
|
||||
return m.fordblks + sbrkHeadroom(); // Free space within arena + uncommitted sbrk headroom
|
||||
#else
|
||||
// this platform does not have heap management function implemented
|
||||
return UINT32_MAX;
|
||||
@@ -49,9 +61,9 @@ uint32_t MemGet::getHeapSize()
|
||||
return dbgHeapTotal();
|
||||
#elif defined(ARCH_RP2040)
|
||||
return rp2040.getTotalHeap();
|
||||
#elif defined(ARCH_STM32WL)
|
||||
#elif defined(MESHTASTIC_DYNAMIC_SBRK_HEAP) // Currently: ARCH_STM32WL
|
||||
struct mallinfo m = mallinfo();
|
||||
return m.arena; // Non-mmapped space allocated (bytes)
|
||||
return m.arena + sbrkHeadroom(); // Non-mmapped space allocated + uncommitted sbrk headroom
|
||||
#else
|
||||
// this platform does not have heap management function implemented
|
||||
return UINT32_MAX;
|
||||
|
||||
Reference in New Issue
Block a user