Multi image configuration with mcuboot doubt

Hi! I'm working with nRF52833 in a laird dev kit and I'm having problems understanding the multi-image build configuration on nrf Connect SDK with zephyr.

Our project concept is the following:

Having mcuboot on top, and 2 more bootable images.

The first image is the one with the hability to write to the slot 1 of both images.

The second image is the client application.

And I'm having problems on undestranding the project configuration and how child image works.

I'm having doubts in 2 different aspects, which are about project configuration and image management.

In order to understand the first one I'm working with the hello world sample with mcuboot enabled and trying to add an additional image to the project. Doing this I have the following doubts:

- Whats the correct syntax in the dts in order to specify my concept?

    As stated in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/readme-zephyr.html#building-and-using-mcuboot-with-zephyr  the first updateable image will go as image_0_primary_partition and image_0_secondary_partition and the second as image_1_primary_partition and image_1_secondary_partition. But when I go to the board dts I find the following corresponding to the hello world first image:

That label confuses me.

- Do I need to modify the flash-map stated in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/design.html#flash-map for multi-image? If so, where is it located in my project?

-Is hello world + mcuboot a multi image build? If so, is mcuboot build in the project as a child? Why I don't find in cmakelists.txt mcuboot child enable and definition as stated in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/ug_multi_image.html#defining-and-enabling-a-child-image ?

And about the second aspect, image management:

-The smp server example writes the image received in the slot 1 of the current image, is it possible to make it modify the slot 1 of other images? If not, what's the correct approach to my flash structure proposal?

Is there any example or documentation that clarifies what I'm trying to do?

Thanks!

