From zero to a C++ STM32 development environment

It’s been a while since I wrote an article about my stm32plus C++ library for the STM32 series of MCUs so I thought I’d combine a long overdue catchup with a step-by-step tutorial that will show you how to set up a completely free and unrestricted STM32 development environment from scratch. I’ll cover setting up the graphical Eclipse IDE as well as a command line environment. The development environment will include an installation of my stm32plus library that makes it easier to access the STM32 peripherals using C++ programming techniques.

I’ll be covering Windows 7 in this article and Ubuntu Linux in a followup. I’ll be running the tutorials myself inside a fresh installation of each of the operating systems to ensure that no steps are missed and by the time we’re done you’ll have a free and modern development system ready to write and debug code for the STM32 MCU family.

I’m using the 64-bit version of Windows in this tutorial but the same steps apply if you’re using the 32-bit version and where a choice exists between installing a 32 or 64 bit version of something I’ll make it clear which one I’m using.

Step 1: Install Cygwin

Cygwin is an ambitious open-source project designed to replicate a Posix command-line environment as close as can be done on Windows. I’ve used it for as long as I can remember and, although it’s not without it’s limitations, I could not do without it. The first thing I do after powering up my Windows system is to open up a cygwin xterm.

Visit the Cygwin website and download and run the setup executable. I’ll be running the 32-bit version which works just as well on 64-bit Windows.

At the first screen I chose the options that don’t require Admin rights. The cygwin package will be installed into my home directory and it’ll be set up for my use only.

Click through the installer until you get to the page that asks you which packages you want to install. We need to add a few extra packages to the default so that we can get a coherent and comfortable development environment. To install a package, click on the little rotating arrows icon next to the name. Change the following packages to be installed:


Be careful if using the ‘Search’ box at the top of the screen because it seems to have a bug that causes it to clear the installed status of any top level packages such as ‘X11’.

You’ll get the ‘vim’ editor by default and I deliberately haven’t specified any additional editors in the above package list because editors are a very personal preference. Cygwin does offer a selection of additional editors so if ‘vim’ isn’t your cup of tea then have a look at the alternatives. You can of course use any of your Windows-based editors as long as they support Unix (LF) line endings. My personal favourite is currently Sublime Text.

When you’ve got all of the above selected, continue with the installation. It’ll take quite a while to download and install. The great thing about the installer is that you can re-run it at any time afterwards to add or remove packages and it’ll automatically upgrade any components for you as well.

Prepare and personalize cygwin

Cygwin’s basic installation will plonk a ‘Cygwin Terminal’ icon on your desktop. Go ahead and run it. You’ll get a fairly decent terminal that looks like this:

I prefer the X-Windows system and its ‘xterm’ terminal and I’m going to show you how to get that working.

  1. Navigate an explorer to the cygwin ‘bin’ directory. For me that’s ‘c:\Users\Andy\cygwin\bin’.
  2. Locate ‘XWin.exe’ and drag it to the desktop with the right mouse button. Choose ‘Create shortcut here’ from the menu that appears when you let go of the mouse button.
  3. Right-click on the new shortcut and choose ‘Properties’. Append ‘-multiwindow’ to the text in the ‘Target’ field.

Double-click on your new ‘XWin’ shortcut. Nothing will appear to happen except that you should now see a little ‘XWin’ icon down in the taskbar tray area that indicates that XWin is running. XWin must be running in the background like this before you can start any client programs such as ‘xterm’.

Now we’ll create a shortcut to the xterm terminal program. Right-click on the desktop and choose ‘New -> Shortcut’. In the box that appears paste this line, changing the pathname of ‘run.exe’ to match your system:

C:\Users\Andy\cygwin\bin\run.exe /bin/xterm.exe -display :0 -ls -sb +tb -fg cornsilk -bg #404040

Click through the rest of the wizard and give the shortcut any name you like. Now run the shortcut and you should see something like this.

If you don’t like the colour scheme then simply change the ‘fg’ (foreground) and ‘bg’ (background) options in the shortcut.

Step 2: Install the ARM EABI g++ compiler

Some enterprising engineers at ARM have decided to maintain a free distribution of the gcc/g++ compiler package for ARM EABI. It contains everything you need to compile STM32 programs and is very up-to-date so we’re going to use it. Navigate to the website and download the Windows zip package.

When it’s finished downloading we’ll unzip it using our new cygwin xterm:

Note the /cygdrive/c/ prefix. That’s how cygwin converts drive letters into paths that are useable by the Unix tools. Now we’ll add the compiler tools to our PATH environment variable so that it’s always there when we need it.

Step 3: Install java

The Eclipse IDE is written in Java so we need to install the runtime environment (JRE). Head to the java website and install the latest version that’s on offer. Note that the big button on the javasoft home page will install the 32-bit edition. If you’re running 64-bit windows then you need to download and run the offline installer. You can find it on this page. This is important because the bitness of java must match the bitness of Eclipse that we’ll install in the next step.

