I recently picked up an STM32F0 board from Digikey, and set about making it work on the Mac. Some documentation I found was slightly outdated for Yosemite and didn’t cover everything needed.
This is what I had to do:
libusb is a library that wraps common USB interactions so that application developers don’t have to tear their hair out dealing with the vagaries of dealing directly with USB. The STLink programming software will use it.
If you don’t already have it, you’ll need to install Homebrew, a package manager for Mac OS X that makes it easy to install popular open-source libraries.
Once Homebrew is installed, open a Terminal and type this:
brew install libusb-compat
After a short period of time, you will be returned to the bash prompt.
Clone, build and install the STLink programmer software
Originally intended for Linux, this open-source programmer knows how to speak the ST-Link v2 protocol that the Discovery board uses.
git clone firstname.lastname@example.org:texane/stlink.git cd stlink ./autogen.sh ./configure make sudo make install # enter your password here..
Once the install has completed, you should be able to type
which st-flash and have it return
/usr/local/bin/st-flash (or, if you changed the
--prefix setting in the configure script, wherever you ended up installing it to.)
Install the Mac OS X STLink driver
The driver is included in the stlink git repository so we’ll unpack and install it while we’re here.
cd stlinkv1_macosx_driver tar -zxvf osx.tar.gz
Convince Yosemite to load unsigned kernel extensions
Added in recent versions of Yosemite, Apple has attempted to crack down on third-party kernel extensions (such as the STLink driver we’re trying to install) by forcing code signing. If you attempt to install the driver right now, you will end up with some error messages and nothing will happen.
sudo nvram boot-args="kext-dev-mode=1"
Now restart your Mac. Don’t forget to come back here!
Modify the osx/install.sh file
osx/install.sh file in your favorite text editor.
Change the case statement from
Change the references to
When you’re done the file should look something like this:
#!/bin/bash ISOSXLION=$(sw_vers -productVersion) case $ISOSXLION in 10.6*) KEXT="stlink_shield10_6.kext" ;; 10.7*) KEXT="stlink_shield10_7.kext" ;; 10.8*) KEXT="stlink_shield10_8.kext" ;; 10.9*) KEXT="stlink_shield10_9.kext" ;; 10.10*) KEXT="stlink_shield10_10.kext" ;; *) echo "OS X version not supported." exit 1 ;; esac chown -R root:wheel osx/$KEXT/ cp -R osx/$KEXT /System/Library/Extensions/stlink_shield.kext kextload -v /System/Library/Extensions/stlink_shield.kext touch /System/Library/Extensions
Install the STLink driver
After all that we can finally install the STLink driver. Invoke the following from the
sudo make osx_stlink_shield
If all goes well, you should see a message about the
stlink_shield.kext being successfully loaded.
Test it out
Run the following:
cd ../ # in the root of the git repository ./st-util
You should see something like the following:
2015-07-10T18:46:38 INFO src/stlink-usb.c: -- exit_dfu_mode 2015-07-10T18:46:38 INFO src/stlink-common.c: Loading device parameters.... 2015-07-10T18:46:38 INFO src/stlink-common.c: Device connected is: F0 device, id 0x20006440 2015-07-10T18:46:38 INFO src/stlink-common.c: SRAM size: 0x2000 bytes (8 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 1024 bytes 2015-07-10T18:46:38 INFO gdbserver/gdb-server.c: Chip ID is 00000440, Core ID is 0bb11477. 2015-07-10T18:46:38 INFO gdbserver/gdb-server.c: Target voltage is 2929 mV. 2015-07-10T18:46:38 INFO gdbserver/gdb-server.c: Listening at *:4242...
Install the GCC ARM tools
- Get the Mac installation tarball from here.
- Unpack the tarball with
tar jxvfto a handy directory (I used
- Add the
bindirectory from the unpacked tarball to your
$PATH. Edit your
.bash_profileor whatever other file launches for your shell.
Make sure the ARM tools are installed properly
Run the following from a new Terminal window:
You should see this text, among other things:
GNU gdb (GNU Tools for ARM Embedded Processors) 22.214.171.12450304-cvs Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi".
OpenOCD is a nice tool for pushing your code to the device.
Now you can start building code and deploying it to the discovery board.
Download the basic template project
Mike Szczys has developed a template project that gets you started on the Discovery.
Clone it from Github and build it. It should succeed, if the ARM tools were installed properly. You should end up with a
If you installed OpenOCD, running
make program will install and launch the program on the Discovery board. You can tweak the timing and reinstall it to make sure that it actually did something.
Stuff should be running, congratulations.
Note that I am unsure as to if the ST license allows redistributing the files from the StdPeriph lib. My template project references the ST files in the Makefile without directly including them in the repo. That said, Mike Szczys’ template project was a bona fide life saver on this one and provided missing chunks such as the startup code, OpenOCD configuration files and linker scripts that I copied.
New projects should use his template project if at all possible.
Download the ST standard peripherals library
These files will be important if you want to write code without checking in the StdPeriph lib files, or if you wish to target a different device.
You can go here to get them.
Some important directories:
Libraries/CMSIS/Include: Core include files
Projects/STM32F0xx_StdPeriph_Templates: Device conf headers
Libraries/CMSIS/Device/ST/STM32F0xx/Include: Device headers
Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates: Device library files (statically link against these)
Libraries/STM32F0xx_StdPeriph_Driver/inc: Peripheral headers
Libraries/STM32F0xx_StdPeriph_Driver/src: Peripheral library (statically link against these too)
If you’re anything like me the first time you wrote some code the board didn’t seem to do anything. Don’t worry. The debugger is here.
Once you’ve started the gdb bridge from STLink (in a previous step), launch the ARM GDB and connect to the bridge.
(gdb) target extended-remote :4242 Remote debugging using :4242 Cannot access memory at address 0xffffffff 0x08000358 in ?? ()
You can restart the program from the beginning of execution using
monitor reset, and then step, set breakpoints, etc like you would normally in GDB.
If you have never used GDB before, the RMS tutorial is a handy guide.
Symbols can be loaded like this, prior to connecting to the remote:
(gdb) symbol-file blink.elf Reading symbols from blink.elf...done. (gdb) target extended-remote :4242 Remote debugging using :4242 0x080003d8 in WWDG_IRQHandler ()
Problems I encountered
I failed to provide
-mthumb to the linker even though I had provided it to the compiler. This apparently caused it to break trying to switch instruction sets.
OpenOCD push failed in
I had the gdb-server running at the same time. Killing it let me communicate with the device again and push code to it.
Complaining about missing
There is no
_exit in the libc for this device, because where would you exit to on an embedded device?
Stripping sections during linking by passing
--gc-sections to the linker ended up taking care of this problem, as it removed the pieces of libc (such as
exit) that called these missing implementations.
The following sources were helpful in figuring this one out: