Custom NRF52840 target problem with Mbed OS 6/cmake

Hi,
I noticed that the support for targets was significantly reduced with the introduction of mbed-os 6.x and cmake support.
I’m using a NRF52840 Laird module and was able to create a custom target in custom_targets.json with the old mbed-os 5.15 and mbed-cli 1 using the following json declaration:

"MTB_LAIRD_BL654_CUSTOM": {
    "inherits": ["MCU_NRF52840"],
    "release_versions": ["5"],
    "device_name": "nRF52840_xxAA",
    "detect_code": ["0465"],
    "features_remove": ["CRYPTOCELL310"],
    "macros_remove": ["MBEDTLS_CONFIG_HW_SUPPORT"],
    "macros_add": ["NRFX_RNG_ENABLED=1", "RNG_ENABLED=1", "NRF_QUEUE_ENABLED=1", "CONFIG_GPIO_AS_PINRESET"],
    "overrides": {
        "lf_clock_src": "NRF_LF_SRC_RC",
        "console-uart-flow-control": null
    }
},

However, this seems to be broken using mbed-cli 2 and cmake. I can build a simple “hello world” main.cpp and latest mbed-os 6.9 with the NRF52840_DK without any problem:

mbed-tools compile -m NRF52840_DK -t GCC_ARM
→ works fine

I have seen that the NRF52840_DK is also simply derived from MCU_NRF52840 like my custom target is.
But if configure/build with my custom target, the compiler is not able to find the NRF52 specific headers:

stefan@phidias:~/projects/mbed6test2$ mbed-tools compile -m MTB_LAIRD_BL654_CUSTOM -t GCC_ARM
Configuring project and generating build system…
– Configuring done
– Generating done
– Build files have been written to: /home/stefan/projects/mbed6test2/cmake_build/MTB_LAIRD_BL654_CUSTOM/develop/GCC_ARM
Building Mbed project…
[1/121] Building C object CMakeFiles/mbed6test2.dir/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c.obj
FAILED: CMakeFiles/mbed6test2.dir/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c.obj
/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gcc @CMakeFiles/mbed6test2.dir/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c.obj.rsp -MD -MT CMakeFiles/mbed6test2.dir/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c.obj -MF CMakeFiles/mbed6test2.dir/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c.obj.d -o CMakeFiles/mbed6test2.dir/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c.obj -c …/…/…/…/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c
In file included from …/…/…/…/mbed-os/cmsis/device/RTE/include/RTE_Components.h:23,
from …/…/…/…/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_core_c.h:30,
from …/…/…/…/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_lib.h:30,
from …/…/…/…/mbed-os/cmsis/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_delay.c:26:
…/…/…/…/mbed-os/cmsis/device/rtos/include/mbed_rtx_conf.h:26:10: fatal error: mbed_rtx.h: No such file or directory
26 | #include “mbed_rtx.h”
| ^~~~~~~~~~~~
compilation terminated.

Even creating a custom target which only inherits from the working NRF52840_DK causes the same issue.

I have expected that the usage of custom_targets.json and mbed-cli 2/cmake is still possible. Is this correct? Has anybody an idea on what’s wrong with my approach?

Best Regards,

Stefan

Hi Mbed-OS,

I am experiencing exactly the same issue as Stefan above with our customer target.

Is there already a way to address the above issue?

can you share a github repository with a simple project to reproduce the issue?

hi ladislas,

After having digged a bit deeper, it seems like my issue is related to how I setup CMake for my project (I am quite new to CMake).

I discovered this guide here: Porting custom boards - Porting | Mbed OS 6 Documentation, which I followed closely but I still get the same issues, i.e. mbed_rtx.h and cmsis_compiler.h are not found during compilation.

My structure look like this:

├── bootloader.cpp
├── cmake_build
├── CMakeLists.txt
├── custom_targets.json
├── mbed_app.json
├── mbed-os
├── mbed-os.lib
└── TARGET_PHOENIX
    ├── CMakeLists.txt
    ├── PeripheralPins.c
    ├── PinNames.h
    └── system_clock.c

My custom target is derived / inherits from MCU_STM32WB55xG and actual device name is STM32WB55RGVx

This is the top-level CMakeLists.txt:

cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)

set(MBED_PATH mbed-os CACHE INTERNAL "")

set(APP_TARGET bootloader)

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

project(${APP_TARGET})

add_subdirectory(TARGET_PHOENIX)
add_subdirectory(${MBED_PATH})

add_executable(${APP_TARGET})

target_include_directories(${APP_TARGET}
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}
)

target_sources(${APP_TARGET}
    PRIVATE
        bootloader.cpp
)

target_link_libraries(${APP_TARGET}
    PRIVATE
        mbed-os
)

mbed_set_post_build(${APP_TARGET})

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

And this is the CMakeLists.txt in the PHOENIX directory:

add_library(mbed-phoenix-wb55xg INTERFACE)

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

target_include_directories(mbed-phoenix-wb55xg
    INTERFACE
        .
)

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

Some paths here are setup wrongly, but I am not exactly sure how to fix it.

@Reinier_Coetzer please share your custom board in GitHub - ARMmbed/stm32customtargets: Enable the support of your custom boards in mbed-os 6
Regards

I am lacking some basic understanding of how adding custom targets in mbed-os 6 with CMake works. The above guide is useful, but a bit cryptic on how to properly inherit from existing targets, in my case STM32WB55xx.

If somebody could just briefly explain this to me or at least point me to more resources and/or concrete examples, it would really be helpful.

Hi,

