image

STM32 development workflow part 1

Table of contents
  1. Introduction
  2. Basic theory
  3. Let’s make it work!
    1. 1st step - VS code
    2. 2nd step - new folders:
    3. 3rd step - Arm GNU Toolchain:
    4. 4th step - OpenOCD
    5. 5th step - CMake
    6. 6th step - Ninja or Make
    7. 7th step - Environment variables
    8. 8th step - Checking everything
    9. 9th step - Setup Visual Studio Code
    10. 10th step - Configure CMake and build your program
    11. 11th step - flashing program into your device
    12. 12th step - Debugging
  4. How to use Git(Hub) with VScode?

Introduction

When you start programming microcontrollers, usually you use some IDE (integrated development environment). That is convenient - you just select your board, plug it into your computer, and start writing your program. But maybe someday you ask yourself: how is it possible that code from your PC is toggling LEDs on your Nucleo board? Let’s summarize everything from writing code through flashing it to debugging and viewing register values. This post will discuss the integration of VScode, CMake, OpenOCD, and Cortex-Debug for STM32 development.

Basic theory

Firstly, you need to create your code. You can do it in every text editor e.g. Notepad, Word, Eclipse, or VScode.

When you have the text (code) written in C or C++ you need to compile it -> translate a source code into machine code, bytecode which will be understandable for the microcontroller. The compiler looks for errors and optimizes the final binary code (those .bin files made with zeros and ones). At this point, the compiler needs to know the target platform to compile source code into a suitable format.

Next, your understandable (for microcontroller) code has to be transferred from your desktop into a microcontroller. Here comes the programmer and flashing software:

A microcontroller’s programmer acts as an interface between the PC and the target controller. The API/software of the programmer reads data from the hex file stored on the PC and feeds it into the controller’s memory. It needs to have suitable software but you don’t have to bother with that, just use a programmer from a Nucleo (this top part of a board) or any other ST-LINK programmer (I recommend those small USB dongles). Your job (as PC) is transferring this .bin file to the programmer and now you need some kind of flashing software. There are many of them (STM32 ST-LINK Utility, OpenOCD…) but for now, we will be using openocd.

imageNucleo board has ST-Link programmer

imageST-Link dongle

And this is all you need to flash your idea into embedded systems!

But sometimes (probably even often) you need to check your program at runtime, set breakpoints, see variables, find errors, etc. That’s when you need a DEBUGGER. And yes, one debugger is on the programmer, but that’s only one part. In addition, you need a debugger on your computer and for convenience, some software to display and interact with your code (usually IDEs have such built-in, but for VScode we need an extension such as Cortex-Debug).

Let’s make it work!

Key elements:

  • Environment for code editing: Visual Studio Code
  • Building (within compiling): CMake with Make/Ninja
  • Flashing and Debugging: OpenOCD, Cortex-Debug, arm-none-eabi-gdb

1st step - VS code

Download VScode: link

In VScode add extensions: C/C++, CMake Tools, Cortex-Debug:

image

If your Windows Username contains non-ASCII letters, before installation of the extensions, check the step with the debugging explanation (end of this chapter - 12th step).

2nd step - new folders:

Create folders somewhere on your computer for the next steps:

For example:

  • C:\tools\OpenOCD
  • C:\tools\CMake
  • C:\tools\ Arm GNU Toolchain

3rd step - Arm GNU Toolchain:

Download and install Arm GNU Toolchain: link

image

imageChoose the location on your computer

imageRemember to add the path to the environment variable (checkbox)

Now you have and can use arm-none-eabi-gdb which is a GNU debugger for ARM processors.

4th step - OpenOCD

Download OpenOCD: link

image

Next, unzip and copy and paste into C:\tools\OpenOCD This software supports flashing and debugging a wide variety of platforms.

5th step - CMake

CMake download and install: link

image

Install it in your newly created folder C:\tools\CMake.

image

Remember to add the path to the environmental variables

image

What is CMake?

CMake is an extensible, open-source system that manages the build process in a platform-independent and compiler-independent manner. This is not building software – those are: Make, Ninja… But CMake is a “build generator” allowing you to use any building program you like and create in a more convenient way final main.elf or main.bin or main.hex or any other executable programs. More information here: link

