Implement bootloader in NCS SDK

Hello,

Until now I was working on an application based on the nRF5 SDK: it is this application that is used by my customers.
Now I would like to use the NCS SDK to continue to have the latest features and bug fixes.

Here I almost finished redeveloping my new application (based on NCS SDK) to work like my old one (based on nRF5 SDK) but I have a problem with the bootloader...

My board (contains an nrf 52840) has no buttons and no external memory (so I will have to overwrite existing code when I do an update) but does have a UART.
I need to be able to update the application but also the bootloader.

Here are my questions:

  • I think I have to go into recovery mode to be able to update in this situation? But how can I do it if I don't have a button?
  • The update files will be sent by another microcontroller on the board via the uart: can you tell me more about what I need so that the other microcontroller can communicate with the nrf 52840 to send the files to the bootloader? (files ? protocol ?)
  • Is it possible to update a device that would work with the nRF5 SDK (secure_bootloader_uart_mbr_pca10056) to keep the old bootloader but updating the softdevice+app with the new application (NCS SDK)?

THANKS

Parents
  • Hi,

    I think I have to go into recovery mode to be able to update in this situation? But how can I do it if I don't have a button?

    One option is to use "serial recovery with wait", 

    A colleague of mine has written this repository with samples, where you the serial recovery samples containing samples for serial recovery using both the waiting and mcumgr method and regular UART serial recovery. I suggest you have a look at these samples to see if they fit your project or if you're able to tailor them to your project

    The update files will be sent by another microcontroller on the board via the uart: can you tell me more about what I need so that the other microcontroller can communicate with the nrf 52840 to send the files to the bootloader? (files ? protocol ?)

    I recommend you to have a look at devzone.nordicsemi.com/.../doing-an-fota-via-ble-using-a-nordic-development-kit

    Is it possible to update a device that would work with the nRF5 SDK (secure_bootloader_uart_mbr_pca10056) to keep the old bootloader but updating the softdevice+app with the new application (NCS SDK)?

    Yes, but there are things you will have to take in mind. I recommend you to have a look at  One bootloader to rule them all which refers to a sample created by a colleague of mine showing how to port a nRF5 app to become a NCS app  Hang with nRF5 SDK 17.1.0 Bootloader and nRF Connect SDK 2.1.0 application . This case, https://devzone.nordicsemi.com/f/nordic-q-a/100639/nrf5340-multi-image-dfu-update-over-ble-remote-error-in-value-3 does also to some extent explain some of the procedure

    Let me know if this is enough to get you started! 

    Kind regards,
    Andreas

  • Hello,

    Thank you very much for your answer.

    I've been working on this for 2 weeks but unfortunately I still have problems...

    Here at the moment, I'm trying to find a way to update the devices that are with my customers (with the nRF5 SDK) so that it's not too complicated for us and for them to manage the updates of old devices and new ones (with NCS SDK). I think the simplest solution would be to manage to only update the app of the devices that are with my customers (therefore keeping the old bootloader and the softdevice present in the devices).

    To do this, I tried to do like Vidar Berg with his project 2273.peripheral_lbs.zip (devzone.nordicsemi.com/.../hang-with-nrf5-sdk-17- 1-0-bootloader-and-nrf-connect-sdk-2-1-0-application) but unfortunately there must be things I forgot because it doesn't work.

    When I compile my project and flash it, it works on my device. On the other hand, if I send the update to a device working with the nRF5 SDK, it accepts the update but afterwards it is blocked.

    Here are the problems I'm seeing that I don't know how to fix:

    - In the prj.conf file of my project, I put "CONFIG_FLASH_LOAD_OFFSET=0x27000" but it is the value 0xC000 which is put (I have a warning for that in the logs).

    - In my mcuboot.cong file in the child_image folder, I added "CONFIG_SINGLE_APPLICATION_SLOT=y". Despite this, I have to provide memory in my pm_static.yml file for mcuboot_secondary otherwise I get a compilation error: do you know why?

    Here are my DFU logs:

    3312.test.log

    Here is my \Application\boards\pm_static_nrf52840dk_nrf52840.yml:

    app:
      address: 0x10200
      region: flash_primary
      size: 0xdfe00
    mcuboot:
      address: 0x0
      region: flash_primary
      size: 0x10000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x1200
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0x10000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      size: 0xD0000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      orig_span: &id002
      - app
      region: flash_primary
      size: 0xcfe00
      span: *id002
    mcuboot_secondary:
      address: 0xE0000
      end_address: 0xF0000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x10000
    settings_storage:
      address: 0xf0000
      end_address: 0x100000
      region: flash_primary
      size: 0x10000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000


    Here is my \Application\child_image\mcuboot.conf:
    CONFIG_UART_CONSOLE=n
    CONFIG_MCUBOOT_SERIAL=y
    CONFIG_BOOT_SERIAL_UART=y
    
    CONFIG_FPROTECT=n #The flash protection mechanism in MCUboot assumes that the mcuboot_primary slot is always placed after the mcuboot partition. It disabled flash protection to get around this limitation.
    
    #CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x18000
    CONFIG_PARTITION_MANAGER_ENABLED=y
    
    # The build won't fit on the partition allocated for it without size
    # optimizations.
    CONFIG_SIZE_OPTIMIZATIONS=y
    
    # Serial
    CONFIG_SERIAL=y
    CONFIG_UART_CONSOLE=n
    CONFIG_UART_LINE_CTRL=y
    
    # MCUBoot serial
    #CONFIG_MCUBOOT_SERIAL=y
    #CONFIG_BOOT_SERIAL_UART=y
    
    # Config logger
    CONFIG_LOG=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_UART=n
    CONFIG_LOG_BACKEND_RTT=y
    
    #-------------------------------------------------------------
    
    # Declare for single slot and partition size for MCUBoot
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x10000
    CONFIG_SINGLE_APPLICATION_SLOT=y
    
    CONFIG_BOOT_SIGNATURE_KEY_FILE="mcuboot/key/mcuboot_private.pem"  # add a signature key file to this bootloader. This option only accepts the private key of an ECDSA key pair, as build system scripts automatically extract the public key at build time. The file path is relatively to the application directory.
    CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
    


    Here is my \Application\boards\nrf25840dk_nrf52840.overlay:

    /* Copyright (c) 2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    / {
    	/*
    	* In some default configurations within the nRF Connect SDK,
    	* e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell.
    	* This devicetree overlay ensures that default is overridden wherever it
    	* is set, as this application uses the RNG node for entropy exclusively.
    	*/
    	chosen {
    		zephyr,entropy = &rng;
    	};
    };
    &adc {
    	status = "disabled";
    };
    &uart1 {
    	status = "disabled";
    };
    &pwm0 {
    	status = "disabled";
    };
    &i2c0 {
    	status = "disabled";
    };
    &spi0 {
    	status = "disabled";
    };
    &spi1 {
    	status = "disabled";
    };
    &spi2 {
    	status = "disabled";
    };
    &spi3 {
    	status = "disabled";
    };
    &qspi {
    	status = "disabled";
    };
    &usbd {
    	status = "disabled";
    };
    
    &uart0_default {
    	group1 {
    		psels = <NRF_PSEL(UART_TX, 1, 1)>, <NRF_PSEL(UART_RTS, 0, 5)>;
    	};
    };
    
    &uart0_default {
    	group2 {
    		psels = <NRF_PSEL(UART_RX, 1, 2)>, <NRF_PSEL(UART_CTS, 0, 7)>;
    	};
    };
    
    &uart0_default {
    	group1 {
    		psels = <NRF_PSEL(UART_TX, 1, 1)>, <NRF_PSEL(UART_RTS, 0, 5)>;
    	};
    };
    
    &uart0_default {
    	group2 {
    		psels = <NRF_PSEL(UART_RX, 1, 2)>, <NRF_PSEL(UART_CTS, 0, 7)>;
    	};
    };
    
    &uart0_default {
    	group1 {
    		psels = <NRF_PSEL(UART_TX, 1, 2)>, <NRF_PSEL(UART_RTS, 0, 5)>;
    	};
    };
    
    &uart0_default {
    	group2 {
    		psels = <NRF_PSEL(UART_RX, 1, 1)>, <NRF_PSEL(UART_CTS, 0, 7)>;
    	};
    };
    
    &uart0_default {
    	group2 {
    		psels = <NRF_PSEL(UART_RX, 1, 2)>, <NRF_PSEL(UART_CTS, 0, 7)>;
    	};
    };
    
    &uart0_default {
    	group1 {
    		psels = <NRF_PSEL(UART_TX, 1, 1)>, <NRF_PSEL(UART_RTS, 0, 5)>;
    	};
    };
    
    &uart0_default {
    	group1 {
    		psels = <NRF_PSEL(UART_TX, 1, 2)>, <NRF_PSEL(UART_RTS, 0, 5)>;
    	};
    };
    
    &uart0_default {
    	group2 {
    		psels = <NRF_PSEL(UART_RX, 1, 1)>, <NRF_PSEL(UART_CTS, 0, 7)>;
    	};
    };
    
    &arduino_adc {
        io-channel-map = <0 &adc 1>, <1 &adc 2>, <2 &adc 4>, <3 &adc 5>, <4 &adc 6>, <5 &adc 7>;
    };
    
    
    
    /delete-node/ &scratch_partition;
    /delete-node/ &storage_partition;
    
    
    // Place storage partition below nRF5 Bootloader. The bootloader starts at 0xf8000 in this case.
    &flash0 {
        partitions {
            storage_partition: partition@f5000 {
                label = "storage";
                reg = < 0xf5000 0x3000 >;
            };
        };
    };

    Here is my prj.conf of my Application:

    #
    # Copyright (c) 2020 Nordic Semiconductor
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    # nRF board library
    CONFIG_DK_LIBRARY=y
    
    CONFIG_MBEDTLS_SHA1_C=n
    CONFIG_FPU=y # Allow to process float (double) numbers
    CONFIG_ASSERT=y
    
    # Enable the UART driver
    CONFIG_UART_INTERRUPT_DRIVEN=y #UART in interrupt mode
    CONFIG_SERIAL=y
    
    # Enable ring buffer
    CONFIG_RING_BUFFER=y
    
    # Add Bootlaoder to the application
    # CONFIG_SECURE_BOOT=y
    CONFIG_BOOTLOADER_MCUBOOT=y # add MCUboot as upgradable bootloader 
    
    CONFIG_IMG_MANAGER=y
    CONFIG_MCUBOOT_IMG_MANAGER=y
    CONFIG_IMG_ERASE_PROGRESSIVELY=y
    
    CONFIG_SIZE_OPTIMIZATIONS=y
    CONFIG_FLASH_LOAD_OFFSET=0x27000
    
    # After you upload a new image and reset the development kit, MCUboot attempts to boot the secondary image. If this image has, in order of precedence, a major, minor, or revision value that is lower than the primary application image, it is considered invalid and the existing primary application boots instead.
    # The optional label or build number specified after the + character is ignored when evaluating the version. An existing application image with version 0.1.2+3 can be overwritten by an uploaded image with 0.1.2+2, but not by one with 0.1.1+2.
    CONFIG_MCUBOOT_IMAGE_VERSION="0.1.0+0"
    

    And finaly, here are my partitions:

    app:
      address: 0x10200
      region: flash_primary
      size: 0xdfe00
    mcuboot:
      address: 0x0
      region: flash_primary
      size: 0x10000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x1200
      placement:
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0x10000
      orig_span: &id001
      - mcuboot_pad
      - app
      region: flash_primary
      size: 0xD0000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      orig_span: &id002
      - app
      region: flash_primary
      size: 0xcfe00
      span: *id002
    mcuboot_secondary:
      address: 0xE0000
      end_address: 0xF0000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x10000
    settings_storage:
      address: 0xf0000
      end_address: 0x100000
      region: flash_primary
      size: 0x10000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000

    Here I only put the MCUboot to simplify but then I would like to add the CONFIG_SECURE_BOOT.

    Thanks for your help !

  • Hi,

    You understood my problem very well: everything you said is correct.

    The devices that are with my customers were developed with the NRF5 SDK. As I want to be able to benefit from the new features, I was forced to redevelop my application using the NCS SDK.
    All the old features now work with this new SDK and so I would now like to get the bootloader working to continue to be able to update the devices that are in the field when I have a new release.
    So I created this ticket to find out how to implement the bootloader in the NCS SDK to be able to update my old devices that work with the old SDK and also how to update new devices that would work with the new SDK.

    Now I know how to update the application of my devices which are at my customers (based on the nRF5 SDK) to an application based on the NCS SDK -> therefore an update which uses the bootloader of the nRF5 SDK
    Now I would like new devices we produce to use the Zephyr bootloader (NCS SDK). The problem I have is that I can't update it: once I write the file to MCUboot secondary, I can't get it to write this file to s0/s1.

    To summarize, now I can update the applications of the devices that are with my customers (using the nRF5 SDK) so I can continue to send them my new updates. But I would like also to use the Zephyr bootloader for the new devices we produce so the bootloader update must work (update a device working with the NCS SDK to a new version coming from the NCS SDK).

    Thank you

  • Great, thank you. That makes us up to speed with what you're attempting to achieve

    I've spent the day digging around in the serial recovery configurations together with my colleague and we found a discovery that could be a potential solution w.r.t creating an app that uses serial recovery + NSIB in NCS.

    When using serial recovery, pretty much every other configuration have been disabled to keep things as small as possible. That does also include https://github.com/nrfconnect/sdk-mcuboot/blob/adab597a0eb0eb9c030a7b797748a49ca89988c2/boot/zephyr/Kconfig.serial_recovery#L202, which is required for MCUboot to do it's magic (i.e perform the update when restarting the device). MCUboot will not move the image from mcuboot secondary to its respective image slot unless the new image is confirmed for upgrade. 

    So since this configuration is disabled by default in serial recovery, you can't set the image to confirmed. Enabling the config should fix that.

    After you've added this configuration and tagged the new update image with 'confirm', MCUboot should transfer it from mcuboot_secondary to s0/s1 by following the steps in https://github.com/hellesvik-nordic/samples_for_nrf_connect_sdk/tree/main/bootloader_samples/updatable_bootloader/nsib_mcuboot_smp. Remember to use the flag -n 2 to ensure that the new image gets uploaded to mcuboot_secondary and not to mcuboot_primary.

    Let me know if this gets us any closer to achieving your goals

    Kind regards,
    Andreas

  • Thank you for your help ;-) 

    To do this, I had to update my SDK (from v2.3.0 to v2.5.0). With this config, I can now see the hash and "to confirm" the hash. Unfortunately, now (with this new SDK), I can no longer write to the secondary (using -n 2): it writes the file to the primary. For this command to work I need to do "CONFIG_SINGLE_APPLICATION_SLOT=n"...

    FYI, to successfully activate CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD and BOOT_SERIAL_IMG_GRP_IMAGE_STATE, I had to delete the "depends on !SINGLE_APPLICATION_SLOT" lines from the kconfig.serial_recovery file: I guess this is the only way to do it?

    Would it be possible for me to give you my code so you can see what's wrong?

  • Happy to help :) Been a learning process for me as well as serial recovery + NSIB is not the most common setup

    QuentinD said:
    To do this, I had to update my SDK (from v2.3.0 to v2.5.0). With this config, I can now see the hash and "to confirm" the hash. Unfortunately, now (with this new SDK), I can no longer write to the secondary (using -n 2): it writes the file to the primary. For this command to work I need to do "CONFIG_SINGLE_APPLICATION_SLOT=n"...

    My thoughts here are that in v2.3.0 there might've been a bug or a warning in your build that allowed you to both use CONFIG_SINGLE_APPLICATION_SLOT=y and to define a 64k Mcuboot secondary application slot in your pm static AND that you were allowed to use -n 2.

    When reflecting over this now it seems strange to me that we were allowed to configure both a secondary application partition and use CONFIG_SINGLE_APPLICATION_SLOT=y. If you still have the v2.3.0 revision that had the previous issue we investigated, could you check to see if there were a warning when building your previous app in v2.3.0 which had CONFIG_SINGLE_APPLICATION_SLOT=y and the 64k secondary partition? If not I'll add it to the to do list to look into, so no worries.

    QuentinD said:
    For this command to work I need to do "CONFIG_SINGLE_APPLICATION_SLOT=n"...

    I would imagine that you don't need to have CONFIG_SINGLE_APPLICATION_SLOT enabled if you have serial recovery as the application should go straight into mcuboot_primary_application slot and this should allow you to use -n 2 to upload the new MCUboot image fo mcuboot_secondary_application slot before transporting it to the s0/s1 slot. But I guess that causes issues for you in v2.5.0 since you need to remove the dependency you mention?

    Kind regards,
    Andreas

  • Sorry, I have already deleted v2.3.0 from my disk and am making code adaptations for the new SDK.

    If I set "CONFIG_SINGLE_APPLICATION_SLOT=n" (with a primary and a secondary of a different size), I have this issue:

    *** Booting nRF Connect SDK v2.5.0 ***
    [00:00:00.000,213] <inf> mcuboot: Starting bootloader
    [00:00:00.000,488] <wrn> mcuboot: Failed reading sectors; BOOT_MAX_IMG_SECTORS=128 - too small?
    [00:00:00.000,793] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.000,854] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.000,885] <inf> mcuboot: Boot source: none
    [00:00:00.000,976] <inf> mcuboot: Image index: 1, Swap type: none
    [00:00:00.001,037] <err> mcuboot: Image in the primary slot is not valid!
    [00:00:11.416,015] <err> mcuboot: Unable to find bootable image

    And here are the image lists before and after an update:

    C:\DocTA\Soft\TA-Smart-BT840P>mcumgr -c my_config image list
    Images:
     image=0 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 6f52cf5c50e6989c3c8779b66d1087432384f96033d28455281f51cbeb61cd94
     image=1 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 34552d5c69164df57ff025d9a79a695d3784ae72b1b730b5175a3a9b188e3755
    Split status: N/A (0)
    
    C:\DocTA\Soft\TA-Smart-BT840P>mcumgr -c my_config image upload Application\TA_Smart\zephyr\signed_by_mcuboot_and_b0_s1_image_update.bin -n 2
     59.00 KiB / 59.00 KiB [=======================================================================] 100.00% 2.19 KiB/s 26s
    Done
    
    C:\DocTA\Soft\TA-Smart-BT840P>mcumgr -c my_config image list
    Images:
     image=0 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 6f52cf5c50e6989c3c8779b66d1087432384f96033d28455281f51cbeb61cd94
     image=0 slot=1
        version: 2.0.1
        bootable: true
        flags:
        hash: 9782abe03da3012f15f3d0d5f7ddc6c66216471a90344591f7f7456785492cb4
     image=1 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 34552d5c69164df57ff025d9a79a695d3784ae72b1b730b5175a3a9b188e3755
     image=1 slot=1
        version: 2.0.1
        bootable: true
        flags:
        hash: 9782abe03da3012f15f3d0d5f7ddc6c66216471a90344591f7f7456785492cb4
    Split status: N/A (0)

    Basically, I activated CONFIG_SINGLE_APPLICATION_SLOT because I have a constraint in terms of memory space and therefore I do not want to have to duplicate the space used by my application.

