STM32F4 – Template Project with Generic Makefile

In this tutorial I provide a template project based on the Hello world! project with a generic Makefile that is easily-customizable. This reduces the overhead to create the project environment, because you may change, add or remove source files without modifying the Makefile, just like Spock it has one facial expression/one Makefile for many feelings/many projects. 🙂


1. Prerequisites

2. Install Software Dependencies

Use third party GCC suite rather than official, because the latter currently (Aug 2014) lacks C++ library.

cd ~
# Remove the official package
sudo apt-get purge binutils-arm-none-eabi \
                   gcc-arm-none-eabi \
                   gdb-arm-none-eabi \

# Add 3rd party repository
sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
sudo apt-get update
# Check the GCC package version in the PPA repository
sudo apt-cache policy gcc-arm-none-eabi

# Install software requirements
sudo apt-get install build-essential git openocd \
 gcc-arm-none-eabi qemu-system-arm \
 symlinks expect

# Clone my git repository & init submodules
git clone
cd ~/stm32
git submodule update --init

3. Build and deploy the template project

The project tree below describes the project structure. It is based on the “Hello World!” project.

cd ~/stm32/examples/Template
# tree
# .
# ├── bin # DON'T TOUCH
# ├── inc # DON'T TOUCH
# │ ├── CMSIS/Include
# │ ├── stm32f4_discovery.h
# │ ├── STM32F4xx/Include
# │ ├── stm32f4xx_conf.h
# │ ├── stm32f4xx_it.h
# │ └── STM32F4xx_StdPeriph_Driver/inc
# ├── src # DON'T TOUCH
# │ ├── main.c
# │ ├── misc.c
# │ ├── startup_stm32f4xx.s
# │ ├── stm32f4_discovery.c
# │ ├── stm32f4xx_exti.c
# │ ├── stm32f4xx_gpio.c
# │ ├── stm32f4xx_it.c
# │ ├── stm32f4xx_rcc.c
# │ ├── stm32f4xx_syscfg.c
# │ └── system_stm32f4xx.c
# ├── Makefile # DON'T TOUCH
# └── stm32_flash.ld

The template should automatically adjust to your project changes as long you keep the directory structure intact, i.e. bin, inc and src folders.

  • You may add or remove header files (*.h) from the inc folder, add subdirectories or even use symbolic links. The Makefile script automagically finds appropriate files. 😉
  • You may add or remove C (*.c) or Assembly (*.s) source files from the src folder, add subdirectories or use symbolic links.
  • Don’t touch the Makefile unless, unless necessary.
  • Build and deploy the project as follows.
    make clean && make -j4 # Size optimized build
    # Other build options
    # make clean && make -j4 release-memopt # Size opt. build
    # make clean && make -j4 release # Non-optimized build
    # make clean && make -j4 debug # Debug build
    sudo make deploy # Deploy on ST32F4XX target platform

Q: Deployment fails repeatedly due to some OpenOCD issue. 😦 Is there a workaround?
A: Yes, the current official Ubuntu package (Aug 2014) contains a prehistoric OpenOCD version. You should build a newer version from scratch. I provide step-by-step instructions here (2nd section, it takes less than 3 minutes to build it). When you are done, just return here and continue as nothing happened. It will work out of the box. 🙂

Further Reading

This generic template is useful, because it eases project building. However, it leaves you on your own at project setup. It is your responsibility to add source files, appropriate libraries, etc. Because project initialization is time-consuming task as well, I provide a project wizard that accomplishes this for you in no time. 😉


About istarc

Embedded Systems Developer.
This entry was posted in Embedded Systems, STM32F4 and tagged , , , , , . Bookmark the permalink.

2 Responses to STM32F4 – Template Project with Generic Makefile

  1. su says:

    hey, all the instruction work fine and when i do make deploy, there are lots of error as following
    supriya@supriya-Vostro-3546 ~/stm32/examples/test-mbed-none $ make deploy
    /opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/board/stm32f4discovery.cfg -c “program bin/”outp.elf” verify reset”
    Open On-Chip Debugger 0.9.0-dev-00346-g3e1dfdc (2015-03-20-17:08)
    Licensed under GNU GPL v2
    For bug reports, read
    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
    adapter speed: 2000 kHz
    adapter_nsrst_delay: 100
    none separate
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    Info : Unable to match requested speed 2000 kHz, using 1800 kHz
    Info : Unable to match requested speed 2000 kHz, using 1800 kHz
    Info : clock speed 1800 kHz
    in procedure ‘program’
    in procedure ‘init’ called at file “embedded:startup.tcl”, line 471
    in procedure ‘ocd_bouncer’
    in procedure ‘transport’
    ** OpenOCD init failed **
    shutdown command invoked
    embedded:startup.tcl:449: Error:
    in procedure ‘program’
    in procedure ‘program_error’ called at file “embedded:startup.tcl”, line 472
    in procedure ‘shutdown’ called at file “embedded:startup.tcl”, line 449
    make: *** [deploy] Error 1

    can u please help, thanks in advance.

  2. sai charan says:

    It is because adapter speed of debugger is greater than the clock speed, normally it should be just 1/6th of the clock speed! You should change the speed in settings.

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