Warning! A poor commercial decision made by Sun in the early days and inherited by Oracle means that the java installer is bundled with some crapware that will interfere with your web browser and downgrade your search engine. Be careful when you navigate through the installer and come across this page.

Be sure to uncheck the two options that are of course checked by default to trap the unwary.

Step 4: Install the Eclipse CDT

Eclipse is a powerful IDE that will allow us to edit, compile and debug all in one place with syntax highlighting, code refactoring and intelligent navigation. Navigate to the Eclipse downloads page and choose the latest version for ‘Eclipse Kepler’. The reason for choosing Kepler over the newer versions is that we need to stay compatible with the plugins that we’re going to use and at the time of writing the GNU ARM Plugin is most compatible with Kepler.

This is the link for the Windows x64 version and this is the link for the Windows 32-bit version.

Eclipse is delivered in a large zip file. When it’s downloaded, extract it to your Windows profile home directory. When it’s complete I have a new ‘c:\Users\Andy\eclipse’ directory. Navigate an explorer to your equivalent of ‘C:\Users\Andy\eclipse’ and locate ‘eclipse.exe’. Drag it with the right mouse button to your desktop and choose ‘Create shortcut here’. Right-click on the shortcut and choose ‘Properties’. Append a ‘-vm’ option that points to your java installation like this:

Now you can double-click on the eclipse shortcut and it will load up. The first time it loads you’ll get asked where you want the workspace location to be.

The workspace directory is where eclipse will search for all your projects. This is the root directory for your source code so I’m changing it to a location within my cygwin home.

We’re now ready to install the GNU ARM Eclipse plugin.

Step 5: Install the GNU ARM Eclipse plugin

Select the ‘Help/Install new software’ menu option. In the form that appears, paste this URL into the ‘Work with’ box and press enter:

The dialog box will update itself with the contents of the plugin.

Click your way through the installer and wait for it to finish. Eclipse will want to restart itself when the plugin is installed.

Now we need to install the ‘Build Tools’ package for Windows. We need this because the plugin uses the ‘make’ and ‘rm’ commands to build projects and neither of these are available in Windows. The current location of the tools is here. Follow the instructions on that page to install the package. In keeping with our Cygwin-based setup I changed the installation directory to ‘C:\Users\Andy\cygwin\home\Andy\install\build-tools’.

Now go to the Project menu and uncheck “Build Automatically”. That’s a useful option for java development but less so for C++ and it’ll just annoy you by attempting a build each time you save a file.

Finally we need to tell Eclipse where the toolchain files are. Go to ‘Window/Preferences’ and open up ‘C/C++/Build/Global Tools Paths’. Fill in the directory containing the build tools in the first field and the directory containing ‘arm-none-eabi-g++’ and others in the second field.

Click for larger

Your development environment is now complete and the next steps will walk you through getting started with the stm32plus library.

Step 6: Create an stm32plus project

In this project I’m going to help you to create a classic ‘blink’ project that will run on the STM32 F4 Discovery board. The first step is to check out and build the stm32plus library. If you haven’t already got an xterm open then do that now and enter the following commands:

cd ~/src
git clone

It’ll look like this:

Before getting into the Eclipse setup let’s build stm32plus inside the terminal for the F4. This build that we’ll perform using ‘scons’ is independent from the build that we’ll use in Eclipse. This is the command line that we’ll use for the build:

scons mode=debug mcu=f407 hse=8000000 -j12 install INSTALLDIR=~/install/stm32plus

Change into the stm32plus subdirectory and run the command. The options we use specify that we’re doing a debug build targetting the STM32F407 MCU with an 8MHz external oscillator and we’d like the output from the build installed into ~/install/stm32plus. The -j12 option tells scons to execute a parallel build using a maximum of 12 jobs. You should change the number 12 to be approximately the number of cores that you have in your computer.

After a few minutes of building you’ll be left with the stm32plus library and examples installed into the ~/install/stm32plus directory. Now we’ll move on to the process of building and editing your projects in Eclipse.

Run Eclipse if you haven’t already done so and navigate to the ‘File/Import…’ option. Select ‘General/Existing Projects into Workspace’ Click ‘Next’ and you’ll be presented with the ‘Import Project’ dialog. Click ‘Browse’ and choose the ‘stm32plus’ subdirectory from your Cygwin ‘src’ directory. Eclipse will automatically find all the stm32plus project files. There’s one for the library and one each for the many, many example projects.

Click ‘Finish’ and Eclipse will do its thing and import all the projects. You can see them in the ‘Project Explorer’.

We’ll build the library first. It’s the first in the project explorer list (highlighted in the image above). Right-click on the project and select ‘Build Configurations/Set Active/Debug_f407_168_8’. This ensures that we’ll target the STM32F407 that’s included on the discovery board.

