A Complete STM32F0 Development Environment
June 14, 2014
This post expands on (and updates) a few of my earlier posts about developing for the STM32F0 microcontroller. Some parts have become easier and I've found a few more useful ways to get things done. Some of the commands below assume a Debian-based Linux distribution, but should be reworkable for your particular setup.
Let's start by making some directories for the STM32 tools and projects:
$ mkdir ~/stm32
$ mkdir ~/stm32/projects
Installing the Toolchain
The GCC ARM Embedded package is a collection of utilities (compiler, assembler, libraries, debugger, etc.) that's maintained by ARM employees. It's available in the regular repositories, but you can use a PPA to get more up-to-date versions. OpenOCD facilitates communication between your PC and the ST-Link programmer. Install both tools:
$ sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
$ sudo apt-get update
$ sudo apt-get install gcc-arm-none-eabi libnewlib-arm-none-eabi libnewlib-doc gdb-arm-none-eabi openocd
There's currently a minor bug: those packages don't include the newlib-nano library. If you need newlib-nano you can manually install the GCC ARM Embedded package. Instead of using the above three commands, use these:
$ sudo apt-get install openocd ia32-libs
$ cd ~/stm32
$ wget https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q1-update/+download/\
gcc-arm-none-eabi-4_8-2014q1-20140314-linux.tar.bz2
$ tar -xjvf gcc-arm-none-eabi-4_8-2014q1-20140314-linux.tar.bz2
$ echo export PATH=$PATH:/home/username/stm32/gcc-arm-none-eabi-4_8-2014q1/bin >> ~/.bashrc
$ source ~/.bashrc
Regardless of how you install GCC Arm Embedded, you'll also want the CMSIS and STM StdPeriph libraries:
$ cd ~/stm32
$ git clone https://github.com/szczys/stm32f0-discovery-basic-template.git
$ cd stm32f0-discovery-basic-template/Libraries/
$ make
We're now ready to build and flash some firmware. I'll cover three ways to accomplish that: using the command line, using the Geany IDE, and using the Eclipse IDE.
Building and Flashing: From the Command Line
For a very simple workflow you can just use the command line to get everything done. Write your code in whatever editor you like, and use a Makefile to encapsulate all of the build, debugging and device programming commands.
My basic empty project is available as a zip file or through my stm32f0-empty-project repository on GitHub. Extract it to ~/stm32/projects/. It has a main() that just configures a GPIO and toggles it in an infinite loop. The f0lib/ directory contains my incomplete and unpolished collection of potentially reusable code. There's also a Makefile and configuration files for GDB and OpenOCD. Usage is trivial:
make compiles the firmware into an ELF and a BIN.
make install flashes the firmware to the STM32F0 with OpenOCD.
make clean deletes the ELF and BIN.
make debug_server, make debug_nemiver and make debug_cli are used for debugging. More on this in the debug sections below.
Building and Flashing: With the Geany IDE
Geany is a simple IDE and perhaps my favorite environment for programming in C. The IDE is essentially a text editor with a few extra features to support coding. It's minimalist and very fast. The only settings you need to change are the build commands. Go to Build > Set Build Commands. Configure them as compile = make clean, build = make, execute = make install. While this might sound weird, it makes the three build icons in the toolbar perfect for one-click actions instead of having to use the drop-down build menu.
Side note: if you're using Cinnamon or Gnome3 with a high-DPI display, the experimental GTK3 support in Geany gives you a beautiful high-DPI-friendly IDE. You'll have to build Geany from source with ./configure --enable-gtk3 && make && make install.
Building: With the Eclipse IDE
Many people prefer the Eclipse IDE. While I don't care for it's busy interface and relatively sluggish performance, there is a must-have plug-in that gives awesome annotated register views in the debugger. Start by installing the Eclipse and CDT packages, then install the GNU ARM Eclipse and EmbSysRegView plug-ins. Don't install Eclipse from the repositories -- the repo version of Eclipse is a few years old.
Download from https://www.eclipse.org/downloads/
Extract to ~/stm32
Open Eclipse
Help > Install New Software > Work with > Kepler
Programming Languages > C/C++ Development Tools
Help > Install New Software > Add
Name = GNU ARM Eclipse Plug-in
Location = http://gnuarmeclipse.sourceforge.net/updates
Select: Cross Compiler Support, Generic Project Templates, STM32Fx Project Templates, OpenOCD Debugging Support
Help > Install New Software > Add
Name = EmbSysRegView Plug-in
Location = http://embsysregview.sourceforge.net/update
Select: embsysregview (both components)
I only use Eclipse for debugging, so you might be better served by reading the GNU ARM Eclipse plug-in documentation. My way is a bit of a dirty hack to just get things working well enough to debug. Here's what I do:
File > New > C Project
Executable > Empty Project > Cross ARM GCC > Next > Next
Toolchain Path = ~/stm32/gcc-arm-none-eabi-4_8-2014q1/bin
Finish
Copy the contents of your project folder into the Eclipse project's folder. Then in Eclipse:
Right click on project > Refresh
Right click on project > Properties
C/C++ General > Paths and Symbols > GNU C > Add > File system
Navigate to: ~/stm32/stm32f0-discovery-basic-template/Libraries/CMSIS/Device/ST/STM32F0xx/Include
OK > OK > Yes
Right click on project > Properties
C/C++ Build > Build Settings tab
Uncheck “Use default build command”
Uncheck “Generate Makefile automatically”
Build command = make
Build directory = ${workspace_loc:/your_project_name_goes_here}
C/C++ Build > Behavior tab
"Build (incremental build)" = leave it empty
Again: I only use Eclipse for debugging. If you actually want to do any development in Eclipse, don't do what I do.
Debugging: With the Eclipse IDE
Having already prepared your project, now setup the debugging parts:
Right click on project > Debug as > Debug Configurations
Double-click on GDB OpenOCD Debugging
Name = STM32_Debug
Debugger tab
Uncheck “Start OpenOCD locally”
GDB Client Setup Executable = arm-none-eabi-gdb
Apply
Close
Window > Preferences
C/C++ > Debug > EmbSys Register View
Architecture = cortex=m0
Vendor = Stmicro
Chip = stm32f051x
Board = STM32F0DISCOVERY
In a terminal in the project directory: make debug_server
(Leave this running)
Click on the debug drop-down in the toolbar > STM32_Debug > Yes
Window > Show View > Other
Debug > EmbSys Registers
You can now debug using step/next/etc. Double-click on registers in the EmbSys Registers tab to view their contents. It automatically updates as you step though code.
Debugging: With Nemiver
Nemiver is a fast and no-frills debugger. Using it with this project is trivial:
$ make debug_server
$ make debug_nemiver
make debug_server will have to stay running for the duration of the debugging process, so run it in a separate terminal window. After closing Nemiver you can close the server with Ctrl-C.
Debugging: From the Command Line
Command line debugging with this project is also really easy:
$ make debug_server
$ make debug_cli
make debug_server will have to stay running for the duration of the debugging process, so run it in a separate terminal window. After closing gdb you can close the server with Ctrl-C.