BareMetal GCC: STM32 ARM Cortex M0


This web page guides in programming the STM32F0 ARM microprocessor series. The aim is to provide a compelling, easy to use method using an open source toolchain setup next to the commercially available products like Keil, mbed, etc. The setup can be summarized as making use of:

  • STM32F0 (ARM Cortex M0) MCU (STM32F051 specifically), soldered on a breakout board
  • Debian based (e.g. also Ubuntu, Mint, etc).
  • GNU gcc standard compiler
  • For flashing: stm32flash
  • Standard STM library STM32F0Cube

A note here on packaging and soldering: the STM32 MCU's are not available in DIP packages, but soldering Surface Mound Technology Devics (SMT's) is relatively easy. It's is worthwile to be able to solder SMT, wich opens up a wealth of other Integrated Circuits to be used in your projects. In oder to learn SMT soldering, there are plenty of tutorials on Youtube and elswhere on the internet explaining how to do it. A standard soldering iron, solder, and solder flux will do. To get started, it is worthwile to explore the different sizes in which MCU's can be ordered. The STM32F051 is available for instance in 48-pin LQFP48 package, which has a pitch of 0.5mm between the pins, but also the LQFP32 version with a pitch of 0.8mm and easier to begin with. There are also TSSOP20 MCU's like the STM32F030, which are dual in line with a pitch of 0.65mm. Below a picture of the MCU used in this example, soldered on a standard PCB

STM32 MCU for baremetal programming

Setting up the GNU Toolchain

The set of programs used to compile and flash code to a microcontroller is named toolchain. As of writing, the standard GNU compiler toolchain can be used to compile source code into executable binaries. In order to obtain the toolchain it is cimply a matter of installing the correct package. On Debian, and Debian-based distributions like Ubuntu, Mint, etc, this can be done either via a package manager like Synaptic (which is a front-end for apt), or using apr directly on the command line:

sudo apt-get install gcc-arm-none-eabi

Some background here: a special version of the gcc compiler is required for compiling code for a target processor other than the host computer. This is called cross-compiling. That explains the gcc-arm version of the compiler. The “none” version is needed to indicate the use without an operating system (also known as baremetal programming). If we were to compile a program used for an OS, some parts of the program can / should make use of the OS provided functions, for instance when allocating and referencing memory. Without an OS, these standard function need to be linked and added to the binary you are compiling. This will also install the other required packages like binutils and the c-library.

Next to this, in order to flash your binary to the MCU, a program called stm32flash will be used:

sudo apt-get install stm32flash

Acquire the STM32F0 libraries

The example used here, makes use of the open source libraries provided by STM for the selected MCU. These can be downloaded from the STM site directly, or by downloading the same library via the created git repository. The latter also requires the git package to be installed:

sudo apt-get install git

after which the STM32 library can be cloned:

git clone

Next to that, the source code of the example below can now also be installed (without changing directory) from the previous command:

git clone

Note that this also provides the needed makefile for using the STM32 library with the GNU compiler. The linker script is already

Setting up the programmer and STM32F051

In this case, the Adafruit FT232H Breakout board is used to program the MCU. The FT232H is used in this case as a USB to UART modem. Likely, other UART’s can be used as well. The LPC MCU has a bootloader which check upon reset (when Reset pin 23 is pulled low), if pin 24 is pulled low as well. In that case, pin 15/16 can be connected to a UART device (with RX and TX lines) to upload the binary, see figure below. The lpc21isp program can be instructed to use the additional DTR and RTS UART signals to control the reset – and bootloader pin. Next to that, the LPC needs to be powered by a 3.3V power source and grounded with the UART device. Here a breadboard is used to achieve all needed connections.

Hello World Example

And here's the last step