Blink for stm32f4-discovery board on Linux with Makefile

I was inspired by this great post by Ross Wolin to make (yet) another blink tutorial for the stm32f4-discovery board on Linux. Ross Wolin did a great job writting makefiles for the peripheral library and reading his makefiles showed me how to actually work with the library, which is what I wanted because I like to write my own Makefiles and know what happens during the compilation process. IDEs like Eclipse are OK, but when learning, they stand in my way. Ross’s code however does not really use the peripheral library. This led me to adapt his code and Makefile and make a (almost) new one. His code can be found on Github. There is also a very cool GPIO tutorial by Elia for the stm32f4 here. Elia put his Makefile on Github, so I had one more case to study. Elia’s code is very obscure if you are just getting startet with C code, so his code made me want to write some clearer code.

Needed tools

In order to develop for the stm32f4-discovery board on Linux you need a few tools:

  1. GNU toolchain for  the ARM Cortex-M. This toolchain contains the compiler (gcc), debugger (gdb)  and other utilities used to generate machine code for the ARM-architecture. You can download it for free from Launchpad here:

    After downloading, extract the archive somewhere. It does not matter where you extract it. I have put it under /opt/gcc-arm-embedded/ so the path to the gcc compiler is /opt/gcc-arm-embedded/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gcc. Your download may have another version number.

  2. The stlink utility written by texane. The package contains two programs: st-util and st-flash.

    st-util is a gdb server (that is a server taking commands from gdb over network) which on one side connects to the serial port of the discovery board and on the other side listens at TCP port 4242 on localhost, where gdb is also connecting and sending instructions. Such instructions are for instance loading the program into the flash memory, setting break points and so on. st-util converts the instructions from gdb into actual hardware signals which the board understands and sends them to the serial port of the board. This is how you debug on the chip the discovery is used to write or read the flash memory of the board. You can use this to just flash the executable without debugging. Note that after loading the programm with st-util and gdb, the program stays in memory so you don’t have to flash again.

    You can download stlink here:

    Installation and usage instructions are found in the downloaded archive (or cloned repository, if you use git). Don’t forget to copy the udev rules.

    Archlinux users: you’re lucky, stlink is in the AUR.

  3. STMF4 Discovery board firmware package. This is a package of headers and source files which you can use to access the board peripherals by using symbolic names. Without this package, you have to know the exact memory mapping of the board and do a lot of initialization work before you actually write some useful code. You will compile the C source files and link them together with your own code.
    You can download the peripheral library here:

    After downloading, extract it somewhere in your workspace. Its exact location will be entered in the makefile. In my case, I have extracted the archive into $HOME/workspace/stm so the location of the Utilities folder of the library is $HOME/workspace/stm/STM32F4-Discovery_FW_V1.1.0/Utilities/.

  4. make. This should be preinstalled on all Linux machines.

This is actually all you need to develop for the stm32f4 discovery board on Linux (except the board itself).

Code sample

Code sample, a makefile and usage instructions can be found here:

All files written by me are commented.


You might also want to have a look at the related documentation found on this page and at the reference manual for the STM32F4* boards.

Writting the makefile

If you have no problems reading the makefile I wrote, you can skip this section because I will try to explain a basic strategy for writting a makefile when dealing with an external library like the standard peripherals library for the stm32f4 board.

Writting a makefile is more or less a matter of trial an error. After setting up the compiler’s flags like -Wall, -mcpu=cortex-m4 and so on, you try to compile your code. If you get errors about missing headers, you search for the missing header file and add its directory to the “include directories” option of gcc (that is to the “-I” option). If you get link-errors about gcc not finding some reference or function, you search the library for the C-file implementing that function and add this file to the list of source files to compile. Then you try again to compile.

Thus, in the makefile I wrote, you find two variables: INC_DIRS and SRCS. Every time I was missing a header file, I used my file manager to search the library’s folder for that file and added it’s directory to the variable INC_DIRS. The variable INCLUDE, defined later, is build by using the make-function addprefix to add the prefix -I to every directory in the variable INC_DIRS. It contains a string like “-Idirectory1 -Idirectory2 -Idirectory3“. INCLUDE is then passed as argument to gcc, which will search those directories for the missing header files.

The second variable, SRCS (for “sources”), holds a list of all source files to compile. Every time a got an undefined reference error to some function, I used the file manager to search for the C-file implementing that function and added the file name to SRCS (only the base name, without path). The next thing to do after adding a file name to the sources list, is to tell make where to look for that file, because it will not be in the current directory and make will not find it. You do this by using the make-function vpath (for “virtual path”). Thus, the line vpath %.c $(STM_SRC) tells make to look in the directory $(STM_SRC) every time it does not find a .c file in the current directory.

4 thoughts on “Blink for stm32f4-discovery board on Linux with Makefile”

  1. Hi liviu Thank you, thank you Thank you for this work. This was amazing. Well done. You have done a lot of work here. I am building of your good work. I have been researching for work like lours, like forever ! ha ha ! I am documenting all my work. And will be share open source everything, once I’m all done. It’s based on USB HID communication to Arch linux running on Raspberry pi, headless Archlinux, lua and elua, a tiny webserver.
    I’m developing a complete control system to access and control anything, like and engine or a 3d printer for example. Everything can be accessed through a phone, tablet, pc. no need to install software it’s all control thorough web app. The micro-controllers are plunged in a usb hub. anyway, it’s too big to discuss, here, if your interested, let me know, I could use a guy like you.
    Cheers mike.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s