Skip to main content

Advanced Firmware Topics

The deeper skills that separate "it blinks" from "it ships": understanding memory, working at the register level, and debugging methodically. Go here once you're past the basics in Firmware Approaches.

The memory model​

An MCU program lives in a fixed memory map you must understand:

RegionLives inHolds
.text / .rodataFlashCode and constants
.dataRAM (copied from Flash at boot)Initialized globals
.bssRAM (zeroed at boot)Uninitialized globals
HeapRAM (grows up)malloc/new allocations
StackRAM (grows down)Locals, call frames, ISR context
  • The linker script defines these regions; the map file shows exactly how much you used.
  • Flash/RAM "region overflowed" is a link-time error β€” too much code or static data.
  • Heap and stack growing into each other is a runtime crash β€” far nastier, see below.

Memory management​

  • Prefer static / fixed pools over malloc/free. Dynamic allocation in a long-running device causes fragmentation and non-deterministic timing.
  • Size with headroom β€” leave ~20–30% Flash and RAM free for growth, OTA, and stacks.
  • const data stays in Flash β€” don't waste RAM on read-only tables.
  • DMA buffers need correct alignment and, on cached cores (Cortex-M7), cache maintenance or coherency bugs appear intermittently.
  • Use the MPU (Memory Protection Unit) to trap stray writes and guard stacks.

Common memory bugs​

BugCauseSymptomMitigation
Stack overflowDeep recursion, big locals, nested ISRs, undersized RTOS task stackRandom corruption, HardFaultStack painting / high-water mark, MPU guard, size stacks
Heap fragmentationRepeated malloc/free of mixed sizesmalloc fails over timeAvoid dynamic alloc; use memory pools
Buffer overflow / out-of-boundsWriting past an arrayCorruption, security holeBounds checks, safe string fns, static analysis
Memory leakAllocations never freedSlow RAM exhaustionTrack ownership; pools; leak checks
Use-after-free / dangling pointerUsing freed/expired memorySporadic crashesNull after free; avoid raw lifetimes
Uninitialized readUsing memory before setHeisenbugsInitialize; compiler warnings
Stack overflow is the silent killer

It rarely crashes where it happens β€” it corrupts whatever is next in RAM, so the bug surfaces elsewhere. Enable stack-overflow checking (RTOS hook, MPU guard, or stack painting) and check each task's high-water mark before shipping.

Working at the register level​

  • Peripherals are memory-mapped registers; access them via CMSIS definitions, not magic addresses.
  • Declare hardware registers volatile so the compiler doesn't optimize away reads/writes.
  • Use read-modify-write carefully β€” a naΓ―ve RMW on a shared register can race with an ISR; guard with atomics or critical sections.
  • Your source of truth is the reference manual + datasheet β€” and always read the errata.

Debugging methods​

Match the tool to the question (see also Programmers & Debuggers and Measurement Instruments):

MethodToolBest for
On-chip debug (SWD/JTAG)ST-Link / J-Link + IDEBreakpoints, watchpoints, single-step, inspect memory/registers
printf loggingUART + serial consoleQuick traces (but timing-intrusive)
SEGGER RTTJ-LinkHigh-speed logging with almost no timing impact
Logic analyzer / scopeβ€”Bus decode (IΒ²C/SPI/UART), real timing, glitches
Fault handler decodeDebuggerFind where a HardFault came from
Static analysiscppcheck, clang-tidy, MISRACatch bugs before running
Map file + stack high-waterToolchain / RTOSMemory budgeting
Decode the HardFault, don't guess

When a Cortex-M faults, the cause is in the fault status registers (CFSR/HFSR) and the stacked registers hold the PC at the moment of failure. A minimal fault handler that prints these turns "it just resets" into an exact line of code.

Reliability practices​

  • Watchdog timer β€” recover from hangs into a safe state.
  • Brown-out detection β€” defined behavior on sag (see decoupling).
  • CRC / integrity checks on stored data and firmware images.
  • OTA with rollback β€” never ship an update path that can brick the device.
  • Assertions + defined safe states for out-of-range conditions.

See also: Building a Product.