Incorrect linking of the firmware for Blue Pill and DFU upload protocol

Hi everyone,

Where can I open issues against build script of framework-arduinoststm32-maple? It isn’t related to the framework per se, but the build script is contained inside framework folder.

I will post the issue here for now.

Here’s my platformio.ini:

platform = ststm32
board = bluepill_f103c8
board_build.core = maple
framework = arduino
upload_protocol = dfu
upload_port = anything

As you can see, I’m using Blue Pill board.

There is an inconsistency between build process and linker when I specify upload_protocol = dfu. It resides in platformio-build-stm32f1.py.

def get_vector_tab_addr(board, upload_protocol):
    # Some special cases
    boards_8005000 = (
        "maple",
        "maple_ret6",
        "microduino32_flash",
        "maple_mini_origin"
    )

    if any(b == board for b in boards_8005000):
        return "0x8005000"

    # depending on upload method
    if upload_protocol == "dfu":
        return "0x8002000"
    elif upload_protocol == "hid":
        return "0x8001000"
    else:
        # for other upload methods (including serial)
        return "0x8000000"

This snippet sets interrupt vector table address to 0x8002000 when using DFU bootloader.

def get_linker_script(board, mcu, upload_protocol):
    if upload_protocol == "dfu":
        boards_with_boot_20 = (
            "genericSTM32F103C",
            "genericSTM32F103T",
            "maple_mini_b20",
            "hytiny_stm32f103t"
        )

        if any(b in board for b in boards_with_boot_20):
            return "bootloader_20.ld"
        elif board.startswith("genericSTM32F103R"):
            return "bootloader.ld"
        elif board.startswith("genericSTM32F103V"):
            return "stm32f103veDFU.ld"
        elif board.startswith("genericSTM32F103Z"):
            return "stm32f103z_dfu.ld"
        elif board == "maple_ret6":
            return "stm32f103re-bootloader.ld"

    elif upload_protocol == "hid":
        # a rare case only one board
        if board.startswith("genericSTM32F103C"):
            return "hid_bootloader.ld"
        else:
            sys.stderr.write(
                "%s doesn't support uploading using HID method\n" % board)
            env.Exit(1)
    else:
        # Any other upload protocol
        specific_scripts = (
            "genericSTM32F103R",
            "genericSTM32F103V",
            "genericSTM32F103Z"
        )

        flash_scripts = (
            "maple",
            "mapleMini",
            "microduino32_flash"
        )

        jtag_scripts = (
            "nucleo_f103rb",
            "genericSTM32F103CB",
            "genericSTM32F103TB",
            "disco_f100rb",
            "hytiny_stm32f103t"
        )

        if any(b in board for b in specific_scripts):
            return "%s.ld" % mcu[0:11]
        elif any(b in board for b in flash_scripts):
            return "flash.ld"
        elif any(b in board for b in jtag_scripts):
            return "jtag.ld"
        elif board == "genericSTM32F103C8":
            return "jtag_c8.ld"
        elif board == "genericSTM32F103T8":
            return "jtag_t8.ld"

    return "flash.ld"

While this one sets linker script to flash.ld which includes mem-flash.inc which sets rom origin to 0x8005000.

But I have manually flashed DFU bootloader to Blue Pill and now I want to use DFU upload protocol. As a consequence, the program does not start. If I edit mem-flash.inc manually and set rom origin to 0x8002000, the software works correctly.

1 Like

I’ve found a temporary workaround: you need to supply custom linker script. Suppose it’s placed in src folder with other source files and named flash.ld, you need to add build_flags = -Wl,-T'"$PROJECT_DIR\src\flash.ld"' to your platformio.ini build environment section. The single quotes enclosing double quotes enclosing actual path is needed to escape possible spaces in path.

More info: Allow to specify own path to linker script (ld) using "build_flags" option · Issue #233 · platformio/platformio-core · GitHub

1 Like