Right-click on the project again and choose ‘Build Project’. The build will start and a progress dialog will appear. I recommend that you choose ‘Run in background’ and select the ‘Always run in background’ option. You can then select the ‘Console’ tab at the bottom of the IDE to see the build output. This is where any errors will be reported so it’s a very important view to have open.

A successful build will result in console output similar to the image above. Now that you’ve built the stm32plus library, let’s build the blink example just to round things off. Locate the ‘stm32plus-examples-blink’ project in the project explorer, right-click and change the build configuration to ‘Debug_f407_168_8’ just like you did for the main library. Again, right click on the project and choose ‘Build Project’. You’ll see output like this:

16:54:31 **** Build of configuration Debug_f407_168_8 for project stm32plus-examples-blink ****
make all 
Building file: ../system/f407_168_8/Startup.asm
Invoking: Cross ARM GNU Assembler
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra  -g3 -x assembler-with-cpp -DSTM32PLUS_F407 -DHSE_VALUE=8000000 -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\include" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\examples\blink" -MMD -MP -MF"system/f407_168_8/Startup.d" -MT"system/f407_168_8/Startup.o" -c -o "system/f407_168_8/Startup.o" "../system/f407_168_8/Startup.asm"
Finished building: ../system/f407_168_8/Startup.asm
Building file: ../system/f407_168_8/System.c
Invoking: Cross ARM C Compiler
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra  -g3 -DSTM32PLUS_F407 -DHSE_VALUE=8000000 -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\include" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\examples\blink" -std=gnu11 -MMD -MP -MF"system/f407_168_8/System.d" -MT"system/f407_168_8/System.o" -c -o "system/f407_168_8/System.o" "../system/f407_168_8/System.c"
Finished building: ../system/f407_168_8/System.c
Building file: ../system/LibraryHacks.cpp
Invoking: Cross ARM C++ Compiler
arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra  -g3 -DSTM32PLUS_F407 -DHSE_VALUE=8000000 -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\include" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\include\stl" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\examples\blink" -std=gnu++0x -fabi-version=0 -fno-exceptions -fno-rtti -pedantic-errors -fno-threadsafe-statics -MMD -MP -MF"system/LibraryHacks.d" -MT"system/LibraryHacks.o" -c -o "system/LibraryHacks.o" "../system/LibraryHacks.cpp"
Finished building: ../system/LibraryHacks.cpp
Building file: ../blink.cpp
Invoking: Cross ARM C++ Compiler
arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra  -g3 -DSTM32PLUS_F407 -DHSE_VALUE=8000000 -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\include" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\include\stl" -I"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\examples\blink" -std=gnu++0x -fabi-version=0 -fno-exceptions -fno-rtti -pedantic-errors -fno-threadsafe-statics -MMD -MP -MF"blink.d" -MT"blink.o" -c -o "blink.o" "../blink.cpp"
Finished building: ../blink.cpp
Building target: stm32plus-examples-blink.elf
Invoking: Cross ARM C++ Linker
arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra  -g3 -T "C:\Users\Andy\cygwin\home\Andy\src\stm32plus\examples\blink/system/f407_168_8/Linker.ld" -Xlinker --gc-sections -L"C:\Users\Andy\cygwin\home\Andy\src\stm32plus\lib\Debug_f407_168_8" -Wl,-Map,"" -Wl,-wrap,__aeabi_unwind_cpp_pr0 -Wl,-wrap,__aeabi_unwind_cpp_pr1 -Wl,-wrap,__aeabi_unwind_cpp_pr2 -o "stm32plus-examples-blink.elf"  ./system/f407_168_8/Startup.o ./system/f407_168_8/System.o  ./system/LibraryHacks.o  ./blink.o   -lstm32plus
Finished building target: stm32plus-examples-blink.elf
Invoking: Cross ARM GNU Create Flash Image
arm-none-eabi-objcopy -O ihex "stm32plus-examples-blink.elf"   "stm32plus-examples-blink.hex"
Finished building: stm32plus-examples-blink.hex
Invoking: Cross ARM GNU Create Listing
arm-none-eabi-objdump --source --all-headers --demangle --wide -h -S "stm32plus-examples-blink.elf" > "stm32plus-examples-blink.lst"
Finished building: stm32plus-examples-blink.lst
Invoking: Cross ARM GNU Print Size
arm-none-eabi-size --format=berkeley "stm32plus-examples-blink.elf"
   text	   data	    bss	    dec	    hex	filename
   4612	   2128	   1116	   7856	   1eb0	stm32plus-examples-blink.elf
Finished building: stm32plus-examples-blink.siz

16:54:33 Build Finished (took 1s.606ms)

Your edit/build environment is complete. You can now build from a terminal using scons and you can build from Eclipse. Let’s move on to creating a project of your own that references the stm32plus library.

Step 7: Creating a project of your own

It’s possible to create a project from scratch in Eclipse using wizards and stuff like that but I’ll teach you a little shortcut that can have a new project up and running in seconds by cloning an existing project. We’ll create a project called ‘myproject’ by duplicating the ‘blink’ example and making a few basic edits.