6th step - Ninja or Make

Of course, you can use any other CMake-compatible building software but those 2 are popular and good enough to start.

Ninja download: link Next, unpack and save ninja.exe in one of the previous bin folders (I’ve saved it in C:\tools\CMake\bin\ninja.exe).

For “Make” you have a few options (link) but I’ve used MinGW downloaded from link:

image

MinGW is a little bit more complicated than Ninja: unpack (I’ve created a new folder C:\tools/MinGW) and install (uncheck GUI installation). Next, in the folder with “mingw-get.exe” (in my case C:\tools/MinGW/bin) open the cmd window and type: “mingw-get install mingw32-make”. After installation, you can save this (mingw32-make.exe and all other files from …\MinGW\bin directory) together with ninja.exe. The rest of the MinGW folder can be deleted:

imageUncheck "... support for the graphical user interface"

imageWait to the end of the installation

image

Copy required files (I copied them into Cmake bin directory)

Of course, you can make separate folders for these build programs or even for each individual, but remember to add their paths into environmental variables (see the next step on how to do it).

7th step - Environment variables

The next important step is to set up all environment variables and add all new tools to the PATH. In this step, we will show our system where it can find some useful tools so we can use them in many places and programs.

Firstly, open “Edit environment variables” and click “Environment variables”.

image

Now, you can see all the variables that your system recognizes in any program. On the top, you have variables assigned to the currently active user, and on the bottom variables for the whole system. If you checked in the installers to add paths to the environment variables you have to add the path to OpenOCD (C:\tools\OpenOCD\bin) and you should be ready to go. Nevertheless, you can check if everything is correct. Also, we want to make one change here.

If you’ve created similar folders, you should have similar paths (some of these paths can be saved as system variables - you can leave them there or move everything to one place):

imageClick "Edit"

imageCheck all of your paths

To simplify further usage, I will delete the path to Arm Toolchain (C:\tools\Arm GNU Toolchain\10 2021.10\bin) and create my variable (ARMGCC_DIR):

imageCreate a new variable and fill in its name and the path

This is not necessary (you can always use a full path) but can be useful.

8th step - Checking everything

Before configuration, we will check if everything is properly installed: Go into the bin folder in your OpenOCD directory (C:\tools\openOCD\bin) Next, turn on the cmd window:

imageOpen command window in specific directory

And check if everything works (write openocd.exe):

image

