Creating custom board for STM32F429ZGT6

It seems object files are compiled with -mfloat-abi=hard but this build flag isn’t used in the final ELF linking stage.

Try adding a small extra script to append to the linker flags.

extra_scripts =

with in the project’s root directory


This seems to solve the issue. Thanks!

Now I could get hello world to run in debug mode! great!

Next questions I have are more regarding libraries and includes setup:

  • If adding #include <stm32l4xx_hal.h> to main.cpp to VScode it does not see the framework file, what is correct way to set include path for such?

  • Usually in STM32 HAL projects I would have config file provided by STM32 HAL library template
    included with defines to set up library includes. Is this file defined somewhere in project settings or I have to add it to project /src dir ?

  • I have my own library, which is located in parent directory of platformio project. Tree looks like this:

└─ .
   ├─ app2
   │  ├─ app.cpp
   │  ├─ app.h
   │  └─ targets
   │     ├─ desktop_target_dir
   │     └─ platrofmio_dir
   ├─ app1
   │  ├─ app.cpp
   │  ├─ app.h
   │  └─ targets
   │     ├─ desktop_target_dir
   │     └─ platrofmio_dir
   └─ custom_library
      ├─ blocks
      │  └─ some_block.h
      ├─ dsp
      │  └─ some_dsp.h
      └─ utils
         └─ some_util.h

How should I include my custom library correctly to the project, considering that I might need to debug and make library code changes while working in the environment?

I don’t understand the question. It does not “see” the framework file? There is a compile error when writing that include?

PlatformIO by default automatically uses a config file that enables all submodules. If you don’t want that, you can tell the builder script to not use that default file by adding

board_build.stm32cube.custom_config_header = yes

and additionally adding a e.g. -Iinclude flag so that if your HAL config file is in include/ it will be found by the framework during the build process. An example is in e.g. GitHub - maxgerhardt/pio-stm32h7-stm32cube-freertos.

Adding libraries is per LDF doc and library options.

Your libraries should be organized in a PlatformIO compatible folder structure for this to work.

Since I don’t see where in the directory tree structure above the project root with the platformio.ini is, I can’t say specifically what path you need. One option is to use lib_extra_dirs with with a relative path, e.g. lib_extra_dirs = ../custom_library, then all folders within custom_library/ are seen as potentially includable libraries (blocks, dsp, utils modelled as separate libraries).

If you have more complex libraries and need to add include files, give a library a library.json file.

Lint gives this error:

#include errors detected. Please update your includePath. Squiggles are disabled for this translation unit() .C/C++(1696)

cannot open source file "stm32l4xx_hal.h"C/C++(1696)

I had wrong include file name copied from example files,

#include “stm32f4xx_hal.h”

works like charm!

Regarding rest:

Will read carefully library include docs and get back here with my progress!

@maxgerhardt before I jump in lib stuff deep in:

Program with simple hello world runs, but it does not print in to VScode terminal. Could you suggest how I can redirect stdout there. In original eclipse project I was debugging trough SWO.

Is it really via SWO or SWD semihosting? What’s a minimal piece of code to use SWO?

Out-of-the-box, PlatformIO doesn’t have the capability to read the SWO stream (or tell OpenOCD to read it), per Viewing SWO output within PIO?. But the linked topic also contains workarounds. The “Monitior” task starts, which can connect to serial ports (UART) and network sockets.

Seeing semihosting output is possible by expanding the GDB initialization commands and running the application in debug mode (gd32-pio-projects/gd32-spl-semihosting-printf at main · CommunityGD32Cores/gd32-pio-projects · GitHub).

Actually per Viewing SWO output within PIO? - #13 by maxgerhardt I was able to get a SWO demo running within PlatformIO. This is now also tracked in Support viewing SWO data · Issue #4069 · platformio/platformio-core · GitHub.

I think debugging via semihosting is OK for now, later on I might want to get SWO running and its good to know that there is work towards this direction.

I tried to add .ini lines

board_debug.semihosting = yes
debug_extra_cmds =
    monitor arm semihosting enable
    monitor arm semihosting_fileio enable

However linker fails to find initialise_monitor_handles()
What I am missing?

