Shared config values in multi-image build

I'm working with an nRF5340 and am trying to set up a multi-image build in VS Code with the "rpc_host" project on the network core using the "CONFIG_BT_RPC_STACK=y" config value. I'm basing this off of the Bluetooth: Peripheral HIDS Mouse sample, which has an overlay to enable a multi-image build on the nRF5340.

In the BLE RPC documentation page, it provides a list of config values that must have the same value in both images. It also states to use an overlay/fragment that is shared between both images in order to keep the values for these config options in sync.

In the Perhipheral HIDS Mouse sample, though, multiple config values are duplicated in the "prj.conf" and the "child_image/rpc_host.conf" files (e.g. "CONFIG_BT_DEVICE_NAME"), which clearly is not adhering to this principle for a shared overlay so that these values are only declared in a single source of truth.

I'm trying to figure out a way to modify this sample to keep it DRY and not duplicate config values for the application and network core images. Since the "rpc_host" image is enabled entirely by the "CONFIG_BT_RPC_STACK" option, and not managed in a build config, CMakeLists, or other file in the application project, the options are limited. I've considered several options:

  1. Have two separate config files in the "child_images" directory (one for child-image-only values, one for shared values), and have them both applied to the child image and add the shared one as a fragment to the parent image build config. Based on the multi-image build documentation though, it seems that only one fragment can be automatically applied to the child image ("child_image/<ACI_Name>.conf"), and I can't specify additional ones, so this approach would not work.
  2. Specify a shared fragment for both the child image ("rpc_host") and the parant/application image. Since the child image is enabled by "CONFIG_BT_RPC_STACK", though, and not by any kind of West build configuration, I can't find a way to apply a fragment to it.
  3. Somehow include a shared fragment within the child image and parent image conf files (something like "#include shared.conf"). I have not been able to find a way to do this through my search of documentation though.

So, the question: how can I have a single conf file that is applied to both the application image and the "rpc_host" child image that is enabled through the "CONFIG_BT_RPC_STACK" config setting, while also supporting additional config values that are specific to one or the other?

As a separate, semi-related question: the CONFIG_BT_RPC_STACK config value (and Bluetooth over RPC in general) is marked in the SDK as "EXPERIMENTAL". The nRF5340, however, has been out for almost 4 years now, so I would expect that there would be production-grade options for utilizing the networking core. If BLE over RPC is experimental, what's the recommended production-grade option for offloading BLE to the network core?