Reply
  • Sorry, I have already deleted v2.3.0 from my disk and am making code adaptations for the new SDK.

    If I set "CONFIG_SINGLE_APPLICATION_SLOT=n" (with a primary and a secondary of a different size), I have this issue:

    *** Booting nRF Connect SDK v2.5.0 ***
    [00:00:00.000,213] <inf> mcuboot: Starting bootloader
    [00:00:00.000,488] <wrn> mcuboot: Failed reading sectors; BOOT_MAX_IMG_SECTORS=128 - too small?
    [00:00:00.000,793] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.000,854] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.000,885] <inf> mcuboot: Boot source: none
    [00:00:00.000,976] <inf> mcuboot: Image index: 1, Swap type: none
    [00:00:00.001,037] <err> mcuboot: Image in the primary slot is not valid!
    [00:00:11.416,015] <err> mcuboot: Unable to find bootable image

    And here are the image lists before and after an update:

    C:\DocTA\Soft\TA-Smart-BT840P>mcumgr -c my_config image list
    Images:
     image=0 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 6f52cf5c50e6989c3c8779b66d1087432384f96033d28455281f51cbeb61cd94
     image=1 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 34552d5c69164df57ff025d9a79a695d3784ae72b1b730b5175a3a9b188e3755
    Split status: N/A (0)
    
    C:\DocTA\Soft\TA-Smart-BT840P>mcumgr -c my_config image upload Application\TA_Smart\zephyr\signed_by_mcuboot_and_b0_s1_image_update.bin -n 2
     59.00 KiB / 59.00 KiB [=======================================================================] 100.00% 2.19 KiB/s 26s
    Done
    
    C:\DocTA\Soft\TA-Smart-BT840P>mcumgr -c my_config image list
    Images:
     image=0 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 6f52cf5c50e6989c3c8779b66d1087432384f96033d28455281f51cbeb61cd94
     image=0 slot=1
        version: 2.0.1
        bootable: true
        flags:
        hash: 9782abe03da3012f15f3d0d5f7ddc6c66216471a90344591f7f7456785492cb4
     image=1 slot=0
        version: 2.0.1
        bootable: true
        flags: active confirmed
        hash: 34552d5c69164df57ff025d9a79a695d3784ae72b1b730b5175a3a9b188e3755
     image=1 slot=1
        version: 2.0.1
        bootable: true
        flags:
        hash: 9782abe03da3012f15f3d0d5f7ddc6c66216471a90344591f7f7456785492cb4
    Split status: N/A (0)

    Basically, I activated CONFIG_SINGLE_APPLICATION_SLOT because I have a constraint in terms of memory space and therefore I do not want to have to duplicate the space used by my application.

