Into the quest for a CubeMX framework

Hello all,

I’ve spend some times to get accustomed to platformio and now I try to create an efficient CubeMX framework.

I tried different way to use code generated with MX but had some compilation errors due to outdated includes and I didn’t wanted to blindly replace the files in the pio cube framework. There may be other solutions that what I did.

I am using a Nucleo H743 board but transposing these infos for other STM32 boards should be easy.
First, here is what I did to create the framework:

  • Create a framework-stm32cubemx folder in .platformio/packages/
  • Copy the platformio folder and the package.json file from framework-stm32cube/ to framework-stm32cubemx/
  • Create an xx/ folder (xx being your stm32 mcu architechture. f0, f1, f7 etc…)
  • Modify package.json and change stm32cube to stm32cubemx

The latest ST files for the mcu and board are downloaded in a local repo by MX when initialising a project. I copied them into the hacked up mx framework folder:

  • Copy %User%/STM32Cube/Repository/STM32Cube_FW_H7_V1.4.0/Drivers/ and Utilities/ folder in h7/. It could be interesting to add Middleware/ also, more later. Your ST folder may be any STM32Cube_FW_XX_Vx.x.x depending on what MX have downloaded.

So now the framework_cubemx folder has the latest STM32 drivers sources and includes for the board.

I made some changes in .platformio/platform/ststm32 for pio to find this mx framework.

  • in boards/myboard.json (replace my board with your board), add stm32cubemx in the framework list
  • in builder/frameworks copy stm32cube.py and rename it stm32cubemx.py
  • in platform.json/frameworks add:
    “stm32cubemx”: {
    “package”: “framework-stm32cubemx”,
    “script”: “builder/frameworks/stm32cubemx.py”
    }

Next I modified stm32cubemx.py. It was a little bit of work but I love python when it almost reads like haikus. Nice work Pio Team. After some fiddling around I got something to work well.

  • All drivers includes and sources are taken from the project_dir where MX generates its code. This is to avoid pio compilling all the drivers if only somes are generated. More on that later.
  • All CMSIS includes and sources are taken from the framework folder because MX doesn’t copy everything needed in the project folder, so it needed to be the full CMSIS folder.
  • xx_hal_conf.h is copied in project_dir/driver/Inc at every compilation from the project_dir/Inc folder, and not copied from the template.
  • script still search for linker script in the framework/platformio folder

Here is the full stm32cubemx.py file content:

Next, to start working with this, create a new project with platformio using the stm32cube framework (not stm32cubemx yet as pio doesn’t know how to initialise this framework (yet)). Once the project is created you can change the framework to stm32cubemx in platformio.ini and add

build_flags =
    -D CORE_M7
    -I Inc

In MX, create a new project and save the project in the same folder. I like to have as few files as possible and my main clean. So:

Also, choose Other Toolchains (GPDSC) as your Toolchain/IDE option.

In my case, it compiles, runs and debugs fine with these options.

Now to go further:
The option “Copy all used library…” in MX makes compilation fails.
This is surely due to the py script adding all .c files from the drivers/src dir to the libs-to-build cue, but hal_conf.h does not include all the headers as the periph is not ENABLED.