Parents
  • Have you made any progress here?

    - Do I need to modify the flash-map stated in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/design.html#flash-map for multi-image? If so, where is it located in my project?

    No, you should not modify those. Instead use the Partition Manager and Kconfigs (.conf files).

    -Is hello world + mcuboot a multi image build? If so, is mcuboot build in the project as a child? Why I don't find in cmakelists.txt mcuboot child enable and definition as stated in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/ug_multi_image.html#defining-and-enabling-a-child-image ?

    Yes, hello_world+mcuboot is a multi image build. You need to look at hello_world/build/mcuboot. If you have enabled mcuboot all the mcuboot-related that is generated will be placed there.

    -The smp server example writes the image received in the slot 1 of the current image, is it possible to make it modify the slot 1 of other images? If not, what's the correct approach to my flash structure proposal?

    Could you take a look at the machine learning sample and the configs I linked to and see if you're able to get this to work? If not please get back to me and I will to put off some time and try set up a working example using the nRF52833

  • Hi Simon,

    Thanks for all the information.

    I've read about partition manager in order to understand how multi image works and I have more doubts.

    I'm trying to modify the partitions in the smp server example but I don't know how to shrink the app size, because in partitions.yml the mcuboot + the smp server app is occupying all the flash size.

    Who decides the size of my application? Because the smp example size is 0x37000, knowing this, I cannot fit any more images in my build because the primary and secondary partitions of smp server already occupies all flash.

    Moreover, if I wanted to configure a simple hello world as a child image to another project, what would be the steps to follow in partition manager and in the hello world itself?

    If you could try to set up the example that would be great!

    Thanks

  • UPDATE 21.01.2022: Added strikethrough to some information I provided, after figuring this is not the best way to go about this. See later reply for more details.


    Hello, I will share my temporary progress. The project attached below is built using NCS v1.8.0 and the nRF52833dk_nrf52833

    2705.multi_img_dfu_833.zip

    I created a pm_static.yml file that would allocate space for the mcuboot_primary_1 (client APP slot 0) mcuboot_secondary_1 (client APP slot 1) partitions. Here is the result from running ninja partition_manager_report in the build folder:

      flash_primary (0x80000 - 512kB):
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x39000 - 228kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x38e00 - 227kB)-+
    | 0xc200: app (0x38e00 - 227kB)                   |
    +-------------------------------------------------+
    | 0x45000: mcuboot_secondary (0x39000 - 228kB)    |
    | 0x7e000: mcuboot_primary_1 (0x1000 - 4kB)       |
    | 0x7f000: mcuboot_secondary_1 (0x1000 - 4kB)     |
    +-------------------------------------------------+
    
      sram_primary (0x20000 - 128kB):
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x20000 - 128kB) |
    +--------------------------------------------+

    What todo next:

    • Modify the mcumgr libraries such that they will look at the magic value stored in the start of app_update.bin and if the value is equal to e.g. 0x96f31111, it will place the update into "Client APP slot 1" (mcuboot_secondary_1), otherwise if the value is 0x96f3b83d (magic value for normal mcuboot updates, see MCUboot-->Image Format) put it into "DFU app slot 1" (mcuboot_secondary)
      • Then, if you want to update the client APP, you would need to modify the app_update.bin file and swap 0x96f31111 with the default value 0x96f3b83d
    • Modify the size of mcuboot_primary_1 and mcuboot_secondary_1 according to the size of client APP
  • I looked into this, and it seems like you don't need to do any modifications to the mcumgr libraries.

    If you issue an image upload command, img_mgmt_upload() will run and set .image to 0 and next img_mgmt_impl_upload_inspect()-->img_mgmt_get_unused_slot_area_id() will run and since image was set to 0, it will run zephyr_img_mgmt_flash_area_id(1), which run FLASH_AREA_ID(image_1), which will make it use mcuboot_secondary (DFU APP slot 1).

    To make it use mcuboot_secondary_1 (Client APP slot 1, which I defined in the pm_static.yml file), you need to make it select image_3, and for that you'll have to run zephyr_img_mgmt_flash_area_id(3) and for that to happen, you need to set image to 1 in img_mgmt_upload().

    One way of going about this, is to use the -n flag, to set the image to 1 when running the mcumgr image upload command, see mcumgr-->image management

    Then I think cbor_read_object() will override the old image value and set it to 1, and the new image will be stored in mcuboot_secondary_1.

    I have not gotten time to test this, but I'll try it out in the next days.

  •  5226.multi_img_dfu_833_v2.zip

    I did some testing, and I was able to perfomr multi image DFU using the sample above and an nRF52840DK (don't have an nRF52833 DK at the moment). I enabled serial dfu support following Modify the Hello World sample and performed a DFU following Testing. The only difference I did was to append "-n 1" when running the upload command:

    mcumgr --conntype serial --connstring "COM5,baud=115200" image upload -n 1 -e app_update.bin

    I then confirmed using the Programmer app that the new uploaded images was successfully put into mcuboot_secondary_1 (Clien APP slot 1). 

    The next step now is to be able to swap the image in mcuboot_secondary_1 into 
    mcuboot_primary_1 using mcuboot.
  • Hello, have you gotten any progress? I've not been able to get it fully working yet, but I'll share my temporary progress.

    I still have some problems withmcuboot not being able to validate mcuboot_primary_1 (getting  W: Failed reading image headers; Image=1
    E: Unable to find bootable image). I tried to add a custom sample and add it as as a child image (placed into mcuboot_primary) to the mutli_image_dfu sample, but it is not able to validate it.

    Here is the multi_img_dfu sample (only tested on nRF52840 DK):

    multi_img_dfu_v3.zip

    Here is a diff of the nrf, after modifying it to support a custom child image:

    https://github.com/nrfconnect/sdk-nrf/compare/nrfconnect:cfedfdf...simon-iversen:fcfc6ef

    Best regards,

    Simon

  • Hi Simon,

    Sorry for the lateness, my work had been shifted, and I couldn't spend time on that.

    What I discovered so far:

    Mcuboot is meant to boot always a fix location, so I realized that having mcuboot to boot image 1 or 2 is not viable. A DFU in different slots could be possible but again, it requires modifying mcuboot source code in order to modify the fixed image offset.

    I discovered that mcuboot has dfu capabilities too, so instead of having another image to do the dfu process apart from the client image, I'm trying to make the mcuboot update directly to the client image. In doing so, the dfu functionality is not inside the client application, and that was what I was looking for.

    But in this process I have some doubts.

    I have the following mcuboot configuration:

    That enables me to upload a client image successfully:

    But, mcuboot is not writing the image to slot 1 like the smp server example, instead is writing it directly to slot 0 and overwriting the application.

    In doing so, I cannot test it, and mcuboot is not swapping, just writing new image and booting it. Am I doing something wrong?

    Is mcumgr the commands that I need to use to upload new images in mcuboot serial configuration?

    mcuboot serial only contemplates usb and uart, is it possible to make it work with ble?

    Is mcuboot really working with mcumgr when I enable mcuboot_serial?

    The only "documentation" that I found is in its Kconfig file https://github.com/nrfconnect/sdk-mcuboot/blob/v1.7.99-ncs-branch/boot/zephyr/Kconfig

Reply
  • Hi Simon,

    Sorry for the lateness, my work had been shifted, and I couldn't spend time on that.

    What I discovered so far:

    Mcuboot is meant to boot always a fix location, so I realized that having mcuboot to boot image 1 or 2 is not viable. A DFU in different slots could be possible but again, it requires modifying mcuboot source code in order to modify the fixed image offset.

    I discovered that mcuboot has dfu capabilities too, so instead of having another image to do the dfu process apart from the client image, I'm trying to make the mcuboot update directly to the client image. In doing so, the dfu functionality is not inside the client application, and that was what I was looking for.

    But in this process I have some doubts.

    I have the following mcuboot configuration:

    That enables me to upload a client image successfully:

    But, mcuboot is not writing the image to slot 1 like the smp server example, instead is writing it directly to slot 0 and overwriting the application.

    In doing so, I cannot test it, and mcuboot is not swapping, just writing new image and booting it. Am I doing something wrong?

    Is mcumgr the commands that I need to use to upload new images in mcuboot serial configuration?

    mcuboot serial only contemplates usb and uart, is it possible to make it work with ble?

    Is mcuboot really working with mcumgr when I enable mcuboot_serial?

    The only "documentation" that I found is in its Kconfig file https://github.com/nrfconnect/sdk-mcuboot/blob/v1.7.99-ncs-branch/boot/zephyr/Kconfig

Children
  • pau_vilanova said:

    But, mcuboot is not writing the image to slot 1 like the smp server example, instead is writing it directly to slot 0 and overwriting the application.

    In doing so, I cannot test it, and mcuboot is not swapping, just writing new image and booting it. Am I doing something wrong?

    Hello and sorry for the delay, I have been gone for the last two months. I think this is the intention. If you perform the dfu through the application, you need two slots in order to have a fallback in case the new update bricks your product. However, if you perform the update through mcuboot, a corrupted firmware update is not an issue, because mcuboot is the fallback (can just perform new update with noncorrupt image).

    Best regards,

    Simon

Related