This doesn’t work outside the GigaDevice project I mentioned – it triggers something specific in platform-gd32. You need to remove that line and append your existing extra script with the lines

so that initialise_monitor_handles() becomes available.

; board_debug.semihosting = yes

removed ^^^ line and updated




Still have same link error

changed that py code to



now error changed to

arm-none-eabi-g++: fatal error: /Users/t/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/nano.specs: attempt to rename spec 'link' to already defined spec 'nano_link'
compilation terminated.
*** [.pio/build/erica_black_dsp/firmware.elf] Error 1



env.Append(LINKFLAGS=["-mthumb", "-mfloat-abi=hard", "-mfpu=fpv4-sp-d16"])

env.Append(LINKFLAGS=["--specs=rdimon.specs"], LIBS=["rdimon"])

also link error undefined reference to `initialise_monitor_handles()’

Try adding those too

or try SWO with the referenced demo.

SWD semihosting is extremely slow – you will see for yourself.

Did not help, still linkage error…

Taking a look in SWO demo

So I’m trying to use SWO.

I’ve modified to platformio.ini:

build_flags =
    -D VERSION=1.2.3
    -D DEBUG=1
    ; --specs=nosys.specs
    -fstack-usage -MMD -MP
    -D DEBUG
    -D STM32F429xx

platform = ststm32
board = erica_black_dsp
framework = stm32cube

lib_extra_dirs = ../../../zenlib

; Build options
build_flags =

extra_scripts =

swo_trace_clkin_freq = 180000000

debug_server = $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd
  -f $PLATFORMIO_CORE_DIR/packages/tool-openocd/scripts/interface/stlink.cfg
  -f $PLATFORMIO_CORE_DIR/packages/tool-openocd/scripts/target/stm32f4x.cfg
  -c "tpiu config internal - uart off 180000000"
  -c "itm ports on"
  -c "tcl_port 6666"

Copied from demo repo

On build time I’m getting warning:

Warning! Ignore unknown configuration option swo_trace_clkin_freq in section [env:erica_black_dsp]

Then when I try to connect after main() breakpoint with

python3 --dont-run

I’m getting no output.

I tried to do General → Upload and then Custom-> SWO viewer:

*** [swo_viewer] NameError : name 'link' is not defined
Traceback (most recent call last):
  File "/Users/t/.platformio/packages/tool-scons/scons-local-4.2.0/SCons/", line 1279, in execute
    result = self.execfunction(target=target, source=rsources, env=env)
  File "/Users/t/GitHub/synths/zendelay/targets/BDSP/", line 28, in swo_viewer_task
    "-f", "interface/%s.cfg" % link,
NameError: name 'link' is not defined

Can be ignored, the value is custom-used in the script.

Funny that the code worked for me, but there’s definitely an error there. Copy the latest version again from pio-swo-demo/ at main · maxgerhardt/pio-swo-demo · GitHub.

I’d also suggest opening a CLI and doing a pio upgrade --dev so that you’re on the very latest core version.

I upgraded pio, copied that file

Monitor error dissapeared, but Im still not getting printf in to console.

If I try to set a breakpoint on _write overriding method it never gets to that point.

Do you get SWO output through the ST-Link utility as shown in Support viewing SWO data · Issue #4069 · platformio/platformio-core · GitHub? With what system frequency?

To blame my hands or ST Semi but I can’t make ST-Link Util tool to run on Mac, even not in VM.

Using instead

st-util --clock=180

It does not print anything.

I tried to launch stm32IDE project with print loop with SWV as per following manual:

And it did work out. Running same

st-util --clock=180
prints out to terminal

I have strong feeling that ITM port is not enabled or some thing similar

Besides that I noticed that

board_build.stm32cube.custom_config_header = yes

did not work, it still compiles whole HAL library and seems to bypass my config file.

Could these issues be related?

Update to previous ^^^

This code:

while (1)

Prints in to terminal output:

st-trace --clock=180

A letter once a second on a new line

Running script or upload & monitor from platformio still silent

Upload & Monitor will not display SWO data, Upload + Custom → SWO Viewer should.

If not, can you change this line


    swo_trace_freq = str(env.GetProjectOption("swo_trace_freq", ""))

and retry?