Setting up a bootloader for a custom target fails

Hi Mbed team,

We are using Mbed-OS 6.14 with Mbed-CLI2 and CMake to port a bootloader for our custom target.

In “target_overrides” we are simply using “target.restrict_size”: “0x20000” to basically use the managed bootloader. However, when we are compiling the bootloader application, it seems as though the POST_APPLICATION_ADDR macro is not being defined.

I followed this guide to port a custom target using Mbed-CLI2:
Porting custom boards - Porting | Mbed OS 6 Documentation

Could you maybe give some pointers as to why this happening?

Our custom_target.json:

{
    "TS_PHOENIX": {
        "inherits": [
            "MCU_STM32WB55xG"
        ],
        "components_add": [
            "SPIF", "FLASH", "FLASHIAP"
        ],
        "detect_code": [
            "0839"
        ],
        "device_name": "STM32WB55RGVx",
        "config": {
            "update_file_name": {
                "help": "Value: Defines the update filename which is expected by the bootloader.",
                "value": "\"ts.bin\"",
                "macro_name": "TS_UPDATE_FILE_NAME"
            }
        }
    }

}

Our mbed_app.json

{
    "target_overrides": {
        "*": {
            "target.restrict_size": "0x20000",
            "target.macros_add": ["NDEBUG=1"],
            "platform.stdio-flush-at-exit": false
        },
        "TS_PHOENIX": {
            "target.macros_add": ["TS_UPDATE_FILE_NAME=\"ts.bin\""],
            "spif-driver.SPI_CLK": "SPI_FLASH_SCK",
            "spif-driver.SPI_CS": "SPI_FLASH_CS",
            "spif-driver.SPI_MOSI": "SPI_FLASH_MOSI",
            "spif-driver.SPI_MISO": "SPI_FLASH_MISO"
        }
    }
}

The CMakeLists.txt for our target:

add_library(mbed-ts-phoenix INTERFACE)

target_sources(mbed-ts-phoenix
    INTERFACE
        PeripheralPins.c
        system_clock.c
)

target_include_directories(mbed-ts-phoenix
    INTERFACE
        .
)

target_link_libraries(mbed-ts-phoenix INTERFACE mbed-stm32wb55xg)

@ladislas I noticed that you are quite deeply involved in Mbed-CLI2, can you maybe please assist?

:slight_smile:

I’ve played with mbed-cli 2 quite a lot and (maybe) helped (a little) in the development.

We are still not using it in production for our project mainly because of: Reduce unnecessary recompilation of object files by removing mbed-os INTERFACE libraries where possible · Issue #15039 · ARMmbed/mbed-os · GitHub

That being said we hit a similar issue APP_START and APP_SIZE undefined.

We fixed the issue with the following:

# Bootloader option
option(ENABLE_BOOTLOADER "Build LekaOS with bootloader" OFF)
message(STATUS "ENABLE_BOOTLOADER (Build LekaOS with bootloader) --> ${ENABLE_BOOTLOADER}")
if (ENABLE_BOOTLOADER)
	set(MBED_APP_FLAGS
		-DMBED_APP_START=0x08040000
		-DMBED_APP_SIZE=0x180000
	)
endif(ENABLE_BOOTLOADER)

This can be added to your main CMakeLists.txt

@ladislas thanks a lot for the reply and also for additional info. I think it will then also be more prudent for us to still use mbed-cli 1 until 2 is a bit more stable.

I tried to define those additional compiler flags via our top-level CMakeLists.txt, but it did not seem to make any difference. Is the order/location of those defines important in the CMakeLists.txt?

We are not using mbed-cli1, we are using a modified version of GitHub - USCRPL/mbed-cmake: Use the power of CMake to create your MBed applications

Our project set up using that is now open source if you want to take a look: GitHub - leka/LekaOS: LekaOS is Leka's firmware based on Mbed OS

I’d say they are yes, depending on where you’re using them.

You also need to call cmake directly instead of mbed-tools, to pass the option as -DENABLE_BOOTLOADER=1

Here is how we do it:

For simplicity, I completely skipped using the ENABLE_BOOTLOADER flag mechanism (like below) to just see if I get those defines. However, if I check mbed_config.cmake in the “cmake_build” directory, I would expect the defines to be there, but they are not.

# Copyright (c) 2020 ARM Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)

set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "")
set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "")
set(APP_TARGET VOYAGER-PHOENIX-BL)

set(MBED_APP_FLAGS
        -DMBED_APP_START=0x08000000
        -DMBED_APP_SIZE=0x20000
        -DPOST_APPLICATION_ADDR=0x08020000
)

include(${MBED_PATH}/tools/cmake/app.cmake)

add_subdirectory(${MBED_PATH})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/TARGET_TS_PHOENIX)

add_executable(${APP_TARGET})

mbed_configure_app_target(${APP_TARGET})

project(${APP_TARGET})

target_sources(${APP_TARGET}
    PRIVATE
        main.cpp
)

target_include_directories(${APP_TARGET}
    PUBLIC
        .
)

target_link_libraries(${APP_TARGET}
    PRIVATE
        mbed-os
        mbed-core
        mbed-stm
        mbed-stm32wb
        mbed-ts-phoenix
        mbed-storage
)

mbed_set_post_build(${APP_TARGET})

option(VERBOSE_BUILD "Have a verbose build process")
if(VERBOSE_BUILD)
    set(CMAKE_VERBOSE_MAKEFILE ON)
endif()

Well MBED_APP_FLAGS is not available to mbed-cli2, only to mbed-cmake.

At some point you should append to CMAKE_<LANG>_FLAGS, see c++ - How do I add a linker or compile flag in a CMake file? - Stack Overflow

I have to admit, being fairly new to CMake, all of this is still rather confusing and tbh we don’t have the time to go into the belly of the beast to figure this out. We’d have to wait until mbed-cli2 is apparently more stable.

We managed to get everything compiled and running using mbed-cli 1.

Are there any major reasons not to use mbed-cli2 with mbed-os 6.14 or should we then rather use earlier versions of mbed-os 6 (below 6.5), which are still fully supported by mbed-cli 1 ?

I don’t think so, but you’ll soon fine that CMake really is an improvement and the time invested in “learning” this new tool is really worth it. CMake is used by a whole lot of different projects, so this knowledge is not “just for mbed”.

Could you try the following?

set(MBED_APP_FLAGS
  "-DMBED_APP_START=0x08000000 -DMBED_APP_SIZE=0x20000 -DPOST_APPLICATION_ADDR=0x08020000"
)

 add_definitions(${MBED_APP_FLAGS})

It should be possible with CMake too, but I currently put them into mbed_app.json:

"config": {
        "mbed_app_start": {
            "help": "Workaround as target.mbed_app_start is not supported",
            "value": "0x08000000",
            "macro_name": "MBED_APP_START"
        },
        "mbed_app_size": {
            "help": "Workaround as target.mbed_app_size is not supported",
            "value": "0x20000",
            "macro_name": "MBED_APP_SIZE"
        }
    }

They end up in MBED_CONFIG_DEFINITIONS in mbed_config.cmake, so appending to that variable in the main CMake file should also work. This definitely needs to be implemented properly.