From your terminal, duplicate the project like this:

Now use your favourite text editor to edit ‘myproject/.project’ and change the name in the XML to ‘myproject’ as shown in the highlighted text below.

That’s all you need to do outside Eclipse. Save your changes and use the Eclipse ‘File/Import’ and ‘General/Existing project into workspace’ option to bring this new project into your workspace.

As a bit of housekeeping, you should delete any previous output directories that came over with the project copy. In the image above I highlighted the Debug_f407_168_8 directory and pressed the Del key to delete it from disk.

To prove that it works, right-click on the project in the project explorer, ensure that the ‘Debug_f407_168_8’ build configuration is active and then choose ‘Build project’. It should build with no errors.

Now we’ve got as far as creating a skeleton project that you can use as a springboard for building your own project let’s take it to the next level and do some integrated debugging.

Step 8: Install OpenOCD

Debugging a high-level language such as java, C# or even C++ in a modern IDE is a seamless experience and you’re probably unaware of how it’s done behind the scenes. Debugging an ARM binary that’s running outside your PC on a development board is not quite so integrated and it helps to understand the basics of what’s going on.

On the discovery board hardware debug support is provided by a peripheral called ‘ST-Link v2’ whose logic is burned into an STM32F103 that you can see on the board near the USB connector. The code in this MCU is able to issue the commands that halt the main processor and enable single stepping through instructions and reading register values.

Eclipse cannot talk directly to the ST-Link; it doesn’t know how, and nor does the GNU ‘gdb’ debugger. That magic is provided by a debug server called ‘OpenOCD’. OpenOCD is an open source server process that is able to receive commands from ‘gdb’ and convert them internally to the ST-Link Serial Wire Debug (SWD) protocol to send to the discovery board. Eclipse will run gdb. gdb will talk to OpenOCD and openOCD will talk to the ST-Link chip. If it sounds convoluted then you’re right, it is, but it’s easy to set up and work with.

Freddie Chopin, public spirited chap that he is, has made precompiled OpenOCD binaries available for Windows at his website. Download the prepackaged binary and use your terminal to extract it like this:

On my system the file extract did not set the executable bit on the ‘exe’ and ‘dll’ files in the archive so I had to correct that like this:

Now it’s time to plug your F4 discovery board into your PC. Attach it using the mini-B connector, not the micro-B connector. If this is the first time that you’ve done it then you’ll get the following unhappy message:

If at some time in the past you installed the official ST driver then you won’t get the fail message but the procedure is the same. What we need to do is replace the Windows driver with the open source ‘libusb’ driver. This process is completely reversible so don’t worry about not being able to go back to using ST’s client software.

The utility that we require is called ‘zadig’ and can be downloaded from the official website. It doesn’t have an installer, just download and run the binary.

The image shows the options that you should select. Just hit ‘Install Driver’ and it’s done.

Optional: Run OpenOCD as a server

You can skip this step if you want to only debug in Eclipse. I just thought I’d explain how to start OpenOCD as a server process and how to connect to it and flash hex images from outside an IDE.

The package that you downloaded contains both the 64-bit and 32-bit versions. You must run the version that matches the bitness of your operating system. I’m going to run the server in a bog standard windows command prompt. You should automate this into a batch file so you can just double-click an icon to start OpenOCD.

Windows firewall will probably ask if it’s OK to allow OpenOCD to start as a server. Say yes. OpenOCD will then just sit there waiting to be contacted and given orders. The command to start OpenOCD on a 64-bit system, when executed from the ‘openocd-0.8.0’ directory is:

bin-x64\openocd-x64-0.8.0.exe -f scripts/board/stm32f4discovery.cfg

For 32-bit users the command is almost the same, we just remove the ‘x64’ parts:

bin\openocd-0.8.0.exe -f scripts/board/stm32f4discovery.cfg

The server is listening on port 4444 for interactive sessions. If you’ve built yourself a hex file then you can flash it to the debugger with a telnet session. Here’s an example where I halt the processor, flash a new image and then reset the processor to make it run the new program.

$ telnet localhost 4444
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> reset init                                                                                             
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080001e4 msp: 0x20020000
> flash write_image erase C:/Users/Andy/cygwin/home/Andy/src/myproject/build/debug-f407-8000000/blink.hex
auto erase enabled
wrote 16384 bytes from file C:/Users/Andy/cygwin/home/Andy/src/myproject/build/debug-f407-8000000/blink.hex in 5.881210s (2.721 KiB/s)
> reset

If you want to run a debug session from within the Eclipse IDE then you used to have to have an OpenOCD server session open like this in the background, but not any more…

Step 9: Debugging from within Eclipse

The GNU ARM plugin author has done some excellent work to integrate OpenOCD debugging into the IDE. Eclipse will take care of starting and stopping OpenOCD without you having to know about it. Let’s configure a debug session now.