What’s next ? Well we could add the Middleware folder in the compilation list. Should be relatively easy to do, will try this next. (EDIT: It’s not, CubeMX doesn’t remove Middleware generated files like the drivers files, it also doesn’t remove the #includes hen you disable a Middlware… it’s a mess I’m going to cry…)
The py script could exclude the .c drivers that are not enabled by MX in the conf file.
It may also be possible to directly download the repo from ST.

Please tell me what you think, I would love to see this come to life in a pio update, and if you have hints about how to modify the python script further, please tell.

Okay, after noticing that CubeMX is far from perfect, I still succeeded in compiling code with some Middleware and platformio, but the USB HID Middleware is not working correctly for a reason unknown. Also, you can’t use hardware floating point vectors (-mfloat-abi=hard), and I don’t know why. It looks like the flag is not passed to all the compilation command or to the linker. This is a huge problem, I would like to use external library that have been compiled with hard floating point enabled…

If someone with deep pio knowledge could help me getting all of this to work that would make my day.

In the meantime, i’m back to the sluggish CubeIDE. Could be worst tho.

1 Like

Dunno about deep… I’m still rummaging around on the fringes and the occasional deep dive … but you might need to so some advanced scripting… as it seems the build_flags platformio.ini parameter may not be enough

@pfeerick Thanks for the links, especially the last one !

It may be possible to actually scrap the compilation parameters directly from what MX generates for a supported IDE. Everything should already be there, include paths, flags etc… I will look further into that. when time comes.

1 Like

Is something missed in this framework-stm32cubemx package? Should we update it?

What do you mean ? ‘cubemx’ is not a package from platformio. (or I missed something)
The stm32cube framework is and seems to work fine.

@ivankravets we actively use stm32cube mx with PIO. Goal is to generate boring things with MX, but avoid any manual edit of autogenerated files.

Here is sample of sources & config: GitHub - puzrin/dispenser: SMT solder paste and flux dispenser

I’d like to say, it works in general. MX creates only minimal possible set of files, and everything else used from PIO packages. But i have some notes:

  1. Middlewares are missed almost everywhere. For example, USB CDC exists only in in F4 folder. All USB-capable chips need this option (F0 and others).
  2. Middleware version for F4 seems outdated. This requires use Cube 5.0.1, because build fails with later versions. New CubeMX 5.4 also have more fresh middlewares for F0.
  3. It would be nice to optionally exclude all embedded PIO .c/.h cube files (but keep build features), if i prefer to use all files for Cube MX. That will guarantee versions consistency for cube-generated sources.
  4. Probably i missed something… PIO does not allow add recursive search path for headers (via -I build flag we need to add too much).
  5. F0 configs miss usb dfu upload option (it works and we have to create custom config to enable)
1 Like

Hi @vit! Thanks for keeping us updated, this year we’re planning to greatly extend support of native frameworks for each platform, so some of the issues you described will be implemented.

Middlewares are missed almost everywhere. For example, USB CDC exists only in in F4 folder. All USB-capable chips need this option (F0 and others).

Middleware version for F4 seems outdated. This requires use Cube 5.0.1, because build fails with later versions. New CubeMX 5.4 also have more fresh middlewares for F0.

At the moment we use somewhat stripped CubeMX packages (due to package size optimizations), but the next version of the CubeMX packages will have the same structure as the original ones from ST.

It would be nice to optionally exclude all embedded PIO .c/.h cube files (but keep build features), if i prefer to use all files for Cube MX. That will guarantee versions consistency for cube-generated sources.

I’m not sure I understand what build features do you want to keep. Do you want to exclude some files from the framework package, but use the same build flags for the files generated by Cube MX?

Probably i missed something… PIO does not allow add recursive search path for headers (via -I build flag we need to add too much).

You can avoid manually adding search paths by using extra_script, feature. For example, in this script you can use os.walk function to recursively add new paths to CPPPATH

F0 configs miss usb dfu upload option (it works and we have to create custom config to enable)

Not all boards support this upload method. What board do you use?

Yes. Cube has option to generate configs only, or include drivers too. I’d like to build from cube source completely and exclude “outdated” version from pio.

Thanks, i already use exctra_script, but it would be nice to simplify.

I do not use boards at all. Custom PCB with STM32F072CBT6. Initially used some nucleo config with the same chip. Then had to switch to custom config to enable dfu for users GitHub - puzrin/dispenser: SMT solder paste and flux dispenser

1 Like

When user wish to use cubemx for configure, and reuse driver sources from pio, it’s important to have the same hal firmware version. If you wish to make such approach usable, it’s important:

  • allow user select hal version number (now impossible)
  • keep firmware packages up to date (now seriously outdated)
  • additional middlewares, at least most popular (example: usb cdc missed in F0)

Just for the record, current string in build flags to add recursive dir tree for headers search is:

build_flags=
  ...
  !python -c 'import os; print(" ".join(["-I " + i[0] for i in os.walk("hal/stm32f072cb")]))'
  ...

Worth add to docs. Looks a bit ugly, but useabale. I could not invent more comprehensive solution. But i don’t know python at all.

1 Like

Hello guys, nice to see some activity here.
I didn’t touched my STM32 board since ages, switched to linux because the project I’m working on outgrew the MCU world. Will get back to it sometimes. Linux is another kind of manageable mess.

@vit, thanks for having had a peek, clarifying what was the problems and continuing. I took a look at your paste dispenser. That’s the kind of dodgy I like :stuck_out_tongue:

Cube has option to generate configs only, or include drivers too. I’d like to build from cube source completely and exclude “outdated” version from pio.

Exactly !

@valeros, a demonstration is worth more than thousands of words… You guys need to try CubeMx with PIO, you will really quickly see how MX is helping for developers, and what are the pitfalls of using it with PIO. Try on an H7 board. That thing is the ST top of the line in term of intricacies. If it works, the smaller series will also.

Hello everyone,

Really interesting topic,
I do really enjoy using platformio with CubeMx but I ran into some minor problems when I create a new project:
-I have to copy the sources of the generated code of cubemx into the folder generated by platform.
-It seems there are differences between the HAL library from cube, and HAL library from pio, sometimes I get some compilation errors and I have to edit some files manually:

For instance (with the STM32F446RE) I just created a simple CubeMx project, a pio project, copied the generated sources into the pio folder, tried to compile and get the following error:
"src/tim.c: In function ‘MX_TIM2_Init’:
src/tim.c:42:13: error: ‘TIM_Base_InitTypeDef {aka struct }’ has no member named ‘AutoReloadPreload’

This parameter exist in cube and hopefully I don’t need it,
so I can simply comment the corresponding line in the tim.c file.
Therefore, concerning this :

Yes. Cube has option to generate configs only, or include drivers too. I’d like to build from cube source completely and exclude “outdated” version from pio.

Is it possible to learn this power ?
Otherwise I will try this small script

https://github.com/ussserrr/stm32pio

2 Likes

I’ve just opened a feature request for this

2 Likes