Leveraging PlatformIO and STM32CubeIDE for Optimized STM32 Firmware Development
Guest post
Exploring the benefits and setup of both PlatformIO and STM32CubeIDE for firmware development
My preferred environment for firmware development is VSCode with PlatformIO. However, for one of my projects, I needed to develop on an STM32, and for this MCU family, STM32CubeIDE is the manufacturer’s recommended tool.
Table of Contents
- Introduction
- Existing conversion tools
- Project setup
- Synching files
- File Locations on both environments
- Build Configurations
- Tips and Tricks
- Conclusion
Introduction
Both IDEs have their own strengths. Rather than having to choose between them, I would like to use both side by side, turning to either one whenever needed.
Strengths of PlatformIO with VSCode:
- State-of-the-art editor
- Git integration with CI/CD possibilities
- Github Copilot
- Generic and target unit testing with test coverage
- Single configuration file that provides a good balance between simplicity and flexibility
- Support for third-party debug probes other than ST-Link
Strengths of STM32CubeIDE:
- Advanced project configurator with code generation
- Extensive debugger support
- Better support for ST-Link debug probes
- Support for SWO tracing
Existing conversion tools
There are some tools that allow you to create a PlatformIO project from an STM32CubeIDE project, but it’s a one-way conversion, and you can’t go back to STM32CubeIDE:
- Python script that converts the STM32Cube project to PlatformIO
- Tutorial on how to manually convert your STM32Cube project to PlatformIO
- VSCode extension to create a project from STM32CubeMX
- ST’s own VSCode extension
In my experience, it’s often necessary to go back to STM32CubeMX, for example, to activate an extra peripheral or change existing settings. In such cases, I would like to simply re-run the MX config tool and continue with the existing project, rather than having to start from scratch.
I find it useful to be able to use both toolchains side by side, as this provides some redundancy when something breaks down. Whenever I encounter something unusual in the build process, I can always build using the other toolchain to determine if the issue lies in my code or elsewhere.
Project setup
Let’s set up a project that allows us to use both toolchains side by side. To avoid either IDE overwriting the settings of the other, I will keep two versions of the project, each in its own directory. Each IDE has a default or preferred location for its projects, so we can use those. Additionally, this approach will allow us to create separate git repositories, making it appear as a standard project for other users, whether they use PlatformIO or STM32CubeIDE.
Synching files
With two project directories, we need a way to sync our source code between them. There are various methods to do this, but I prefer using a program called FreeFileSync. It allows you to set up a sync configuration with folder pairs, filters, and sync strategies. At any time, you can compare both sides, view the differences, and sync them when you’re satisfied.
FreeFileSync also offers an ‘automatic’ mode, where it detects changes in any of the files to be synced and performs a sync operation immediately. However, I prefer to manually trigger the ‘compare’ function and only initiate the sync when everything looks good.
File Locations on both environments
Project folder structures are a bit different on both sides, so FreeFileSync will need a few folder-pairs to get everything synced. Here’s how I have set them up:
- Application source code:
- STM32Cube path:
…/STM32WorkSpaces/<someWorkspace>/<someProject>/Core/Src
- PlatformIO path:
…/PlatformIO/Projects/<someProject>/Src
- Filter:
main.cpp
stm32wlxx_hal_msp.c
stm32wlxx_it.cpp
- STM32Cube path:
- Application include files
- STM32Cube path:
…/STM32WorkSpaces/<someWorkspace>/<someProject>/Core/Inc
- PlatformIO path:
…/PlatformIO/Projects/<someProject>/Include
- Filter: none
- STM32Cube path:
- Libraries
- STM32Cube path :
…/STM32WorkSpaces/<someWorkspace>/<someProject>/lib
- PlatformIO path :
…/PlatformIO/Projects/<someProject>/lib
- Filter : none
- STM32Cube path :
- Depending on your setup (hardware platform, external libraries, etc) you may want to add additional folder-pairs
The following files and folders do not need synchronization because they are either specific to one IDE or already included in both IDEs:
Drivers
: Contains CMSIS and STM32_HAL<project>.ioc
: Specific to STM32CubeIDEplatformio.ini
: Specific to VSCode/PlatformIO
Build Configurations
STM32CubeIDE requires that all library directories be explicitly included in the build. To do this, right-click on a folder and select Add/Remove Include Paths. In contrast, VSCode/PlatformIO uses the project directory defaults, so no additional configuration is needed.
You should now be able to build the project, download the binary to the target, and start debugging on both sides. Whenever you make changes on one side, you can use FreeFileSync to sync the source code and then switch to the other side.
Tips and Tricks
File Saving
In VSCode, I have auto-save enabled, which means that changes to the source code are automatically saved to disk. In STM32CubeIDE, however, you need to click Save All to save changes. If you make changes but haven’t saved them yet, FreeFileSync will not detect or sync these unsaved changes.
Rerun the MX Project Config Tool
1) Whenever you want to change the configuration of the STM32Cube project, you can rerun the CubeMX tool. If you have placed your application code between the following markers:
/* USER CODE BEGIN */
/* USER CODE END */
CubeMX will keep that code untouched while making changes to the generated code.
2) I am a C++ user, and in order to invoke the C++ compiler, I renamed main.c
into main.cpp
. However, I noticed that when modifying the project configuration in the STM32CubeIDE, it will not modify the main.cpp
file, but rather generate a new main.c
file, even if you ask it to generate a C++ project (the same is true for stm32wlxx_it.cpp
). It’s a bit inconvenient but the only solution is to rename main.cpp
back to main.c
, then run the project config then rename back to main.cpp
.
3) Sometimes I like to know what exactly has been modified by CubeMX, and this is now easy by comparing the files on both IDEs before syncing them.
Conclusion
In summary, managing a project with both PlatformIO in VSCode and STM32CubeIDE requires careful synchronization and configuration. By maintaining separate project directories for each IDE and using FreeFileSync for synchronization, you can leverage the strengths of both tools and efficiently handle source code updates across both environments.
Stay in touch with us
Stay tuned to this blog or follow us on LinkedIn and Twitter @PlatformIO_Org to keep up to date with the latest news, articles and tips!