Select the ‘Run/Debug Configurations’ option. A form will appear. Right-click on the ‘GDB OpenOCD Debugging’ option and select ‘New’ from the menu that pops up.

Click for larger

There are a few tabs to deal with here. Firstly, on the ‘Main’ tab, fill in the ‘C/C++ Application’ field to point to the .elf file produced by building ‘myproject’. If the ‘Project’ field wasn’t already set to ‘myproject’ then make it so.

Here’s the ‘Debugger’ tab. Set it up like I’ve done in the image, adjusting the ‘Executable’ locations for OpenOCD and arm-none-eabi-gdb.exe to wherever you installed them. Be careful to get the 32/64 bit version of OpenOCD that matches your OS.

Note also the ‘Config options’. I’ve picked the correct options for the F4 discovery board. If you are working with a different board then explore the ‘board’ directory to find the correct .cfg file for you.

The last tab that we need to edit is the ‘Startup’ tab. Change yours to match the image above. Let’s get debugging! Hit the Debug button and wait a few seconds while Eclipse asks OpenOCD to flash your executable to the discovery board and start a debugging session. Eclipse will ask you whether you want to switch to the ‘Debug perspective’. Say yes to that and a debug session will be displayed.

Click for larger

Upon startup your application will be halted ready for you to set breakpoints and prepare for debugging. Let’s set a breakpoint in the source code and let Eclipse run to it. Open the ‘blink.cpp’ file from ‘myproject’ and double-click in the margin to set a breakpoint. The breakpoint will be indicated by a blue circle (see image above).

When you’ve set the breakpoint, press ‘F8’ and your application will run and then stop at the breakpoint. It will look like the image above. You can use the variables window to drill down into your variables or you can just hover over a variable name in the source code. The memory window can be used to inspect the contents of memory addresses and the registers window lets you see what’s going on at CPU level.

Note that the hardware only supports a maximum of 6 breakpoints, something that you can see in the OpenOCD startup messages. Eclipse doesn’t know about this and will let you try and set more than that but if you do you’ll find it starts to behave very strangely, stopping at random places and missing your actual breakpoints.

Now that we’ve frozen our code we can single step through it using F6, step into method calls using F5 and out of methods using F7. When you’re ready to let it go just press F8, you can always suspend it again using the pause icon on the toolbar.


That’s all for this tutorial. I hope I’ve helped you Windows users get up and running with a free and open source STM32 development environment in which you can develop from a Unix-like terminal or from a graphical IDE and debug using a user-friendly visual debugger. It’s about as close to writing and debugging native PC applications as you can make it.

