chapter seven
7 Managing stack and heap in resource-constrained systems
This chapter covers
- The three memory regions of an embedded Rust program (static, stack, heap) and why heap usage is the exception rather than the default in
no_stdfirmware - Enabling dynamic allocation in
no_stdwith thealloccrate and a custom global allocator (embedded-alloc,buddy_system_allocator) - Heap-free alternatives for deterministic memory use: fixed-capacity containers from
heaplessandarrayvec, plus hybrid stack-or-heap structures fromsmallvecandtinyvec - Detecting and preventing stack overflows with
cargo-call-stack, emitted stack sizes,flip-link, software canaries, and MPU guard regions
Chapters 4 and 5 established where firmware memory lives: the linker script defines FLASH and RAM regions, the reset handler initializes .data and .bss, and the memory-mapped I/O regions expose hardware registers through the same address space. With those foundations in place, we now return to memory, this time from the application programmer’s point of view. Where does a local variable end up? What happens when a function returns a Vec? Can we use a Box on a Cortex-M3 with 20 KB of RAM, and if so, what does that cost us?