If everything works you can go further, if not repeat the earlier steps 4th step - OpenOCD installation](#fourth_step).

Then, go into the bin folder in your CMake directory (*C:\tools\CMake\bin), and turn on the cmd window:

image

And check if everything works (write cmake.exe):

image

Then in the bin folder in your ARM GNU Toolchain directory (C:\tools\Arm GNU Toolchain\10 2021.10\bin), turn on the cmd window:

image

And check if everything works (write arm-none-eabi-gdb.exe):

image

It can happen that you’re missing Python 2.7. If so - download and install it (link). After that, everything should be working properly.

Also, you can check if everything is in the right place where cmake where arm-none-eabi-gcc where openocd where ninja where mingw32-make:

imageIf environmental variables are set correctly you should be able to check it in any directory

or just check the versions of installed programs cmake --version ninja --version openocd -v mingw32-make -v arm-none-eabi-gcc -v:

imageResults depend on versions you have installed

If you have problems in 2 last tests and no problems in the previous ones that means your environmental variables are not set correctly. Check them for missing paths and check if they are user variables or system variables. If user ones you should pay attention to which directory you call these commands since they are not visible for all users (in my case it has to be C:\Users\symon).

9th step - Setup Visual Studio Code

When you have everything installed, we can go to the configuration in VScode. First, check if you have all the essential extensions:

image

Now, is the perfect time to open a project. You can create a new one if you can (how to do this in the next post). For now, we don’t want to configure everything from scratch, so it is better to clone my project from GitHub (if you don’t know how to do this check the git chapter).

When you’ve opened the project, you can see all folders on the left side of the screen.

If everything is installed it is time to choose the compiler. You can either click on the bottom bar or press Ctr+Shift+P (open Command Palette) and type: CMake: Scan for Kits:

If your ARM_GCC_DIR variable is in the Path it should find your compiler and set it.

image

10th step - Configure CMake and build your program

If you want to use Ninja or any other program you need to change a value in “cmake.generator” in /.vscode/settings.json (for the first time leave it as is if you’ve installed MinGW):

image

Now, open the command palette and type: CMake: Configure or CMake: Delete Cache and Reconfigure:

image

If there is no error, it is time to try building the project:

image

There should be no error and 3 files should be created in the bin directory - main.bin, main.elf, and main.hex.

11th step - flashing program into your device

After building we’re ready to flash our program into the microcontroller. But first, let’s see what is inside /.vscode/tasks.json:

Sometimes you want to have different options during building or flashing programs. Tasks are just sets of commands which you can execute at once. It allows you to declare a few different building processes and easily change between them. There are a lot of options, but in a nutshell, it makes things simpler and faster. I’ve created a few tasks for my project. Let’s try one of them:

press Ctr+Shift+B next choose clean&build:

image

Now you’ve built the project with clearing at the beginning. As you can see there is an option to “Load Firmware” and since we’ve got a built project we can do this. So, connect your board to the Nucleo programmer (or any st-link programmer) and try “Load Firmware”.

If an error occurs:

Probably, you don’t have drivers for ST-Link. You can check it - by going into the device manager and see if your computer recognizes your device:

image

If drivers are installed STM32 programmer should be recognized either as a COM port or USB device

If not, you need to download either the STM32CubeProgrammer or the ST-LINK Utility: link. Download and install one of these programs:

image

After that, your computer should recognize the STLink device. Now, you should be able to flash your program without any problem.

12th step - Debugging

After all this setup, it is time for debugging. Everything should be working, so press the green play button or press F5 and after a while, the program should stop at the beginning of the main():

image

Problem occurs when your User Name contains non-ASCII letters. No matter where have you installed VScode itself .vscode directory always will be created C:\Users\your_user_name.vscode. Inside, there is a folder for all extensions C:\Users\your_user_name.vscode\extensions. The Cortex Debug extension will crash when the path contains any non-ASCII letter. Moreover, there is no possibility to move the .vscode folder. At least the directory of extensions can be changed (see below).

Go into the environmental variables and add the new variable VSCODE_EXTENSIONS with the path to the folder where you want to save all extensions:

image

Now you can download all extensions for VScode and start debugging (If you installed them before you have to reinstall).

How to use Git(Hub) with VScode?

For big projects, it is important to take care of new versions of software. Also, all contributors must be able to work on their copy of a program that will not affect the main version. On the other hand, often you need to upload new versions of software and it would be nice for others to be able to update code on their machine without disturbing their adjustments. The answer to all of these problems is Git. And it is really simple to set it up in VScode!

First of all download and install the Git: link

I suggest creating a next folder: C:\tools\GitHub

If you use the installer as it is, Git will install on the default path C:\Program Files\Git. It is not a problem but if you want to specify a directory you need to open the cmd window in the folder where you’ve got git installer and type git_installer_name.exe /DIR=“your\path\to\GitHub” (see the screenshot below).

image

Once you’ve installed git. It’s time to add it to the Path. By default, Git is adding its path to system variables. If you want, you can delete that one and add the same path into variables for user variables to have everything in one place (but the default variable for a whole system is also perfectly fine):

image

image

Now you can open the command window anywhere and use git:

image

Now, we can use it to clone a repository into your local PC. For that, we need a link to this repository, so go to the repository of interest:

image

Next, you create a folder for your project somewhere on your computer. Go there, turn on the cmd window, and type: git clone http://github.com/your/repository/link:

image

Usually, this is enough but sometimes you need to authenticate that you have got access to the repository.

At default, you clone the whole Repo with all branches but if you want to operate only on specified you can type: git clone --branch <your-branch-name> --single-branch <your-remote-repo-url>:

image

More about cloning: link

In the next part of this post, I will explain how to create a new project for any STM32 MCU.