STM32 Arduino Framework new board error (collect2.exe: error: ld returned 1 exit status)

Hello,

I’m having a few problems creating a new board from the existing genericSTM32F103C8. I’ve read almost every post but still can’t find the solution. I get this error: collect2.exe: error: ld returned 1 exit status

I have added boards, variants folders in my project directory, that I copied from the existing genericSTM32F103C8 board and F103C8T_F103CB(T-U) variant from the .platformio.
Renamed the two folders, variants and edited the variant in the .json file.
Does anyone know about this error?
Any help would be much appreciated!

[env:CUSTOM_STM32F103C8T6]
platform = ststm32
board = CUSTOM_STM32F103C8T6
framework = arduino

board_build.variants = Custom_Pinout_STM32F103C8T6
build_flags = -I variants/Custom_Pinout_STM32F103C8T6
board_build.ldscript = variants/Custom_Pinout_STM32F103C8T6/ldscript.ld
{
  "build": {
    "core": "stm32",
    "cpu": "cortex-m3",
    "extra_flags": "-DSTM32F103xB -DSTM32F1",
    "f_cpu": "72000000L",
    "hwids": [
      [
        "0x1EAF",
        "0x0003"
      ],
      [
        "0x1EAF",
        "0x0004"
      ]
    ],
    "mcu": "stm32f103c8t6",
    "product_line": "STM32F103xB",
    "variant": "Custom_Pinout_STM32F103C8T6"
  },
  "debug": {
    "jlink_device": "STM32F103C8",
    "openocd_target": "stm32f1x",
    "svd_path": "STM32F103xx.svd"
  },
  "frameworks": [
    "arduino",
    "cmsis",
    "libopencm3",
    "stm32cube"
  ],
  "name": "Custom Controller (STM32F103C8T6 / 20k RAM. 64k Flash)",
  "upload": {
    "disable_flushing": false,
    "maximum_ram_size": 20480,
    "maximum_size": 65536,
    "protocol": "stlink",
    "protocols": [
      "jlink",
      "cmsis-dap",
      "stlink",
      "blackmagic",
      "serial",
      "dfu"
    ],
    "require_upload_port": true,
    "use_1200bps_touch": false,
    "wait_for_upload_port": false
  },
  "url": "http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f1-series/stm32f103/stm32f103c8.html",
  "vendor": "Custom"
}

You don’t need this since you’re already specifying it in your custom board definition.

The crucial point is that if you want to use your variant from the variants folder of your project, you need to set the variants_dir, since otherwise it will take the variants dir from the framework folder. See code.

So,

[env:CUSTOM_STM32F103C8T6]
platform = ststm32
board = CUSTOM_STM32F103C8T6
framework = arduino
board_build.variants_dir = variants

should work better.

Hello, Thank you for the help :slight_smile:

For the variants I’m keeping in the default location for now, just want to create a new board.

However, I still have the build error.

Linking .pio\build\CUSTOM_STM32F103C8T6\firmware.elf
c:/users/w10/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.exe: warning: .pio/build/CUSTOM_STM32F103C8T6/firmware.elf has a LOAD segment with RWX permissions
c:/users/w10/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.exe: .pio/build/CUSTOM_STM32F103C8T6/SrcWrapper/src/stm32/hw_config.c.o: in function `hw_config_init':      
hw_config.c:(.text.hw_config_init+0x12): undefined reference to `SystemClock_Config'
c:/users/w10/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../arm-none-eabi/bin/ld.exe: .pio/build/CUSTOM_STM32F103C8T6/libFrameworkArduino.a(HardwareSerial.cpp.o): in function `HardwareSerial::HardwareSerial(void*, HalfDuplexMode_t)':
HardwareSerial.cpp:(.text._ZN14HardwareSerialC2EPv16HalfDuplexMode_t+0x88): undefined reference to `digitalPin'       
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\CUSTOM_STM32F103C8T6\firmware.elf] Error 1

For the variants I copied the existing variants_PILL_F103Cx .cpp/.h files to variant_CUSTOM_STM32F103C8T6.

Do I need to edit the variant_CUSTOM_STM32F103C8T6 .cpp/.h or different files?

Thank you!

Your variant_CUSTOM_STM32F103C8T6.cpp must implement the SystemClock_Config() functions, and a PeripheralPins_<your variant>.c provide the pin tables, see the other existing files, if you defined CUSTOM_PERIPHERAL_PINS.