Children
  • Hello,

    Were you able to investigate this problem ?

  • Hello,

    I remind you thant we have been stuck on this problem for 3 months and we still have not had a solution ! If you don't know how to solve the problem, can you ask to the developer team ?

    Thank you

  • Hi,

    Apologies for the long wait. It has been a period with unusual long period with unexpected amount of sickleave and extra load due to that.

    I spent yesterday afternoon creating a sample for you that showcases serial recovery + nsib in the same app. I hope the detailed steps and provided sample (at the bottom/attachments) is enough to get you to your goal

    Requirements:

    • nRF Connect SDK v2.5.0
    • nRF52840DK

    The application features

    • Serial recovery over UART
    • NSIB & updatable bootloader
    • A static_pm.yml where mcuboot primary and secondary has been defined with different non-equal sizes. The sizes has been chosen arbitrarily w.r.t ratios, and is only meant as a sample to showcase that this works with different sized partitions. You can customize them as you see fit given that you do it according to the static partitioning documentation.

    What you can do with this app

    • Enter serial recovery mode to directly upload the new application firmware to mcuboot primary application slot and overwrite the existing firmware. 
      • This means that you can modify the pm_static.yml to create an primary application slot that uses almost all of the available internal flash as long as there still is a secondary mcuboot partition that can fit the new Mcuboot update image for s0/s1
    • Update the bootloader by uploading the new firmware image to the smaller mcuboot secondary partition, confirm and reset

    You can update the bootloader, the application or both in any order you need as long as the pm_static.yml has not been changed in between the revisions you're going to update.

    If you wish to make modifications instead of using the prebuilt firmware in build_v1 and build_v2 do the following:

    1. Build and flash the project
    2. Increment the firmware version in child_image/mcuboot.conf
    3. Make changes to the application if your new firmware needs application changes
    4. And/or make change to $NRF_CONNECT_SDK/bootloader/mcuboot/boot/zephyr/main.c, for instance add a log
    5. Build, do not flash
    6. Follow the steps below to perform the updates

    Below I will give you the steps to recreate this using the prebuilt firmware.

    Updating the application:

    I've predefined my conn as acm0 following the steps in docs.zephyrproject.org/.../mcumgr.html

    1. Erase everything using
      1. nrfjprog -e
    2. Flash the firmware through cmd from the project folder
      1. west flash -d build_v1 --skip-rebuild --recover
    3. Connect to a serial terminal and observe that you boot from slot 0 and that the print output is what you've added to your application
    4. Disconnect from the serial terminal
    5. Hold DK BTN 1 and press the reset button to enter serial recovery mode
    6. Observe that LED1 is lighting
    7. In cmd list your images so you see what's present before the upload
      1. mcumgr -c acm0 image list
    8. Upload the new firmware
      1. mcumgr -c acm0 image upload build_v2/zephyr/app_update.bin -e -n0
    9.  List once more and observe that the new image is in image=0 slot =0 with flags "active confirmed", i.e it has overwritten the previous firmware which in my case ends with ...a55722 and instead uses _v2 which ends with ...a6238  
      1. mcumgr -c acm0 image list
    10. Connect to a serial terminal
    11. Reset the board
      1. nrfjprog --reset
    12. Observe that the DK boots with the "updated version" print

    Output after updating the application

    *** Booting nRF Connect SDK v2.5.0 ***
    Attempting to boot slot 0.
    
    Attempting to boot from address 0x9200.
    
    Verifying signature against key 0.
    
    Hash: 0x8f...3b
    
    Firmware signature verified.
    
    Firmware version 1
    
    Booting (0x9200).
    *** Booting nRF Connect SDK v2.5.0 ***
    APP This is the first version with serial recovery & different mcuboot partitions app print
    *** Booting nRF Connect SDK v2.5.0 ***
    Attempting to boot slot 0.
    
    Attempting to boot from address 0x9200.
    
    Verifying signature against key 0.
    
    Hash: 0x8f...3b
    
    Firmware signature verified.
    
    Firmware version 1
    
    Booting (0x9200).
    
    *** Booting nRF Connect SDK v2.5.0 ***
    Attempting to boot slot 0.
    
    Attempting to boot from address 0x9200.
    
    Verifying signature against key 0.
    
    Hash: 0x8f...3b
    
    Firmware signature verified.
    
    Firmware version 1
    
    Booting (0x9200).
    
    *** Booting nRF Connect SDK v2.5.0 ***
    APP This is the updated version with serial recovery & different mcuboot partitions app print

    MCUmgr input

    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.2.34
        bootable: true
        flags: active confirmed
        hash: d36b9f8cbe980ff4deb866f705c7739b4c18ce3de1d32f02aef6660522a55722
     image=1 slot=0
        version: 1.2.34
        bootable: true
        flags: active confirmed
        hash: d8148464f8c8a4c9951abd6fe518f5dffb26dc685c1e88c5d342352fe1b9dc8f
    Split status: N/A (0)
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image upload build_v2/zephyr/app_update.bin -e -n0
     43.06 KiB / 43.06 KiB [=================================================================================================================================================================] 100.00% 2.43 KiB/s 17s
    Done
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.2.34
        bootable: true
        flags: active confirmed
        hash: bc74e3d37c4889deb9370cf471102fb374fd89b9b014a722692ab1773fea6238
     image=1 slot=0
        version: 1.2.34
        bootable: true
        flags: active confirmed
        hash: d8148464f8c8a4c9951abd6fe518f5dffb26dc685c1e88c5d342352fe1b9dc8f
    Split status: N/A (0)
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>nrfjprog --reset
    Applying system reset.
    Run.
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>
    


    Updating the bootloader

    If you're starting here, then you need to do the first step of adding the conn to acm0. The output here are after I've updated the application in the previous steps

    1. Disconnect from the serial output
    2. Check the images
      1. mcumgr -c acm0 image list
    3. Upload the new bootloader image from build_v2. Since we're in _v1 are using s0 for our bootloader, we need to upload the s1-image.
      1. mcumgr -c acm0 image upload build_v2/zephyr/signed_by_mcuboot_and_b0_s1_image_update.bin -e -n2
    4. List the images. Observe that the new bootloader image is in the slot corresponding to mcuboot_secondary application
      1. mcumgr -c acm0 image list
    5. Confirm the new bootloader and observe that the bin in image 0 slot 1 is now flagged "pending permanent" and is ready for update
      1. mcumgr -c acm0 image confirm 
    6. Connect to a serial terminal
    7. Restart the device and wait a while until the update has gone through
      1. nrfjprog --reset
    8. Reset the device once more and observe that it now boots from s1 

    Output after updating the bootloader:

    *** Booting nRF Connect SDK v2.5.0 ***
    Attempting to boot slot 0.
    
    Attempting to boot from address 0x9200.
    
    Verifying signature against key 0.
    
    Hash: 0x8f...3b
    
    Firmware signature verified.
    
    Firmware version 1
    
    Booting (0x9200).
    
    *** Booting nRF Connect SDK v2.5.0 ***
    APP This is the updated version with serial recovery & different mcuboot partitions app print
    *** Booting nRF Connect SDK v2.5.0 ***
    Attempting to boot slot 1.
    
    Attempting to boot from address 0x16200.
    
    Verifying signature against key 0.
    
    Hash: 0x8f...3b
    
    Firmware signature verified.
    
    Firmware version 2
    
    Setting monotonic counter (version: 2, slot: 1)
    
    Booting (0x16200).
    
    *** Booting nRF Connect SDK v2.5.0 ***
    APP This is the updated version with serial recovery & different mcuboot partitions app print
    
    

    Input in cmd:

    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.2.3.4
        bootable: true
        flags: active confirmed
        hash: bc74e3d37c4889deb9370cf471102fb374fd89b9b014a722692ab1773fea6238
    Split status: N/A (0)
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image upload build_v2/zephyr/signed_by_mcuboot_and_b0_s1_image_update.bin -e -n2
     41.44 KiB / 41.44 KiB [================================================================================================================================================================] 100.00% 2.56 KiB/s 16s
    Done
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.2.3.4
        bootable: true
        flags: active confirmed
        hash: bc74e3d37c4889deb9370cf471102fb374fd89b9b014a722692ab1773fea6238
     image=0 slot=1
        version: 1.2.3.4
        bootable: true
        flags:
        hash: 6f79a50c6399a65cca5d86b6eb1b5009340bbd252b6f770b449ef63b22e3a241
    Split status: N/A (0)
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>mcumgr -c acm0 image confirm 6f79a50c6399a65cca5d86b6eb1b5009340bbd252b6f770b449ef63b22e3a241
    Images:
     image=0 slot=0
        version: 1.2.3.4
        bootable: true
        flags: active confirmed
        hash: bc74e3d37c4889deb9370cf471102fb374fd89b9b014a722692ab1773fea6238
     image=0 slot=1
        version: 1.2.3.4
        bootable: true
        flags: pending permanent
        hash: 6f79a50c6399a65cca5d86b6eb1b5009340bbd252b6f770b449ef63b22e3a241
    Split status: N/A (0)
    
    C:\Nordic\SDKs\ncs\my_projects\samples_for_NCS\DFU\serial_recover_nsib>nrfjprog --reset
    Applying system reset.
    Run.

    0652.serial_recover_uart_nsib.zip

    Kind regards, 
    Andreas

  • Thank you very much   for your long and comprehensive response. Now it works!
    In summary, the problem was therefore a configuration problem.

Related