Parents
  • Hello,

    Well done on the research you have done on this. The way to use a shared fragment on two images is to use extra CMake arguments when building.

    Specify a shared fragment for both the child image ("rpc_host") and the parant/application image. Since the child image is enabled by "CONFIG_BT_RPC_STACK", though, and not by any kind of West build configuration, I can't find a way to apply a fragment to it.

    This is the way to go. You can add the CMake flag -Drpc_host_OVERLAY_CONFIG=<path-to_your-shared-fragment.conf> and -DOVERLAY_CONFIG=<your-shared-fragment>.conf to the build command to apply the fragment to both the RPC host child image and the application image. When building the child image, the build system will search in the child image application directory, so you need to specify the whole relative path from the child image application directory to your shared fragment or the full absolute path to your shared fragment.

    As a separate, semi-related question: the CONFIG_BT_RPC_STACK config value (and Bluetooth over RPC in general) is marked in the SDK as "EXPERIMENTAL". The nRF5340, however, has been out for almost 4 years now, so I would expect that there would be production-grade options for utilizing the networking core. If BLE over RPC is experimental, what's the recommended production-grade option for offloading BLE to the network core?

    HCI RPMsg is not experimental, though it is part of a dual chip configuration, so it is only the Bluetooth LE controller which is on the network core.

    If you want to know anything about future features or our roadmap in general, please contact your Regional Sales Director.

    Best regards,

    Maria

  • Thanks Maria, this is super helpful. A few additional questions:

    1. Is there a way to specify a CMake flag in a sysbuild config (i.e. in sysbuild.cmake)?

    2. What is the difference between the OVERLAY_CONFIG and EXTRA_CONF_FILE build variables? I'm guessing that EXTRA_CONF_FILE is the new version (it's listed in the "latest" Zephyr documentation) and OVERLAY_CONFIG is an old term (it's last shown in the 3.3.0 Zephyr documentation)? Since nRF Connect SDK 2.5.1 is using Zephyr 3.4.99 though, it would seem that I should be using EXTRA_CONF_FILE instead?

    3. What's the best way to specify the "path-to_" in the <path-to_your-shared-fragment.conf>? I tried using a CMAKE variable (-Drpc_host_OVERLAY_CONFIG=${CMAKE_SOURCE_DIR}/overlay-shared.conf) because, as I'm sure you know, it otherwise attempts to use the child image's source directory as the path root. This didn't work though (it still used the child image's source directory). I also tried the CMAKE_CURRENT_SOURCE_DIR (no difference), CMAKE_BINARY_DIR (uses the build directory), and PROJECT_SOURCE_DIR (doesn't seem to be set) variables, none of which worked.

  • Hello,

    Great to see this was helpful.

    Comments and answers to your questions:

    1. Sysbuild is pretty new for me, so I have to ask my colleagues about this.

    2. Good catch. OVERLAY_CONFIG has been replaced by EXTRA_CONF_FILE from NCS v2.5.0 (Zephyr v3.4.99 as well). My previous answer is valid for NCS versions < 2.5.0. For NCS v2.5.x, you use EXTRA_CONF_FILE to apply Kconfig fragments to your build. The change is listed in the release notes for Zephyr 3.4.0 under Build system and infrastructure.

    3. I found that specifying the relative path and the absolute path worked. I get that this is tedious, so I will post a question internally to see if some of the developers has some tips.

    Best regards,

    Maria

  • Hi Maria, were you able to get any info on items 1 and 3?

  • Hello,

    Sorry about the delay.

    JordanK said:
    1. Is there a way to specify a CMake flag in a sysbuild config (i.e. in sysbuild.cmake)?

    You can add a CMake flag in sysbuild.cmake. I created a sysbuild.cmake in the Peripheral HIDS mouse sample directory which included

    set(-Drpc_host_EXTRA_CONF_FILE="<absolute-path-to-project-directory>/shared-fragment.conf")

    set(-DEXTRA_CONF_FILE=shared-fragment.conf)

    which had the same outcome as adding the CMake flags to the Extra CMake arguments in the build configuration.

    You can use the ZEPHYR_BASE variable in the path. For example \${ZEPHYR_BASE}/../nrf/bluetooth/samples/peripheral_hids_mouse/shared-fragment.conf

    JordanK said:
    3. What's the best way to specify the "path-to_" in the <path-to_your-shared-fragment.conf>? I tried using a CMAKE variable (-Drpc_host_OVERLAY_CONFIG=${CMAKE_SOURCE_DIR}/overlay-shared.conf) because, as I'm sure you know, it otherwise attempts to use the child image's source directory as the path root. This didn't work though (it still used the child image's source directory). I also tried the CMAKE_CURRENT_SOURCE_DIR (no difference), CMAKE_BINARY_DIR (uses the build directory), and PROJECT_SOURCE_DIR (doesn't seem to be set) variables, none of which worked.

    CMake variables can be used from command line*. This is essentially what is done when applying flags to the build command or adding the command in sysbuild.cmake. In conclusion, the best way is to use sysbuild.cmake to add the CMake argument for specifying the path to the shared Kconfig fragment.

    * Edit: This is not 100% correct:

    If the CMake variable is defined early and is internal, it can be used in the path and the build system will resolve it. The ZEPHYR_BASE variable is an example of an early defined internal CMake variable. You can read more on these configurations in The Initial Configuration part of the Setting Kconfig configuration documentation.

    Best regards,

    Maria

Reply
  • Hello,

    Sorry about the delay.

    JordanK said:
    1. Is there a way to specify a CMake flag in a sysbuild config (i.e. in sysbuild.cmake)?

    You can add a CMake flag in sysbuild.cmake. I created a sysbuild.cmake in the Peripheral HIDS mouse sample directory which included

    set(-Drpc_host_EXTRA_CONF_FILE="<absolute-path-to-project-directory>/shared-fragment.conf")

    set(-DEXTRA_CONF_FILE=shared-fragment.conf)

    which had the same outcome as adding the CMake flags to the Extra CMake arguments in the build configuration.

    You can use the ZEPHYR_BASE variable in the path. For example \${ZEPHYR_BASE}/../nrf/bluetooth/samples/peripheral_hids_mouse/shared-fragment.conf

    JordanK said:
    3. What's the best way to specify the "path-to_" in the <path-to_your-shared-fragment.conf>? I tried using a CMAKE variable (-Drpc_host_OVERLAY_CONFIG=${CMAKE_SOURCE_DIR}/overlay-shared.conf) because, as I'm sure you know, it otherwise attempts to use the child image's source directory as the path root. This didn't work though (it still used the child image's source directory). I also tried the CMAKE_CURRENT_SOURCE_DIR (no difference), CMAKE_BINARY_DIR (uses the build directory), and PROJECT_SOURCE_DIR (doesn't seem to be set) variables, none of which worked.

    CMake variables can be used from command line*. This is essentially what is done when applying flags to the build command or adding the command in sysbuild.cmake. In conclusion, the best way is to use sysbuild.cmake to add the CMake argument for specifying the path to the shared Kconfig fragment.

    * Edit: This is not 100% correct:

    If the CMake variable is defined early and is internal, it can be used in the path and the build system will resolve it. The ZEPHYR_BASE variable is an example of an early defined internal CMake variable. You can read more on these configurations in The Initial Configuration part of the Setting Kconfig configuration documentation.

    Best regards,

    Maria

Children
  • Some extra insight:

    Sysbuild is in an experimental state, and is supported for Nordic boards. If you are using a custom nRF5340 board, you should not use sysbuild at this stage.

    For the default installation of NCS, using ZEPHYR_BASE/../nrf is going to work. But there could be cases where the folder structure or folder names has been changed. Using ZEPHYR_NRF_MODULE instead is therefore safer.

    The full command is then

    set(-Drpc_host_EXTRA_CONF_FILE="\${ZEPHYR_NRF_MODULE_DIR}/samples/bluetooth/peripheral_hids_mouse/shared-fragment.conf")

    BR,

    Maria

Related