Custom Board definition for STM32G031G8

Hi all,

I hope to tap the knowledge of the community, since I am hitting a brick wall. I want to set up a custom board for a generic STM32G031G8U6. So far, I setup the board file (generic_stm32g031g8u6.json) according to what I could find on the internet:

  "build": {
    "core": "stm32",
    "cpu": "cortex-m0plus",
    "extra_flags": "-DSTM32G0 -DSTM32G0xx -DSTM32G031xx",
    "f_cpu": "64000000L",
    "framework_extra_flags": {
      "arduino": "-D__CORTEX_SC=0"
    "mcu": "stm32g031g8",
    "product_line": "STM32G031xx",
    "variant": "STM32G0xx/G031K(4-6-8)(T-U)_G041K(6-8)(T-U)"
  "debug": {
    "default_tools": [
    "jlink_device": "STM32G031G8",
    "onboard_tools": [
    "openocd_target": "stm32g0x",
    "svd_path": "STM32G031.svd"
  "frameworks": [
  "name": "ST NUCLEO-G031G8",
  "upload": {
    "maximum_ram_size": 8192,
    "maximum_size": 65536,
    "protocol": "stlink",
    "protocols": [
  "url": "",
  "vendor": "FB"

This is basically a copy of the nucleo_g031k8.json.
My platformio.ini for a project with this board looks as expected:

boards_dir = ./boards

platform = ststm32
board = generic_stm32g031g8u6
; board_build.ldscript = ./boards/ldscript.ld
framework = arduino
upload_protocol = stlink
upload_port = stlink

When I try to build a blank project, it compiles all the necessary files, as far as I can see, but then the linker throws a lot of errors:

/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: warning: .pio/build/custom_stm32g031g8u6/firmware.elf has a LOAD segment with RWX permissions
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: .pio/build/custom_stm32g031g8u6/SrcWrapper/src/stm32/hw_config.c.o: in function `hw_config_init':
hw_config.c:(.text.hw_config_init+0xe): undefined reference to `SystemClock_Config'
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: .pio/build/custom_stm32g031g8u6/libFrameworkArduino.a(HardwareSerial.cpp.o): in function `HardwareSerial::setRx(unsigned long)':
HardwareSerial.cpp:(.text._ZN14HardwareSerial5setRxEm+0x4c): undefined reference to `digitalPin'
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: HardwareSerial.cpp:(.text._ZN14HardwareSerial5setRxEm+0x50): undefined reference to `analogInputPin'
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: .pio/build/custom_stm32g031g8u6/libFrameworkArduino.a(HardwareSerial.cpp.o): in function `HardwareSerial::setTx(unsigned long)':
HardwareSerial.cpp:(.text._ZN14HardwareSerial5setTxEm+0x4c): undefined reference to `digitalPin'
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: HardwareSerial.cpp:(.text._ZN14HardwareSerial5setTxEm+0x50): undefined reference to `analogInputPin'
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: .pio/build/custom_stm32g031g8u6/libFrameworkArduino.a(HardwareSerial.cpp.o): in function `HardwareSerial::HardwareSerial(void*, HalfDuplexMode_t)':
HardwareSerial.cpp:(.text._ZN14HardwareSerialC2EPv16HalfDuplexMode_t+0x90): undefined reference to `analogInputPin'
/Users/fb/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld: HardwareSerial.cpp:(.text._ZN14HardwareSerialC2EPv16HalfDuplexMode_t+0x98): undefined reference to `digitalPin'
collect2: error: ld returned 1 exit status
*** [.pio/build/custom_stm32g031g8u6/firmware.elf] Error 1

I tried adding a linker script from CubeIDE, therefore the commented boards_build.ldscript definition in the platformio.ini, but with this, the result is the same.
I think I am missing something obvious here, but I can’t see it. Any help would be greatly appreciated.

There are multiple faults at play here.

First, you say that you have a STM32G031G8U6 but then you put this as your chosen variant

This is wrong. This folder is for all STM32G031K[4/6/8] and G041K[6/8]. Your G031G8 is not at all in there. You have to look at what STM32Duino/variants/STM32G0xx is offering and chose the correct folder.

The right folder for you is STM32G0xx/G031G(4-6-8)U_G041G(6-8)U.

Second of all, the filename itself

Is problematic. There is some “magic” in the STM32Duino builder script that takes the board name and converts it to the -DARDUINO_<board name> macro. You’re not following the naming convention genericSTM32...json so it’s gonna generate a macro that the Arduino core will not recognize. Specifically, in the correct variant folder we’re looking at files like

whose implemention is guarded by requiring that one of these macros must be activated. Obviously, for your stm32g031g8 that should be ARDUINO_GENERIC_G031G8UX.

So you either

  • fixup your filename to be genericSTM32G031G8U6.json plus use a “mcu” field of stm32g031g8u6
  • or add -DARDUINO_GENERIC_G031G8UX to your "extra_flags".

Thank you for the quick replay. Works perfectly now.
How did I not see the G / K there? As I said, something obvious I was missing.