Using STM32CubeMX and PlatformIO

With all the wonderful hints from this discussion, I’ve come up with something that works pretty well for me until PlatformIO can natively support CubeMX Middlewares. Here are the steps I do at the moment…

PlatformIO with CubeMX middleware

  1. Start CubeMX project with required target device, adjust and add middleware, Makefile toolchain (anything else works too), Copy only the necessary library files, then Generate Code - see Images (1), (2)

  2. VSCode : Open folder, F1 > PlatformIO : New terminal

  3. platformio init --board nucleo_f103rb --project-option "framework=stm32cube"

  4. Close folder, open same folder (to get around PlatformIO not recognising project)

  5. Delete PlatformIO generated include folder, and CubeMX Drivers folder

  6. Adjust platformio.ini and add custom prebuild-include.py (only required if you are are using Middlewares)

platform.ini

[platformio]
src_dir = ./
include_dir = Inc/

[env]
src_filter = +<Src/>
extra_scripts = pre:prebuild-include.py
prebuild_include = Middlewares

[env:nucleo_f103rb]
platform = ststm32
board = nucleo_f103rb
framework = stm32cube

prebuild-include.py

from os import path, walk
import SCons.Errors

Import('env')
try:
    import configparser
except ImportError:
    import ConfigParser as configparser

config = configparser.ConfigParser()
config.read('platformio.ini')
prebuild_include = config.get('env', 'prebuild_include').split()

source_paths = set()
header_paths = set()
for included in prebuild_include:
    if not path.exists(included):
        raise SCons.Errors.UserError(
            "prebuild-include.py could not find path '%s'" % included)
    for root, dirs, files in walk(included):
        for file in files:
            if file.endswith(('.c', '.cpp', '.s')):
                source_paths.add(root.replace('\\', '/'))
            if file.endswith(('.h', '.hpp')):
                header_paths.add(root.replace('\\', '/'))

if not 'SRC_FILTER' in env:
    env['SRC_FILTER'] = ['+<Src/>']
env['SRC_FILTER'] += ['+<%s/>' % source_path for source_path in source_paths]

if not 'BUILD_FLAGS' in env:
    env['BUILD_FLAGS'] = []
env['BUILD_FLAGS'] += ['-I' + header_path for header_path in header_paths]

“It works for me”, but I hope this helps out anyone else in the same situation, or at the least provide some additional clues until the day PlatformIO automatically detects and uses CubeMX Middleware. :wink:

Aside: Out of date PlatformIO CubeMX drivers

The framework-stm32cube CubeMX LL and HAL drivers are very out of date now for a lot of the devices (last updated Nov 30, 2018). Pity this can’t be automatically generated via some PlatformIO build/release pipeline every time ST releases updates, or at least on a button click for PlatformIO project maintainers. I wish I could help here, but I couldn’t even find the source for it - and I tried very hard :frowning: .

Currently am forced to do the following (not recommended - absolutely dirty flaky hack)

  1. Find device firmware location in CubeMX (might need to generate code to trigger the download first) - see Images (3)
  2. Delete all the existing files in PlatformIO <packages_dir>\framework-stm32cube\<Fx>\* (see platformio.ini :: platformio)
  3. Copy Drivers, Utilities, package.xml, Release_Notes.html from CubeMX location to PlatformIO location - see Images (4)

Note: This might not work as I’m wilfully ignoring the existing PlatformIO <packages_dir>\framework-stm32cube\platformio\ldscripts, and have only tried it with the STM32F103 (but, will be trying STM32F401 today).

Images

Sorry about this, but had to combine into one image since I cannot post more than one for the first post!


Matthew

2 Likes