Update 2018-08-06: These days ARM are the canonical source for the open source toolchain. Update 2018-08-08: Nucleos come in various sizes these days; added Black Magic Probe notes.

ST make a range of Cortex-M chips, the STM32.1 These are brief notes on developing software for them on a Mac with free and open tools. They’re very much ‘I tried this and it worked’ notes, and not ‘these are the best ways to do things.’. YMMV!

Inevitably Wikipedia has a good summary of STM32 stuff.2

Development boards

ST make two ranges of inexpensive development boards: Nucleo and Discovery. Both ranges include an integrated ST-LINK programmer so you can just connect the board to a USB port and play.


These are very cheap (£10-ish) boards which contain the processor and have some measure of Arduino compatibililty. Originally, the boards came in one size and all sported a 64-pin processor: these days you get get both smaller (48-pin processor) and larger (144-pin processor) boards too.

The ST website has:


These are slightly more expensive but contain more than just the processor.

Again you can see the full range5 on the ST website.

As an example, they make a F429 based board with a lots of IO and a colour QVGA display.6 All for about £20.


All the Nucleo boards are mbed friendly7 but I wanted a more traditional approach.

Happily the GNU tools support ARM, and ARM now provide a canonical version8 of them.

In the past there used to be a homebrew friendly gcc-arm-embedded cask for this, but it’s been removed9. For now, if you want to use brew you can either do something like this:

$ brew cask install https://raw.githubusercontent.com/

or use the PX4 tap:

$ brew tap PX4/px4
$ brew search px4
$ brew install px4/px4/gcc-arm-none-eabi

Firmware library

In principle you could write code which targets the processor’s hardware directly: all you need is the datasheet. However I found the libopencm310 open-source firmware library useful on two counts:

  1. They have plentiful examples, often for the exact development board I’m using. So it’s easy to check that the tool chain is right, and get to the blinking LED stage.
  2. In most cases it seems easier to use their hardware abstractions rather than writing my own.

It’s easy to clone the code from GitHub where there are separate repositories for the library11 and the examples.12

To start a new project based around libopencm3 follow their Reuse instructions13

ST Link

The demo boards all sport an integrated ST Link programmer. These come in two flavours which are imaginatively called version 1 and version 2!

Version 1 of the system seems to be a bit dodgy: it requires a kernel extension on the Mac whereas version 2 ‘Just Works’. Happily only a couple of old boards use version 1, so I’ve just ignored it.

The ST Link interface on the Nucleo boards is apparently a slightly newer version, but I don’t know what’s changed.

When you connect a Nucleo to your computer, three USB devices get created:

The ST Link software

You need some software to flash and debug the target MCU. Happily it’s on GitHub.15

Once installed you can either invoke st-flash to write the code directly, or launch st-util in daemon mode and then interrogate the hardware with gdb.

Taking the latter route, here are some typical commands:

In shell 1:

$ st-link

In shell 2:

$ arm-none-eabi-gdb foo.elf
(gdb) target extended-remote :4242
(gdb) load
(gdb) run

If you’re using libopencm3 convenient dummy targets are provided by make. If your target is called foo.elf:

make foo.flash

should flash the data via ST Link and gdb, but it fails for me:

warning: ../libopencm3/scripts/stlink_flash.scr: No such file or directory

However there is a direct approach:

make foo.stlink-flash

Note that st-util must not be running—otherwise you’ll get an error.


I think one can replace the ST Link software with OpenOCD16 which brings the freedom to talk to many different sorts of hardware. I’ve not tried it though.

Black Magic Probe

The Black Magic Probe17 is an open source JTAG and SWD adapter with integrated support for GDB’s remote debugging protocol. Essentially the BMP bridges between your host machine and the target ARM. You just connect it, point gdb at it, and get to work.

You can buy native hardware18, which is both designed for the BMP and supports its development.

You can also flash the firmware into any number of generic ARM boards. Having bought an official BMP, I had no qualms deploying it on the ST-Link part of a Nucleo19 board.