Did I miss something? Want to leave feedback? Feel free to leave a comment below. If you’re struggling somewhere in the process then please feel free to start a thread over at the forum where you can post the details and screen shots that’ll help me to get you going.

  • Carl

    Hi Andy ! Nice tutorial you wrote there. However I would like to know why did you add the -vm “path_to_JRE” option in the Eclipse shortcut ? It seems to work fine on my system without it…Have a nice day !

    • Hi Carl, thanks for your comments. If you don’t specify a -vm option then Eclipse will go off and look in typical installation locations to try and find one – succeeding in your case. Given java’s poor record on security holes I thought it was best to encourage people to get the latest patched version and to know exactly which one that they’re running.

  • Thelonious

    Hello Andy,

    It’s simply a matter of preference, but flashing STM32 is quite simple from Eclipse GUI, some short gdb script is enough. I have set things up that when ‘Play’ button is clicked, it flashes my board and goes into debugging mode. When ‘Debug’ is clicked, it skips step no 1. You almost feel like debugging a PC application ๐Ÿ™‚

    • Peter

      So – what is the simplest way to modify Andy’s excellent instructions so that it is possible to just flash the target and let it go. I often do not want to go into debug mode – only update the firmware.

      • If you don’t want to fire up Eclipse then you can just flash-and-go using an OpenOCD one-liner. For example, this will do it for me in Windows 7 using the F0 discovery board as an example. Modify paths accordingly for your OS:

        bin-x64/openocd-x64-0.8.0.exe -f scripts/board/stm32f0discovery.cfg -c “program p:/tmp/blink.hex reset”

        • Peter

          Thank you. What I would like, though, is to click the ‘run’ button in Eclipse to flash (and reset if necessary) the target.

  • Freddie Chopin

    Might be worth noting, that ST-Link should work perfectly fine with OpenOCD using “official” ST drivers. If you really want to install the drivers yourself, you should definitely prefer WinUSB drivers over old libusb-win32. Another thing – you don’t need to give “scripts/” in the -f argument for OpenOCD – this path is searched automatically (if it isn’t, try running OpenOCD from within bin/ or bin-x64/ folders, not from openocd-0.8.0/).

    BTW – for C++ you can try my own variant of ARM toolchain, which has disabled C++ exceptions (and some other options are a bit different) – see here –

  • jussy25

    Hi Andy,
    very glad someone does C++ in embedded environments. I recently installed Coocox and wonder if this eclipse installation would work with your setup and your library. Maybe you know Coocox by chance…?

  • Hi Andy, finally you wrote this tutorial. ๐Ÿ˜€ Thank you very much.

  • Jononi

    Just installed a new environment on a new mac computer, eclipse luna and latest arm eabi compiler (4.9-2015q1) following these instructions (disregarding any cygwin related ones) and using brew to install any missing packages. It went very smoothly, much better than my previous experience (it was almost 2 years ago…) Andy did a great job integrating this library with eclipse using the multiple build configurations. No more fiddling with the project properties to make it compile. Thumbs up!

  • Martin Szathmรกri

    Have you ever tried EmBitz?
    It works OOB, no setup required, and best of all, it’s totally free.

  • Marius Liebenberg

    Hi Andy

    I tried your library before but without success. I have just rebuild my system for Debian Wheezy and reinstalled the tool chains. I am trying your library again by following your instructions carefully (i hope). I can compile the master example but any other gives a number of errors. I am using a STM32F4 Discovery so I set the active config for 407_168_8.

    I have installed the openocd and I haev compiled and debugged other test projects from the STM32 plugin in Eclipse. I think my environment is working or a t least for standard stuff.

    I did notice that there is a F1 directory and the error seem to be involving F1 stuff.

    Description Resource Path Location Type

    ‘RCC_PLLMul_9’ undeclared (first use in this function) System.c /my_test/system/f1md line 43 C/C++ Problem

    Thanks for your help. I really want to use the library .

    • This is now fixed on the master branch.

      • Marius Liebenberg

        Thanks Andy. I pulled a new version and it seems to be good.

  • “scons mode=debug mcu=f407 hse=8000000 -j4 install INSTALLDIR=~/install/stm32plus” after I entered this command to xterm, scons was stopped building because of errors. I run again xterm by “Run as administrator” and scons have done building without any error. Andy, you may add this little info to the article.

    • Thanks for the tip Burak – it sounds like maybe your cygwin home dir or the install directory is not writable by non-admin users? I don’t run my cygwin sessions as administrator and all steps in this article were made on a freshly created windows 7 virtual machine.

      • Marius Liebenberg

        Strange, I install to my /home/user/directory and I have to use sudo or scons does not run. It reports that there are permission errors.

  • Phillip Dimond

    I just wanted to thank you for a fantastic writeup. I just rebuilt my STM32 Plus environment (after moving to Windows 10 I’m building VMs for all my development environments so I don’t have to keep building them every time I change Windows! ๐Ÿ™‚

  • Liviu Ionescu

    Hi Andy,

    Cygwin is the classical solution, but now it seems that [MSYS2]( is also getting some traction.



  • Zafer Elektrik

    Hi Andy,

    I’ve done what you have write but I couldn’t manage to done. First error is mkdir : command not found. And second No Java virtual machine found starting Eclipse. I’ll be greatfull if you can help me. My system is Win10


  • Marcell Gerzsenyi

    Hi Andy,

    Your STM32Plus library looks great, I want to try it on a custom board with F103C8T6 controller. As I see, for the scons there is a mcu=f1md option. I want to try an examle with eclipse, I doing your tutor From zero to … but at step 6 i cant find a build configuration for F100_MD. I need to create it, or is available just i can’t find? If I need to create it, what to modify? Need to do for all project one-by-one or is there a simpler method?

    Best regards, Marcell

    • Hi Marcel, support for the old F1 medium density boards was a recent contribution to the source code and I don’t think the author added any Eclipse configurations. It would need to be added project-by-project and I’m afraid it is a time consuming task.

      • Marcell Gerzsenyi

        Hi again ๐Ÿ™‚

        I tried some of the examples on my board, this is awesome ! If you need the configs I can send it to you. Another question, is it in your plans to add the CAN controller to your library?

        • Hi Marcel, I’m always interested in adding new configurations so it would be nice to receive one for the MD line. CAN support is on my radar, currently sitting behind USB on the F0 in the priority list.

          • Marcell Gerzsenyi


            I made configs for the following examples: adc_analog_watchdog, adc_single, adc_single_dma_multichan,blink, button, debug_semihosting,timer_dma_usart. All working, there was a problem in adc_dma_multichan with temperature sensing. And modified the System.c, now its calculating the PLL_MUL from the defined HSE_VALUE. if it cannot be calculated it get in a while(1); loop for debugging purposes. How can I send you these modifications to add?

  • Jordan Tewell

    Hi Andy

    How would I go about creating build configurations for slow and fast libraries in Eclipse?

    • Hi Jordan, you would start by creating a new configuration in Eclipse based on the Debug build for the MCU that you are interested in. Then go to the optimisation settings and select the options that you want. Note that optimised builds are not debuggable in any useful way which means you kind of lose what I think is the main reason for building within Eclipse, i.e. the interactive debugging.

  • Thanks for the tutorial! Got my STM32F4-discovery board working at last! One thing I found is that the ‘blink’ program and the myproject I copied from it needed a couple of edits to work with the STM32F4. The first is the check for the wrap-round on the timer which was reported as an error to UINT32_MAX not being defined. That check isn’t needed anyway as when you subtract one uint32_t from another to get a difference then you automatically get the correct answer during wrap-around without needing any checks in your code. So just remove the if-then section and replace it with:

    return now – start;

    The other change is documented in the comments section of the program: you need to change the pin initialization to : GpioD<DefaultDigitalOutputFeature > pd; and the two instances of pc[8] to pd[13].

    • Hi, thanks for that. I’m a little concerned why UINT32_MAX is undefined though. Nobody else reports problems of this nature, which compiler are you using?

      • I tried to follow your instructions so I’m using the compiler you recommended. I’m most likely doing something stupid. The ‘myproject’ version of blink does run even though the debugger shows an error?
        I’ve tried to capture a screenshot of the bottom part of the debugger showing the error – I don’t know if it’s attached properly to this post though.

        • It’s OK I can read the screenshot. That looks like an “error” from Eclipse’s built-in code scanner and not the compiler. These reports are often caused by the scanner not being able to find include files. I never use the “Problems” view and only ever look at the errors in the compiler console output.

  • Marcell Gerzsenyi

    Hi Andy

    Did you ever used LTO optimization? Made some test with different settings, and it looks interesting.

    library: O0, project: O0 :
    arm-none-eabi-size –format=berkeley “PowerSupply.elf”
    text data bss dec hex filename
    25832 2152 4240 32224 7de0 PowerSupply.elf

    library: Os, project: O0 :
    arm-none-eabi-size –format=berkeley “PowerSupply.elf”
    text data bss dec hex filename
    19428 2152 4240 25820 64dc PowerSupply.elf

    library: Os, project: Os:
    arm-none-eabi-size –format=berkeley “PowerSupply.elf”
    text data bss dec hex filename
    11060 2152 4236 17448 4428 PowerSupply.elf

    library: Os,LTO, project: O0:
    arm-none-eabi-size –format=berkeley “PowerSupply.elf”
    text data bss dec hex filename
    24560 2152 4240 30952 78e8 PowerSupply.elf

    library: Os,LTO, project: Os:
    arm-none-eabi-size –format=berkeley “PowerSupply.elf”
    text data bss dec hex filename
    10604 2152 4236 16992 4260 PowerSupply.elf

    library: Os,LTO; project: Os,LTO :
    arm-none-eabi-size –format=berkeley “PowerSupply.elf”
    text data bss dec hex filename
    8400 2152 4232 14784 39c0 PowerSupply.elf

    Text size gone from 25kBytes to 8.2kBytes, I think it’s a huge improvement, especially for controllers with small flash.

    • Hi Marcell, yes that is a good result. There are bugs reported with the use of LTO so be on the lookout for strange behaviour. From your results it looks like you’ve actually gone from from 11060 to 8400 if you compare like for like which is about the same ratio as I get from writing my code as “header only” as much as possible with only a single cpp file if I can.

  • Anthony Scarpa

    Hello. After the

    scons mode=debug mcu=f407 hse=8000000 -j12 install INSTALLDIR=~/install/stm32plus
    command I get a lot of errors. all of the errors are “error: expected unqualified-id before ‘using'”
    any idea what this could be?

    • Hi Anthony, I don’t have much to go on but can you verify that the version of arm-none-eabi-g++ being executed is the one that you think it is and not some other installation that happens to be on your PATH?

      • Anthony Scarpa

        I do not believe so. Do you have an example on what PATH should look like?

  • Anthony

    Hi Andy,

    I got the library to build, it was an issue with my path variable. However when I try to build a project specifically stm32plus-examples-usb_device_f0_custom_hid, I get the following errors:

    make all

    Building target: stm32plus-examples-usb_device_f0_custom_hid.elf

    Invoking: Cross ARM C++ Linker

    arm-none-eabi-g++ -mcpu=cortex-m0 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra -g3 -T “C:Usersfscarpacygwinhomefscarpasrcstm32plus-masterexamplesusb_device_f0_custom_hid/system/f042_48_8/Linker.ld” -Xlinker –gc-sections -Wl,-Map,”” -Wl,-wrap,__aeabi_unwind_cpp_pr0 -Wl,-wrap,__aeabi_unwind_cpp_pr1 -Wl,-wrap,__aeabi_unwind_cpp_pr2 -o “stm32plus-examples-usb_device_f0_custom_hid.elf” ./system/f042_48_8/Startup.o ./system/f042_48_8/System.o ./system/LibraryHacks.o ./usb_device_f0_custom_hid.o -lstm32plus

    c:/users/fscarpa/cygwin/home/fscarpa/arm-launchpad/bin/../lib/gcc/arm-none-eabi/5.2.1/../../../../arm-none-eabi/bin/ld.exe: cannot find -lstm32plus

    collect2.exe: error: ld returned 1 exit status

    make: *** [stm32plus-examples-usb_device_f0_custom_hid.elf] Error 1

    makefile:61: recipe for target ‘stm32plus-examples-usb_device_f0_custom_hid.elf’ failed
    Can you please help me determine what the problems is?

    • Hi Anthony. It appears that you are now in Eclipse. Eclipse and the ‘scons’ command line build are totally separate. You must build the library in Eclipse for the Eclipse examples to link against it.

      • Anthony Scarpa

        After I download the stm32plus library, where should I store it? Once it is downloaded I open up eclipse and import the examples and the library. Do I copy the files to the workspace or just import them? After I build the library, I should be able to build the examples without changing paths and etc..?

  • Anthony Scarpa

    Hi Andy,
    I was wondering if you can help me get the USB_DEVICE_F0_CUSTOM_HID example built. I am getting the following error: do you have any idea what can be wrong?
    1:07:31 **** Incremental Build of configuration Debug_f042_48_8 for project stm32plus-examples-usb_device_f0_custom_hid ****

    make all

    Building target: stm32plus-examples-usb_device_f0_custom_hid.elf

    Invoking: Cross ARM C++ Linker

    arm-none-eabi-g++ -mcpu=cortex-m0 -mthumb -O0 -fmessage-length=0 -ffunction-sections -fdata-sections -Werror -Wall -Wextra -g3 -T “C:Usersfscarpacygwinhomefscarpasrcstm32plus-masterexamplesusb_device_f0_custom_hid/system/f042_48_8/Linker.ld” -Xlinker –gc-sections -L”C:Usersfscarpacygwinhomefscarpasrcstm32plus-masterlib” -Wl,-Map,”” -Wl,-wrap,__aeabi_unwind_cpp_pr0 -Wl,-wrap,__aeabi_unwind_cpp_pr1 -Wl,-wrap,__aeabi_unwind_cpp_pr2 -o “stm32plus-examples-usb_device_f0_custom_hid.elf” ./system/f042_48_8/Startup.o ./system/f042_48_8/System.o ./system/LibraryHacks.o ./usb_device_f0_custom_hid.o -l”C:/Users/fscarpa/cygwin/home/fscarpa/src/stm32plus-master/lib/Debug_f051_48_8/libstm32plus.a”

    c:/users/fscarpa/cygwin/home/fscarpa/arm-launchpad/bin/../lib/gcc/arm-none-eabi/5.2.1/../../../../arm-none-eabi/bin/ld.exe: cannot find -lC:/Users/fscarpa/cygwin/home/fscarpa/src/stm32plus-master/lib/Debug_f051_48_8/libstm32plus.a

    collect2.exe: error: ld returned 1 exit status

    makefile:61: recipe for target ‘stm32plus-examples-usb_device_f0_custom_hid.elf’ failed

    make: *** [stm32plus-examples-usb_device_f0_custom_hid.elf] Error 1

    11:07:33 Build Finished (took 2s.150ms)

    • Anthony Scarpa

      Sorry for second post. I wasn’t sure it is got through.

  • Anthony Scarpa

    Hi Andy,
    I got the library and example built. I do have a question. Is your library compatible with STM32F072xx versions?

    • No direct built target for the 072 yet but if you just need a subset of its peripherals that are also present on a supported build then that should work. e.g. I’m currently writing up a project that uses an 072 and I used the 051 target without problems. Am I correct in assuming that you’re looking to use the USB peripheral?

      • Anthony Scarpa

        Hi Andy thanks for your commend. I basically need USB (HID) and SPI. I need to interface to a touch screen that has an SPI touch screen controller. Do you recommend any example that would work for my application? I am more concerned with the USB side. Thanks!

        • The 042 build will be the one that you want. It’s the only F0 build that has USB support. The usb_device_f0_custom_hid example would be a good one to try to get working. It’s not likely to work out of the box using the 042 build on the 072 because of the differences in the startup files in the ‘system’ directory. Definitely the memory declarations in Linker.ld will have to be adjusted and Startup.asm will not be correct because the interrupt vector table on the 072 will be different. System.c might work as is but it’ll really come down to some testing and debugging.

          • Anthony Scarpa

            Hey Andy,

            I played around with the 042 build and tried to come up with the required mods to get it working on the 072. Unfortunately I have not been successful yet. Do you plan on releasing a 072 build anytime soon, so I can use as a reference?

  • Mesbah Uddin

    Hello Andy,

    I have a project with STM32F411 how can i build the library for it ?

  • Govindan Nampoothiri

    Hi Andy,

    Thanks for the great write-up.
    When I run the debug in eclipse the colsole output shows
    “Exception condition detected on fd 0
    error detected on stdin”
    and the debugger terminates. Any ideas why?