Using STM32CubeMX and PlatformIO

Since the STM32CubeIDE uses the same CubeMX implementation this should be possible as long as the same .cproject file for eclipse is generated.

But if this is not the case, then creating the same CubeMX information with STM32CubeIDE should still be possible.

Cheers, Joachim

1 Like

A missing puzzle piece to this may also be STM HAL drivers are out of date Ā· Issue #439 Ā· platformio/platform-ststm32 Ā· GitHub. The current STM32Cube HAL is very much out of date and results in compilation error some times. I have generated a new version of framework-stm32cube with the very-latest versions (built through a script), but it needs testing, see issue. @valeros if you see this, please consider updating with the tool I posted in the issue :smiley:

Ok, I didnā€™t know that the libraries provided by Platformio are so outdated. My experiments focused on STM32F4 boards and these seem to be not as badly out of sync as the restā€¦

I now created a new script that extracts as much information from the .project and .cproject file as possible, turns off as much of the additional ā€œintelligenceā€ of platformio as manageable, and then lets it build with only the libraries provided by CubeMX.

Caveat: You must create you project with the option ā€œAdd necessary files as reference in the toolchain project configuration fileā€ because this is the only way my script can extract the needed information.

Here is the link to the script: pio_and_stm32cubeide/automatic_cubemx at main Ā· jbaumann/pio_and_stm32cubeide Ā· GitHub

Looking forward to your comments/feedback.

Cheers, Joachim

1 Like

(yeah, old thread, I know, but it highlights the issues involved to get this working ā€¦)

I canā€™t figure out how to make PIO + FreeRTOS + LwIP play nice together on STM32. Thereā€™s a makefile-based version which works out of the box on github (effortlessly!), but every attempt to bring it into PIOā€™s world has failed me so far (FWIW, Iā€™d rather not go through the STM32Cube code generator, which leads to unmaintainable code).

Iā€™ve tried using the FreeRTOS / LwIP libs inside .platformio (fails to compile) and Iā€™ve tried mincrmatt12ā€™s PIO repos (see 6696, 6751, and github, after adapting them from F2 to F7).

So far, itā€™s a bit like herding cats. If thereā€™s a working example of running PIO + FreeRTOS + LwIP on any STM32 board, Iā€™d love to hear about it ā€¦

After quite literally weeks worth of attempts trying to just manually copy paste files from cubeMX into the src and include and library folders in platformio with zero luck, this technique finally got my project to build, and bonus points because it allowed me to maintain the cubeMX structure which will allow me to regenerate the generated code if i ever want to add more peripherals.

I do have another question, Iā€™m looking to add some C++ to my project and just changing main.c to main.cpp resulted in a bunch of errors (which donā€™t come up in cubeIDE), so I was wondering if anyone knows what else is required to make the project C++ compatible after the successful import into PIO?

Actually bonus points if I can easily just convert the entire project into C++

Nice to read that the script helped you.

The script currently is simply looking for the C resources, C++ resources are currently ignored. If you look into line 161 of the script you can see that it only matches the C Compiler include paths.
Could you post the errors you get so that I could determine whether that is the only problem?
If so, I could try and add this functionality to the script (even though I cannot promise when I have the spare time for thatā€¦)

Cheers, Joachim

changing main.c to main.cpp and main.h to main.hpp yields the following result. Note that doing the same in cubeIDE works without issue.

Processing nucleo_h723zg (platform: ststm32; board: nucleo_h723zg)
--------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
SETUP_CUBEMX: Using the following source directories: 'Core, Middlewares, Drivers'
SETUP_CUBEMX: Using the following build flags: '-mthumb, -mcpu=cortex-m7, -mfpu=fpv5-d16, -mfloat-abi=hard'
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/nucleo_h723zg.html
PLATFORM: ST STM32 (16.1.0) > ST Nucleo H723ZG
HARDWARE: STM32H723ZGT6 550MHz, 320KB RAM, 1MB Flash
DEBUG: Current (stlink) On-board (stlink) External (blackmagic, cmsis-dap, jlink)
PACKAGES:
 - toolchain-gccarmnoneeabi @ 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\nucleo_h723zg\src\Core\Src\freertos.o
Core\Src\freertos.c:23:10: fatal error: main.h: No such file or directory

************************************************************** 
* Looking for main.h dependency? Check our library registry!   
*
* CLI  > platformio lib search "header:main.h"
* Web  > https://registry.platformio.org/search?q=header:main.h
*
**************************************************************

 #include "main.h"
          ^~~~~~~~
compilation terminated.
Compiling .pio\build\nucleo_h723zg\src\Core\Src\main.o
Compiling .pio\build\nucleo_h723zg\src\Core\Src\stm32h7xx_hal_msp.o
Compiling .pio\build\nucleo_h723zg\src\Core\Src\stm32h7xx_hal_timebase_tim.o
Compiling .pio\build\nucleo_h723zg\src\Core\Src\stm32h7xx_it.o
Compiling .pio\build\nucleo_h723zg\src\Core\Src\syscalls.o
Compiling .pio\build\nucleo_h723zg\src\Core\Src\sysmem.o
*** [.pio\build\nucleo_h723zg\src\Core\Src\freertos.o] Error 1
Compiling .pio\build\nucleo_h723zg\src\Core\Src\system_stm32h7xx.o
Core\Src\stm32h7xx_hal_msp.c:22:10: fatal error: main.h: No such file or directory

**************************************************************
* Looking for main.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:main.h"
* Web  > https://registry.platformio.org/search?q=header:main.h
*
**************************************************************

 #include "main.h"
          ^~~~~~~~
compilation terminated.
Core\Src\stm32h7xx_it.c:21:10: fatal error: main.h: No such file or directory

