PlatformIO Community

How to import/use custom arduino board for STM32L4

I am relatively new to PlatformIO (have successfully flashed some STM32s with mbed and arduino through the IDE) and some of the internal workings are a bit nebulous to me despite reading a bunch of documentation and searching through github.

I would like to use the excellent Arduino boards defined at https://github.com/GrumpyOldPizza/arduino-STM32L4 from within PlatformIO (my goal is to create a PR for those boards for the community). The boards are:

  • Dragonfly-STM32L476RE
  • Butterfly-STM32L433CC
  • Ladybug-STM32L432KC

When using the boards with the arduino IDE, I only have to add a the url https://grumpyoldpizza.github.io/arduino-STM32L4/package_STM32L4_boards_index.json to the board manager to then install support for the boards. Given that the arduino board definition already exists, how do I import it and use it from within PlatformIO?

As far as I understand, I want something like:

[env]
platform = ststm32
framework = arduino
board = Dragonfly-STM32L476RE

but how do I tell PlatformIO to use the board definitions from the specific github project?

It’s a little more complicated than that in PlatformIO. The basis is documented at https://docs.platformio.org/en/latest/platforms/custom_platform_and_board.html but then there’s also more platform-specific (here: platform-ststm32) involved in what boards are available, what Arduino core(s) is/are available and how it is built with SCons as the underlying build system.

So, it needs JSON board definitions, package files for the new Arduino core and Python code for building in order to pull in a new Arduino core which may have its very own special settings.

I’ll have a look at integration since it’s a long outsanding issue in that core.

1 Like

Actually there was a discussion at https://github.com/platformio/platform-ststm32/issues/28 and https://github.com/platformio/platform-ststm32/issues/270 about it and a move to unify everything to https://github.com/stm32duino/Arduino_Core_STM32, but still think it’s good to have that core as new option.

thanks for the pointers. It sounds like you are suggesting to add a new arduino core as well as board definitions for the 4 boards?

If I start modifying those github repos you linked to how do I test my local branches? Check it all out locally and compile myself? Just modify my local install in ~/.platformio and then submit the changes as a diff? How do you work on this?

Well it’s hard to convey multiple years of development experience in a single post; there’s a lot of background knowledge in play here, but let me try anyways by showing how I developed it…

I’m assuming you have completely read the linked documentation and know what a platform, framework, package, board definition etc. is and how e.g. a platform and package is described and configured by its JSON files.

The entities involved here are:

  • PlatformIO core logic (pio tool etc) https://github.com/platformio/platformio-core
    • doesn’t need to be modified here since this doesn’t touch on the base code
  • the new Arduino core must come as a package
  • the platform, here ststm32
    • holds all board definitions ( *.json), the platform.json definition (used packages, …) and builders
    • for now knows two Arduino cores: stm32 (STM32Duino) and maple
      • which core is built is either set in the "core": "<core>" section of the board JSON or in the platformio.ini with board_build.core = ..
    • see
  • _
    • needs modification, since this code must call the correct underlying build script for the new STM32L4 core
    • fork repo -> add new code path for core == stm32l4 (as I did here)
    • redirects execution for build into the platformio-build.py of the newly created Arduino core package
  • Understand build logic
    • first understand how the Arduino IDE uses the platform.txt and boards.txt to built the firmware. (https://arduino.github.io/arduino-cli/platform-specification/ and more).
      • these two criticial files dictate what flags ( -D .. -m .. -f ..) the compiler gets, how all available boards / variants are defined (with their name, configuration options which feed into compiler options, variant-specific source code folder, …) and how the code is uploaded (here: either openocd or dfu)
    • can also run Arduino IDE in verbose mode to see all compiler invocations if unsure
  • Replicate board JSON definitions (mostly templated from existing board definition, plus boards.txt, plus what options you need in there accessible from the build script, here e.g. I put hwids, usb_product etc)
  • and build logic in PlatformIO / SCons build script
  • Setup example project that uses all this
    • Redirect platform to the forked version of ststm32 by pointing it to the new git as shown per docs
    • Add new Arduino core package. I chose the simpler platform_packages way here to make PIO download and “know” the package. The proper way would be to modify the platform.json. Since PIO 5.0.0 has introduced a new package repository system, and I don’t yet know how to reference my own published packages in there…
    • my work at https://github.com/maxgerhardt/pio-stm32l4core-example

As you can see one needs a quite good understanding of PlatformIO internals, terminology and python scripting to integrate it here. Usually the core team adds integration for new cores, platforms etc.

The way I develop is to clone all my forked repos but modify my local files in e.g. C:\Users\.platformio\packages and C:\Users\.platformio\platforms, then copy them back and commit. Only at the last stage I redirect the packages / platforms of the project to the forked sources, remove my previous packages and platforms and see if it correctly uses the redirected packages.

On another note, I would be happy for feedback on https://github.com/maxgerhardt/pio-stm32l4core-example. You should be able to download this project, set default_envs = .. for your board (follow documentation links for supported boards and configs) and see if compilation, uploading and e.g. a basic blinky or serial output works.

I can succesfully compile for all environments; however I don’t have a board for testing.

Environment                   Status    Duration
----------------------------  --------  ------------
dragonfly_l496rg              SUCCESS   00:00:03.727
dragonfly_l476re              SUCCESS   00:00:02.967
butterfly_l433cc              SUCCESS   00:00:02.945
ladybug_l432kc                SUCCESS   00:00:02.897
grumpyoldpizza_nucleo_l432kc  SUCCESS   00:00:02.872
grumpyoldpizza_nucleo_l476rg  SUCCESS   00:00:02.906
========================== 6 succeeded in 00:00:18.312 ==========================