This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF5340 Multi-Image example configuration help

I am working on a project that is being ported from the nRF52840 to the nRF5340 and the once unified radio and app codebase needs to be split to the app CPU and network CPU.

The problem I am facing is I don't quite understand how to create a multi image project and the examples provided by nrf_connect dont seme to have a multi image example.

All I see are options when selecting the example for app cpu or net cpu which look to configure the device tree  for that CPU but I don't see any for multi image projects.

When reading the documentation for the radio_test example I see that the app CPU needs to be flashed with the empty_app_core project but I would like to include this project as a parent to the radio_test child project.

Is there any examples on how to do this?

Parents
  • Hello,

    I didn't get the mutlig image build to to work with the radio test example even though 'empty_app_core' is defined as a child image in \nrf\samples\CMakelists.txt. I need to investigate this a bit more and get back to you.

    That said, there are mulitple examples of multi image projects in NCS. The BLE projects do for instance include the 'HCI_rpsmg' sample as a child image when you build for the app core. Have you tried that?

    Best regards,

    Vidar

  • Hello,

    Taking another look at this problem, I have made the following modifications.

    In my project root Kconfig I have the following entry

    module=CHILD_NET
    source "${ZEPHYR_BASE}/../nrf/subsys/partition_manager/Kconfig.template.build_strategy_domain"
    

    copied from ncs/nrf/subsys/partition_manager/Kconfig:73

    Then in my project root CMakeLists.txt I have the following

    set(NETCORE_IMAGE "child_net")
    set(NETCORE_IMAGE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/net")
    message("Adding ${NETCORE_IMAGE} firmware as child image")
    
    add_child_image(
      NAME ${NETCORE_IMAGE}
      SOURCE_DIR ${NETCORE_IMAGE_PATH}
      DOMAIN CPUNET
      BOARD ${CONFIG_DOMAIN_CPUNET_BOARD})

    which was copied from ncs/nrf/samples/CMakeLists.txt

    When I run west build --pristine -b nrf5340dk_nrf5340_cpuapp I get the following error

    fatal error: pm_config.h: No such file or directory
       38 | #include <pm_config.h>
          |          ^~~~~~~~~~~~~
    compilation terminated.

    How to I fix this?

  • sure,

    Since the west build process requires child images to be built in the scope of the ncs directory but if the child image is out of tree there's a cyclical dependency problem.

    My solution was based on Vidar's advice but since I did not want to hard code images such as the way hci_rpmsg and others in the files listed above, I created a variable build config with a new file called external_child_image.cmake in ncs/nrf/cmake 

    if (CONFIG_BUILD_EXTERNAL_CHILD_IMAGE)
        if (NOT CONFIG_CHILD_IMAGE_NAME)
            message(FATAL_ERROR "CONFIG_CHILD_IMAGE_NAME not set")
        endif()
    
        if (NOT CONFIG_CHILD_IMAGE_PATH)
            message(FATAL_ERROR "CONFIG_CHILD_IMAGE_PATH not set")
        endif()
    
        # allow the use of cmake variables in kconfig or prj.conf
        string(CONFIGURE ${CONFIG_CHILD_IMAGE_PATH} CHILD_IMAGE_PATH)
    
        message("Adding child image ${CONFIG_CHILD_IMAGE_NAME}\n"
        "located at ${CHILD_IMAGE_PATH}\n"
        "since CONFIG_BUILD_EXTERNAL_CHILD_IMAGE is set to 'y'")
    
        if (${CONFIG_CHILD_IMAGE_DOMAIN} STREQUAL "CPUNET")
            set(CHILD_IMAGE_BOARD_TARGET ${CONFIG_DOMAIN_CPUNET_BOARD})
        elseif (${CONFIG_CHILD_IMAGE_DOMAIN} STREQUAL "CPUAPP")
            set(CHILD_IMAGE_BOARD_TARGET ${CONFIG_DOMAIN_CPUAPP_BOARD})
        else()
            message(FATAL_ERROR "CHILD_IMAGE_DOMAIN not set to CPUNET or CPUAPP")
        endif()
    
        add_child_image(
        NAME ${CONFIG_CHILD_IMAGE_NAME}
        SOURCE_DIR ${CHILD_IMAGE_PATH}
        DOMAIN ${CONFIG_CHILD_IMAGE_DOMAIN}
        BOARD ${CHILD_IMAGE_BOARD_TARGET})
    endif()

    Then added the following entry to ncs/nrf/Kconfig.nrf

    config BUILD_EXTERNAL_CHILD_IMAGE
    	bool "Enable building an out of tree child image"
    	default n
    	select PARTITION_MANAGER_ENABLED
    
    if BUILD_EXTERNAL_CHILD_IMAGE
    
    config CHILD_IMAGE_NAME
    	string "external child image name"
    
    config CHILD_IMAGE_PATH
    	string "external child image path"
    
    config CHILD_IMAGE_DOMAIN
    	string "external child image domain"
    	help 
    		Child image CPU domain.
    		Can be CPUNET or CPUAPP
    
    endif #BUILD_EXTERNAL_CHILD_IMAGE

    Now in any external project with a dependent child image that is also external I have the following in the parent's prj.conf

    # add net cpu child image to build
    CONFIG_BUILD_EXTERNAL_CHILD_IMAGE=y
    CONFIG_CHILD_IMAGE_NAME="extern child image"
    CONFIG_CHILD_IMAGE_PATH="${APPLICATION_SOURCE_DIR}/path/to/child/image"
    CONFIG_CHILD_IMAGE_DOMAIN="CPUNET"

  • Thank you a lot!

    I have one more question:

    Does your child image folder contains pm.yml file?

  • I did not change anything else besides the above. I am also only using one image per domain (no bootloader, extra 3rd party hex, etc) so the pm.yml wasn't needed.

    Since I am building from source for both the child image and parent image the image placement in app and net domains is automatically calculated via board dts files when building. It's the same process as the peripheral_lbs example when building a single BT enabled app which will use hci_rpmsg as a child image on the net core. However, in my case I replace hci_rpmsg with a custom net core project.

    When building multiple images in the same domain I believe is when pm.yml is needed, however if you still have issues I would open a separate question for clarification from nordic.

  • Below everything anthony has done which is great,

    in ncs/nrf/CMakeList.txt, following line must be added :

    include(cmake/external_child_image.cmake)

  • Hi All,

    Thanks a lot for all of this.

    As zaxkv mentioned, I am also beginner and confused about the available documentation. I am trying to do the same than what Anthony mentioned, this is, replace hci_rpmsg with a custom net core. So, I followed this thread and per Anthony's post above I added the external_child_image.cmake, updated Kconfig.nrf, and added the child image configurations in the application core's proj.conf.

    I am using NCS v1.5.1 and SES v5.34a, but whenever I load the project, I still see hci_rpmsg created inside the build directory (even after full clean), so not sure if I am missing something in order for it not to be included in the project. Thoughts?

    And the other issue I see is that I am too getting the pm_config.h compile error, even though PARTITION_MANAGER_ENABLED is now in Kconfig whenever CONFIG_BUILD_EXTERNAL_CHILD_IMAGE=y.

    Any ideas?

    Thanks again!

    Peter U

Reply
  • Hi All,

    Thanks a lot for all of this.

    As zaxkv mentioned, I am also beginner and confused about the available documentation. I am trying to do the same than what Anthony mentioned, this is, replace hci_rpmsg with a custom net core. So, I followed this thread and per Anthony's post above I added the external_child_image.cmake, updated Kconfig.nrf, and added the child image configurations in the application core's proj.conf.

    I am using NCS v1.5.1 and SES v5.34a, but whenever I load the project, I still see hci_rpmsg created inside the build directory (even after full clean), so not sure if I am missing something in order for it not to be included in the project. Thoughts?

    And the other issue I see is that I am too getting the pm_config.h compile error, even though PARTITION_MANAGER_ENABLED is now in Kconfig whenever CONFIG_BUILD_EXTERNAL_CHILD_IMAGE=y.

    Any ideas?

    Thanks again!

    Peter U

Children
  • as Zaxkv pointed out, I forgot to mention that

     include(cmake/external_child_image.cmake) 

    needs to be added to ncs/nrf/CMakeList.txt so make sure you have that too.

    hci_rpmsg is included here whenever you build with CONFIG_BT_RPMSG_NRF53=y which is set when you use CONFIG_BT=y

    if you are getting pm_config.h missing it is because you are trying to build the child image from the context of your project and not the ncs root directory so header includes are missing.

    The build sequence from what observe is as follows.

    - generate Kconfig autoconf.h headers from all ncs Kconfigs and prj.conf
    - build zephyr kernel
    - build child images
    - enter project directory <--- no child images can be built after here due to ncs root path context being lost
    - build project app image
    - merge child images into final image

    Therefore all child images MUST be built before the project directory is entered, my above solution is a variable child image injection to allow the ncs context to build a child image specified by the app. since Kconfig files and prj.conf are parsed first, an external child image can be injected into the ncs build sequence prior to the app project being built.

    Make sure you are building all child images before your app is built by checking the build logs. the following text should be present when building with west in the terminal output in the following sequence,

    "=== child image <CHILD IMAGE NAME> - <CPU DOMAIN> begin ==="

    *child image is built*

    "=== child image <CHILD IMAGE NAME> - <CPU DOMAIN> end ==="

    "libmetal version: <PROJECT_VERSION> <CMAKE_SOURCE_DIR>"

    where CMAKE_SOURCE_DIR is the path to your app project.

  • Similar to what Anthony suggested, I have this build sequence:

    - Zephyr kernel

    - mcuboot

    - hci_rpmsg

    - my_net_core image -> This is where the build stops

    - Everything else

    I have been playing around with the build order and still have the same issue with pm_config.h, not sure what else I have to do.

    I am wondering if this is related to this other issue with mcuboot, which is still not solved yet: devzone.nordicsemi.com/.../nrf5340-mcuboot-build-pm_config-h-not-found

  • I do not use mcuboot so I do not know how it might affect the build sequence.

    You could try removing mcuboot.. Also I have not tried including both hci_rpmsg and a custom net core image either. If you are trying to use Bluetooth + a custom netcore image that might be a source of problems.

    You might want to open a separate issue so the developers at Nordic can provide better support.  

  • Got it now, the net core we are using is basically a copy of the the hci_rpmsg, the only difference is that it is out of the SDK folder structure (I will call that net_core).

    So what I did was to just remove hci_rpmsg from the parent image build since the net_core provides the same features as they are the same. To do this I added the line below to the parent config file:

    CONFIG_HCI_RPMSG_BUILD_STRATEGY_SKIP_BUILD=y

    With that, the build completes successfully and now I have our net_core as a child image.

    Thanks a lot for all the information in this thread!

Related