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_std firmware
  • Enabling dynamic allocation in no_std with the alloc crate and a custom global allocator (embedded-alloc, buddy_system_allocator)
  • Heap-free alternatives for deterministic memory use: fixed-capacity containers from heapless and arrayvec, plus hybrid stack-or-heap structures from smallvec and tinyvec
  • 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?

7.1 Understanding memory in embedded Rust

7.1.1 The three memory regions of an embedded Rust program

7.1.2 What core provides and what alloc adds

7.1.3 Manual memory management: from C to unsafe Rust

7.2 Custom allocators for heap usage in embedded Rust

7.2.1 Why heap allocation is an explicit choice in no_std

7.2.2 Installing a global allocator with embedded-alloc

7.2.3 An alternative: the buddy system

7.2.4 Using the heap: a worked example

7.2.5 Choosing between allocators in practice

7.2.6 Sizing the heap and avoiding allocation pitfalls

7.3 Alternatives to heap allocation in embedded Rust

7.3.1 Fixed-capacity containers with heapless

7.3.2 Lighter-weight alternative: arrayvec

7.3.3 Hybrid containers: tinyvec and smallvec

7.3.4 Choosing among the alternatives

7.4 Managing the stack for memory safety

7.4.1 How stack overflows happen

7.4.2 Estimating stack usage with static analysis