Bare-metal STM32: vector table, linker script, and startup code from scratch

· coding web · Source ↗

TLDR

  • Walk through building STM32 blinky with no HAL, no CMSIS: vector table, linker script, .data copy, and reset handler all written by hand.

Key Takeaways

  • At power-on, Cortex-M4 reads 4 bytes at 0x08000000 as the initial stack pointer, then jumps to the reset vector at 0x08000004; bit 0 must be set or you get an immediate HardFault.
  • The linker script is the only thing connecting compiler output sections (.text, .data, .bss) to physical flash/RAM addresses; the compiler itself has no knowledge of memory layout.
  • .data variables require two addresses: LMA in flash for storage, VMA in RAM for runtime; the startup code must copy them before main() runs.
  • volatile on memory-mapped register macros is mandatory, not stylistic; without it the compiler eliminates accesses as dead stores and the peripheral never activates.
  • GPIO read-modify-write (LDR/ORR/STR) is non-atomic on Cortex-M; use BSRR for atomic set/clear on output pins without needing bit-band or LDREX/STREX.

Hacker News Comment Review

  • One commenter confirms the ESP32 bare-metal point: despite initial skepticism, ESP-IDF lock-in is real because Espressif’s chips are architecturally diverse enough that even their own low-level API is the only practical common interface.

Original | Discuss on HN