Day 04 Safety

Memory Management and Safety

Embedded C has no garbage collector. Understand the stack, heap fragmentation, static allocation, and the patterns that keep firmware from mysteriously crashing at 3 AM.

~1 hour Intermediate Hands-on Precision AI Academy

Today's Objective

Embedded C has no garbage collector. Understand the stack, heap fragmentation, static allocation, and the patterns that keep firmware from mysteriously crashing at 3 AM.

01

JTAG and SWD

JTAG (Joint Test Action Group): 4 pins (TDI, TDO, TCK, TMS) + optional TRST. SWD (Serial Wire Debug): 2 pins (SWDIO, SWCLK) — ARM's optimized debug interface. Both allow: halt the CPU, set breakpoints, read/write memory and registers, step through code. For STM32: use ST-Link V2 (~$3). For ESP32: use JTAG with openocd -f interface/ftdi/esp32_devkitj_v1.cfg. GDB connects to OpenOCD over a local TCP socket on port 3333.

02

GDB Commands for Embedded

Key commands: target extended-remote :3333 — connect to OpenOCD. monitor reset halt — reset CPU, halt at reset vector. load — flash the ELF file. break main — set breakpoint at main. continue — run. step/next/stepi — single step. info registers — dump all registers. x/8xw 0x20000000 — examine 8 words of SRAM as hex. print gpio_state — print variable value. watch variable — break when variable changes.

03

Printf Debugging with SWO

SWO (Serial Wire Output) is a single-wire trace port that outputs ITM (Instrumentation Trace Macrocell) printf messages without blocking. Configure: enable TRC in CoreDebug, set baud in ITM_TCR, write to ITM->PORT[0].u8. OpenOCD captures SWO output. This gives you printf-style debugging with no UART connection needed and minimal performance impact. VS Code Cortex-Debug extension shows SWO output directly.

bash
#!/bin/bash
# Debug firmware with GDB + OpenOCD

# Terminal 1: Start OpenOCD (adapt config to your hardware)
openocd   -f interface/stlink.cfg   -f target/stm32f1x.cfg   -c "init"   -c "reset halt"
# OpenOCD now listens on port 3333 (GDB) and 4444 (telnet)

# Terminal 2: Connect GDB
arm-none-eabi-gdb firmware.elf << 'EOF'
# Connect to OpenOCD
target extended-remote :3333

# Reset and halt the CPU
monitor reset halt

# Flash the firmware
load

# Set breakpoints
break main
break SysTick_Handler
break EXTI0_IRQHandler

# Run to main
continue

# When stopped at breakpoint:
# info registers        — all register values
# print systick_ms      — print variable
# x/16xw 0x20000000     — dump 16 words of SRAM
# watch button_pressed  — break when this changes
# backtrace             — call stack (if -g compiled)
# stepi                 — one assembly instruction

# Continue execution
continue
EOF

# Useful OpenOCD telnet commands (port 4444):
# echo 'flash list' | nc localhost 4444
# echo 'mdw 0x40020014' | nc localhost 4444  # read GPIO ODR
# echo 'mww 0x40020018 0x01' | nc localhost 4444  # write BSRR
💡
Always compile firmware with debug symbols: add -g3 -Og to your compiler flags. -Og is 'optimization for debugging' — it enables some optimizations while preserving variable names and line numbers. Release builds use -O2 or -O3.
📝 Day 4 Exercise
Debug a Real Firmware Bug
  1. Compile the interrupt example from Day 3 with -g3 -Og debug flags.
  2. Connect ST-Link, start OpenOCD, connect GDB. Set a breakpoint at EXTI0_IRQHandler.
  3. Press the button. When GDB halts in the ISR, print all registers with info registers. Note the PC and LR values.
  4. Use x/8xw 0x40020010 to read GPIOA IDR directly. Does it match what you expect?
  5. Introduce a bug: comment out the pending flag clear line. What happens when you press the button? Use GDB to observe the CPU stuck in the ISR loop.

Day 4 Summary

Challenge

Set up a hardware fault handler. When a firmware bug causes a HardFault (null pointer dereference, stack overflow, etc.), the default handler is an infinite loop — completely unhelpful. Implement a HardFault_Handler that reads the faulting address from the SCB (System Control Block), prints it via UART, and stores it in RTC memory before resetting. Research: what are CFSR, HFSR, and MMAR registers in the SCB? What information do they contain?

What's Next

The foundations from today carry directly into Day 5. In the next session the focus shifts to Debugging and Testing Firmware — building directly on everything covered here.

Day 4 Checkpoint

Before moving on, verify you can answer these without looking:

  • What is the core concept introduced in this lesson, and why does it matter?
  • What are the two or three most common mistakes practitioners make with this topic?
  • Can you explain the key code pattern from this lesson to a colleague in plain language?
  • What would break first if you skipped the safeguards or best practices described here?
  • How does today's topic connect to what comes in Day 5?

Live Bootcamp

Learn this in person — 2 days, 5 cities

Thu–Fri sessions in Denver, Los Angeles, New York, Chicago, and Dallas. $1,490 per seat. June–October 2026.

Reserve Your Seat →
Continue To Day 5
Day 5: Build and Flash