You can check my custom board repo here.

Just for your quick check, import the repo and compile one of custom target. I dont’ see compile errors for my custom board build.

$ mbed-tools import https://github.com/toyowata/nxp-legacy-lpc-mbed6
$ cd nxp-legacy-lpc-mbed6
$ mbed-tools compile -m LPC11U68 -t gcc_arm

In your problem:

…/…/…/…/mbed-os/cmsis/device/rtos/include/mbed_rtx_conf.h:26:10: fatal error: mbed_rtx.h: No such file or directory
26 | #include “mbed_rtx.h”
| ^~~~~~~~~~~~
compilation terminated.

I saw this error message before, but I cannot remember how to fix. This was probably an issue in Mbed-CLI2, so you can check the version of tools.

$ mbed-tools --version
7.3.3

$ cmake --version
cmake version 3.20.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).

You are missing a line in your root level CMakeLists.txt file.

It’s mentioned in the MBED guide, but unfortunately the MBED guide is misleading there.

Under heading “Customizing”, section “3 (Optional)”, it says:
Hint: It’s not Optional :slight_smile:

“Edit your application’s CMakeLists.txt file to let CMake know about the directory where your new board is described.”.

add_subdirectory(TARGET_IMAGINARYBOARD) # This is the new line to add
add_subdirectory(${MBED_PATH})          # This line already exists

Also check that the board you MCU you are referencing in target_link_libraries actually exists as a directory somewhere under TARGET_STM. (For example, as of today support for stm32g031x6 is not there).

2 Likes

I don’t know if @Reinier_Coetzer solved his problem, but I had the same issue here, so I’ll leave my solution here for those who have the same problem. I solved this problem by simply adding this piece of code to my custom_targets.json

"macros_add": [
  "STM32F407xx"
]

In my case, my custom board was based on the DISCO_F407 dev board.

Another thing to pay attention to is the name of folders and the custom board target. Take a look at this note

I’ve also been stuck on this issue for longer than I’d care to admit, but have finally solved it (with help from this issue from @ladislas). I’ll post the details here for other fellow adventurers:

Solution
The name of the custom target in CMakeLists.txt must be in the exact format mbed-x-y-z, and the custom target folder must be in the exact format TARGET_X_Y_Z.

Detail
The CMake target must start with mbed-, followed by the target name, in lower-case, separated by hyphens. The name of the custom target folder must start with TARGET_, followed by the target name, in upper-case, separated by underscores.

The link from Mateus’s post was broken, but should actually link to this issue: [Mbed CLI 2] mbed_rtx.h , device.h , cmsis.h No such file or directory · Issue #278 · ARMmbed/mbed-tools · GitHub

I haven’t been able to find any solid documentation on this, but adhering to the target name/directory formatting rules has worked for me.

Example
In this example, I want to create a custom target called ‘Lemon Tart’ that inherits from the Nordic nRF52832 target.

The project directory structure is:

Workspace
   main.cpp
   CMakeLists.txt
   custom_targets.json
   TARGET_LEMON_TART/
        CMakeLists.txt
        device.h
        PeripheralPins.c
        PeripheralNames.h
        PinNames.h
    mbed-os/

The file TARGET_LEMON_TART/CMakeLists.txt contains:

add_library(mbed-lemon-tart INTERFACE)

target_sources(mbed-lemon-tart
    INTERFACE
        PeripheralPins.c
)

target_include_directories(mbed-lemon-tart
    INTERFACE
        .
)

target_link_libraries(mbed-lemon-tart INTERFACE mbed-mcu-nrf52832)

Note, I had to navigate to mbed-os/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/CMakeLists.txt in order to find the correct library name for the target I am inheriting from (mbed-mcu-nrf52832).

We also need to add an extra line to the CMakeLists.txt at the root of the project:

add_subdirectory(TARGET_LEMON_TART)                  # add this line
add_subdirectory(${MBED_PATH})                       # this line was already in the file

The custom_targets.json file will look something like:

{
    "LEMON_TART": {
        "inherits": [
            "MCU_NRF52832"
        ]
        # your other changes here
}

I can then call the following to get the custom board to build (using Mbed CLI2, CMake & GCC):
mbed-tools compile -m LEMON_TART -t GCC_ARM

4 Likes

Ah! I had the exact same issue recently and could not figure out why it would break. Reading the error messages and the code that generates it I eventually put the pieces together but it was a bad experience…

I created an issue for that: CMake - Custom hardware targets must start with "mbed-" prefix · Issue #15197 · ARMmbed/mbed-os · GitHub

1 Like

Ah my bad @ladisla, it was actually your issue that was the final puzzle piece :tada: .

I’ve edited my previous post to give credit where it’s due, thanks for the prior detective work.

1 Like

Ahah no worries :slight_smile:

I have same issue.
Thanks for this solution, that resolve my issue. :tada:

This post helped me a lot to understand that I have to modify the CMakeLists.txt files and how to do it. I did not have any issue when compiling with cli1. However, when I tried to compile my code with cli2 I started having the same issues mentioned in this thread. There is one more thing I would like to add to this post.

If you are adding a custom board derived from an already supported MCU then these instructions work perfectly. But if you are adding also a new target mcu, then you have to modify one more CMakeLists.txt. I have an STM32L4S7ZIT6 MCU and it is not among the supported MCUs by default. After folowing all these steps I had to add add_subdirectory(TARGET_STM32L4S7xI EXCLUDE_FROM_ALL) to CMakeLists.txt file found in TARGET_STM32L4 folder. Here is my related question and the solution.

1 Like