**************************************************************
* Looking for main.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:main.h"
* Web  > https://registry.platformio.org/search?q=header:main.h
*
**************************************************************

 #include "main.h"
          ^~~~~~~~
compilation terminated.
*** [.pio\build\nucleo_h723zg\src\Core\Src\stm32h7xx_hal_msp.o] Error 1
*** [.pio\build\nucleo_h723zg\src\Core\Src\stm32h7xx_it.o] Error 1
Core\Src\main.cpp:55:1: sorry, unimplemented: non-trivial designated initializers not supported
 };
 ^
Core\Src\main.cpp:55:1: sorry, unimplemented: non-trivial designated initializers not supported
In file included from Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_rcc.h:27:0,
                 from Core\Inc/stm32h7xx_hal_conf.h:247,
                 from Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal.h:29,
                 from Core\Inc/main.hpp:30,
                 from Core\Src\main.cpp:20:
Core\Src\main.cpp: In function 'void SystemClock_Config()':
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_pwr.h:295:14: warning: conversion to void will not access object of type 'volatile uint32_t {aka volatile long unsigned int}'
       UNUSED(tmpreg);                                                          \
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_def.h:69:27: note: in definition of macro 'UNUSED'
 #define UNUSED(x) ((void)(x))
                           ^
Core\Src\main.cpp:175:3: note: in expansion of macro '__HAL_PWR_VOLTAGESCALING_CONFIG'
   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Core\Src\main.cpp: In function 'void MX_GPIO_Init()':
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_rcc.h:1460:48: warning: conversion to void will not access object of type 'volatile uint32_t {aka volatile long unsigned int}'
                                         UNUSED(tmpreg); \
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_def.h:69:27: note: in definition of macro 'UNUSED'
 #define UNUSED(x) ((void)(x))
                           ^
Core\Src\main.cpp:329:3: note: in expansion of macro '__HAL_RCC_GPIOE_CLK_ENABLE'
   __HAL_RCC_GPIOE_CLK_ENABLE();
   ^~~~~~~~~~~~~~~~~~~~~~~~~~
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_rcc.h:1468:48: warning: conversion to void will not access object of type 'volatile uint32_t {aka volatile long unsigned int}'
                                         UNUSED(tmpreg); \
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_def.h:69:27: note: in definition of macro 'UNUSED'
 #define UNUSED(x) ((void)(x))
                           ^
Core\Src\main.cpp:330:3: note: in expansion of macro '__HAL_RCC_GPIOF_CLK_ENABLE'
   __HAL_RCC_GPIOF_CLK_ENABLE();
   ^~~~~~~~~~~~~~~~~~~~~~~~~~
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_rcc.h:1428:48: warning: conversion to void will not access object of type 'volatile uint32_t {aka volatile long unsigned int}'
                                         UNUSED(tmpreg); \
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_def.h:69:27: note: in definition of macro 'UNUSED'
 #define UNUSED(x) ((void)(x))
                           ^
Core\Src\main.cpp:331:3: note: in expansion of macro '__HAL_RCC_GPIOA_CLK_ENABLE'
   __HAL_RCC_GPIOA_CLK_ENABLE();
   ^~~~~~~~~~~~~~~~~~~~~~~~~~
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_rcc.h:1476:48: warning: conversion to void will not access object of type 'volatile uint32_t {aka volatile long unsigned int}'
                                         UNUSED(tmpreg); \
Drivers\STM32H7xx_HAL_Driver\Inc/stm32h7xx_hal_def.h:69:27: note: in definition of macro 'UNUSED'
 #define UNUSED(x) ((void)(x))
                           ^
Core\Src\main.cpp:332:3: note: in expansion of macro '__HAL_RCC_GPIOG_CLK_ENABLE'
   __HAL_RCC_GPIOG_CLK_ENABLE();
   ^~~~~~~~~~~~~~~~~~~~~~~~~~
*** [.pio\build\nucleo_h723zg\src\Core\Src\main.o] Error 1
================================================== [FAILED] Took 1.26 seconds ==================================================

If you look at the first error, you can see that the build misses the file main.h, that is referenced by freertos.c. I know it is a preference of many to use .hpp as the header extension (I personally still prefer .h), but try first to rename main.hpp back to main.h.

Cheers, Joachim

I had that originally, but then had other errors. I did actually figure it out after the fact. What I ended up needing to do was rename main.c to main.cpp as well as rename freertos.c to freertos.cpp. I also just had to remove a C-style struct from main which solves the sorry, unimplemented: non-trivial designated initializers not supported error and after that it did build successfully.

To be 100% honest with you Iā€™m not super sure what your script does but things seem to be working now so I wonā€™t ask too many questions :sweat_smile:. I assume that I shouldnā€™t have any problems from here adding more files and expanding now that the base project builds correctly.

Also a note for others who might be using some of the newer STM chips, I would recommend removing the framework line from your platformio.ini file, since with this import strategy you have your HAL library files bundled in already and itā€™s better to use the one packaged with cubeMX since you wonā€™t run into strange issues with mismatched versions that way.

Fantastic to hear that.

The script actually scrapes all information regarding the build, including all used files, include files and directories, build options and so on from different files in which STM32CubeIDE hides/keeps them. It then uses these informations to manipulate the build state of the PlatformIO build so that it uses the correct libraries.

As long as STM doesnā€™t change the data location and as long as PIO doesnā€™t change the build process this script will hopefully continue to work.

I already suggest to remove the framework reference in the comment directly above it. I tested both and the only difference was that the potentially older libraries got downloaded. But they are not used because my script overwrites the whole library pathā€¦

Cheers, Joachim