Using VS Code for STM32 development (related to MTE 241 @ UW)
At the University of Waterloo, we have an interesting course, MTE 241, where students are expected to develop their real-time-ish embedded operating system on a NUCLEO-F401RE board.
The only problem is that this course used to require students to use an IDE bloated from Eclipse, which feels anything but natural for a modern developer. ST now provides a VS Code extension for STM32 development, but for this course, we still need to “hack” it a little. The drivers and HAL setup needed for the course are not directly provided by the extension.
This note records the setup that worked for me.
Note: scroll to the bottom for update regarding the starter project for the 2026 offerings
Basic setup
Install the extension STM32CubeIDE for Visual Studio Code in VS Code.
Unfortunately, it does not appear to be available in Code OSS, so you may need the official Microsoft build of VS Code.
After installing the extension:
- Create a project.
- Select the correct board,
NUCLEO-F401RE. - Create a launch option in the debug menu.
- Select the ST-LINK server option.
On Linux, you also need to make the ST-LINK device accessible to the user. Create the following udev rule:
1 | # /etc/udev/rules.d/80-stm32.rules |
You may need to unplug and reconnect the board.
The debugger works relatively well — if you have a huge screen.
The default project is not enough
The default CMake project provided by the extension is not sufficient for our purpose. Specifically, it does not provide the already set-up HAL expected by the course. You still need STM32CubeMX / STM32CubeF4 files.
First, get the template from ST’s STM32CubeF4 repository:
https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32F401RE-Nucleo/Templates
The easiest way is to clone the whole repository:
1 | git clone --recurse-submodules https://github.com/STMicroelectronics/STM32CubeF4.git |
Then open the template project in VS Code.
When opening the project, there should be a small pop-up asking whether you want to regard this CMake project as an STM32 project. You must select Yes. Otherwise, the tool will not be able to find the required files.
Bringing in the generated board files
Next, use the board selector to download or generate the correct starter project for your board.
Then copy the source and header files from the generated code and replace the ones in the template project.
This part is not exactly elegant, but it gets the project into a shape that matches what the course needs while still letting VS Code understand it as an STM32 project.
If you get an error saying the compiler cannot be found, create a plain project for your board first, then copy everything under its .vscode directory into the template project.
Serial output
To check the board’s output to the serial port, use:
1 | minicom -D /dev/ttyACM0 |
If /dev/ttyACM0 is not the right device, check with:
1 | ls /dev/ttyACM* |
Always compile in Debug mode
Always compile in Debug mode.
The reason is that compiler optimization will be on in Release mode. The first thing we do in this project is to get MSP_INIT_VAL by dereferencing:
1 | *(uint32_t **) 0x0 |
This is a null pointer according to the C language standard. After optimization, the compiler is free to assume this does not happen, and the generated code may simply break the program.
So unless you have checked the generated assembly and know exactly what is happening, use Debug mode.
Flash without debugging
Sometimes you may want to run the code without starting the debugger.
In .vscode/tasks.json, add:
1 | { |
Then run the Build + Flash task.
Using Mike’s starter code
Just use STM32cube’s “convert Eclipse project” function. You will still need the setting file and tasks file for easier provessing.
Final note
The setup is a bit awkward because the extension-generated project, the STM32CubeF4 template, and the course’s expected HAL setup do not line up perfectly.
But after the pieces are copied into the right places, VS Code can be used for MTE 241 development without relying on the Eclipse-based IDE.