Bare Metal STM32 Development on Windows

It’s been a year and a half since I last posted on this and some new tools are available; they work great with STM32L1xx, STM32F1xx, STM32L4xx, etc.

  1. For an integrated IDE, I still like EmBitz
  2. When working from the command line, I still like vim for Windows
  3. For hardware-level debugging (JTAG/SWD), OpenOCD has dramatically improved their support for STM32 and is now better than the Texane STLink IMHO.  You can download windows binaries and the pdf manual or browse the online documentation.  OpenOCD is a GDB server that listens on:
    • port 3333 for a GDB debugger connection for source-level debugging
    • port 4444 for a telnet connection and sophisticated command line interface that lets you use commands like these:

      > stm32l4x unlock 0 (unlock flash bank 0)
      > stm32l4x mass_erase 0 (erase all flash)
      > flash probe 0
      > flash list
      > flash erase_address 0x08000000 0x3000
      > flash write_image myProgram.bin 0x08000000
      > reset halt
      > mdb 0x08000000 32 (dump 32-bytes at start of flash)

    OpenOCD supports many target processors and many hardware interfaces; when you launch OpenOCD, you must pass it two parameters that tell it which hardware interface to use and what target it will be controlling. For example:

    openocd -f interface\stlink-v2.cfg -f target\stm32l4x.cfg

    There are many pre-built configuration files in the interface and target sub-directories wherever you installed openocd. If your interface or target aren’t supported, the configuration files are text and can be easily edited to support your needs.

  4. GNU ARM Embedded Toolchain continues to be the best pre-compiled toolchain and is kept up-to-date.  It includes gdb which can attach easily to an OpenOCD server and let you do source-level debugging from its command-line interface and is well documented and there are many tutorials and cheatsheets.  An example of the CLI use is:
    arm-none-eabi-gdb <myApplication.elf>
    (gdb) target extended-remote localhost:3333
    (gdb) load myApplication.elf (loads image into flash)
    OR
    (gdb) file myApplication.elf (to debug an image already in flash)
    (gdb) set remote hardware-watchpoint-limit 6
    (gdb) b main
    (gdb) monitor reset run
    (gdb) c
    (gdb) step (s) or next (n)
    (gdb) i b (info breakpoints)
    (gdb) list [fnName]
    (gdb) interrupt (halt execution)
    (gdb) print <symbolName>
  5. Note: the ‘monitor’ command lets you issue any of the OpenOCD CLI commands from within GDB. For example:
    (gdb) monitor reset halt(reset target and halt target)

  6. Eclipse CDT (especially the standalone version) integrates nicely with gdb and OpenOCD and provides a friendly, smart, graphical source-level debugger.
    • On launch, select the appropriate .elf file for debugging at first dialog
    • Under Window->Preferences->C/C++->Debug->GDB set GDB debugger to arm-none-eabi-gdb (in the appropriate directory – you only need to do this once)
    • In a separate Command window, start OpenOCD with the appropriate interface and target (see above)
    • Under File->Debug Remote Executable: set Binary to the .elf file, Hostname to localhost, Port to 3333, check Attach (you should see gdb connect in the OpenOCD window)
    • In the bottom panel of Eclipse CDT, select the Debugger Console tab (accesses the gdb console)
      • file myProgram.elf (if the firmware is already running on the target)
        OR
      • load myProgram.elf (to program the .elf file into the target flash)
      • b main
      • monitor reset run OR
      • monitor reset halt
      • jump Reset_Handler
      • next
      • print myVariable
      • continue
    • From there you can step into/over lines of source code, browse variables and C and assembler source code, view/set/clear breakpoints graphically, and do everything you would expect from a modern debugger.
    • You can read more about it here.