Bare Metal STM32

Periodically I have to bring up a new device and my current favorite processor line is the STM32 Cortex ARM processors from STMicroelectronics.  When bringing up new hardware, JTAG debugging (or similar) is immensely useful and ST provides tools to make that easy including:

    • ST-Link V2 hardware debug interface – you can buy an official ST-Link V2 for $23 from Digikey or elsewhere or purchase a nicer clone on eBay for $3.25.  ST evaluation boards such as for the STM32L476 Discovery or STM32F4 Nucleo (with mBed support too!) cost $10-20 and include an ST-Link on board that you can disconnect from the evaluation processor and connect to your target via the SWD connector and by removing the two ST-LINK jumpers.  You’ll need to connect the SWD connector to Vcc, Gnd, SWCLK, SWDIO, and NRST on the target.
    • Use the GCC ARM Embedded development tools to build your software.  Build an .elf with debug information and a .hex file for programming.
      • For Ubuntu platforms see here for installation via package manager.
    • Use the ST-Link utility to flash your .hex file to the target using the ST-Link V2
    • Use Texane STLink to make your target debuggable via the ST-Link V2 and GDB (see this post for details on linux setup for texane)
    • Debug, by running the texane STLink utility and you should see something like this:

STLINK GDB Server v0.5.6 (Mar 24 2013 10:29:19)
Many thanks to the STLINK development team.

2016-02-29T16:18:14 INFO src/stlink-common.c: Loading device parameters….
2016-02-29T16:18:14 WARN src/stlink-common.c: unknown chip id! 0x10036415
Chip ID is 00000415, Core ID is  2ba01477.
KARL – should read back as 0x03, not 60 02 00 00
Listening at *:4242…


  • Launch gdb for your executable, connect to the target, and start debugging:

arm-none-eabi-gdb myProgram.elf
(gdb) target remote localhost:4242
(gdb) break main
(gdb) continue


  • GDB has a huge set of commands; see the manual here .  For example:
    • step  (or ‘s’)                (step through one source line – steps into functions)
    • stepi (or ‘si’)                (step through one assembly instruction)
    • next (or ‘n’)                  (step over a function)
    • break *0x8004060       (set breakpoint at address)
    • break main                  (set breakpoint at function)
    • info breakpoints          (or info b)
    • del 3                            (delete breakpoint # 3)
    • info registers
    • info reg $r3
    • p <variable_name>   (print value of variable)
    • p/x  $r3                       (print value in register r3 in hex)
    • list                               (list source code)
    • disassemble              (disassemble around current PC)
    • display $pc                 (show value in program counter with each step)
    • display/i $pc               (disassemble code at program counter with each step)
    • display/20i $pc           (disassemble 20 lines starting at pc with each step)
    • x/20i *0x08004060      (disassemble 20 lines starting at address 0x8004060)
    • x/20xw $sp                 (dump 20 longwords from stack)
  • Note that a watchdog interrupt will appear as a SIGTRAP