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

  • Hi,

    Apologies for the delayed response time

    QuentinD said:
    If I do the upload command without the "-n 2", it overwrites my application (mcuboot_primary). So that's why I put "-n 2" so that the application is not deleted and that it puts the bootloader file in the only partition that I have access to (mcuboot_secondary).

    I believe that something might be wrong with your partitioning which causes the update image for the bootloader to be uploaded in the primary application slot if you don't use -n 2. This is what your partitioning should look like if you have a firmware with an updatable application and updatable bootloader in NCS (sample found here). Here you can see that the there is a s0 and s1 partition which is intended for the updatable bootloader. 

    QuentinD said:
    My partitions:

    I see that you state that you have them here in this reply, but could you also navigate to the build folder and enter ninja partition_manager report? It should look something similar to this.


      flash_primary (0x100000 - 1024kB):
    +--------------------------------------------------+
    +---0x0: b0_container (0x9000 - 36kB)--------------+
    | 0x0: b0 (0x8000 - 32kB)                          |
    | 0x8000: provision (0x1000 - 4kB)                 |
    +---0x9000: s0 (0xc200 - 48kB)---------------------+
    | 0x9000: s0_pad (0x200 - 512B)                    |
    +---0x9200: s0_image (0xc000 - 48kB)---------------+
    | 0x9200: mcuboot (0xc000 - 48kB)                  |
    +--------------------------------------------------+
    | 0x15200: EMPTY_0 (0xe00 - 3kB)                   |
    +---0x16000: s1 (0xc200 - 48kB)--------------------+
    | 0x16000: s1_pad (0x200 - 512B)                   |
    | 0x16200: s1_image (0xc000 - 48kB)                |
    +--------------------------------------------------+
    | 0x22200: EMPTY_1 (0xe00 - 3kB)                   |
    +---0x23000: mcuboot_primary (0x6e000 - 440kB)-----+
    | 0x23000: mcuboot_pad (0x200 - 512B)              |
    +---0x23200: app_image (0x6de00 - 439kB)-----------+
    +---0x23200: mcuboot_primary_app (0x6de00 - 439kB)-+
    | 0x23200: app (0x6de00 - 439kB)                   |
    +--------------------------------------------------+
    | 0x91000: mcuboot_secondary (0x6e000 - 440kB)     |
    | 0xff000: EMPTY_2 (0x1000 - 4kB)                  |
    +--------------------------------------------------+
    
      sram_primary (0x40000 - 256kB):
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x40000 - 256kB) |
    +--------------------------------------------+

    When uploading the new image without n -2 you can see that the new image is not added to the primary application slot, i.e slot 0. It is located in a secondary slot before you confirm and reset. We would expect something similar on your end

    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>nrfjprog --com
    1050255060    COM6    VCOM0
    1050255060    COM7    VCOM1
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>mcumgr conn add acm0 type="serial" connstring="dev=COM6,baud=115200,mtu=512"
    Connection profile acm0 successfully added
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.1.1
        bootable: true
        flags: active confirmed
        hash: 05dc5159151571bafa5e11309367b9ac9ede8d6dec708fafab01a2cd4b6fe90f
    Split status: N/A (0)
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>mcumgr -c acm0 image upload build_1/zephyr/signed_by_mcuboot_and_b0_s1_image_update.bin
     35.73 KiB / 35.73 KiB [============================================================================================================================================================================================] 100.00% 2.33 KiB/s 15s
    Done
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.1.1
        bootable: true
        flags: active confirmed
        hash: 05dc5159151571bafa5e11309367b9ac9ede8d6dec708fafab01a2cd4b6fe90f
     image=0 slot=1
        version: 1.1.1
        bootable: true
        flags:
        hash: 3f99475cc81181793e4dbc2f8ba97669270978c8bb318741aa755c118baf9ff7
    Split status: N/A (0)
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>mcumgr -c acm0 image confirm 3f99475cc81181793e4dbc2f8ba97669270978c8bb318741aa755c118baf9ff7
    Images:
     image=0 slot=0
        version: 1.1.1
        bootable: true
        flags: active confirmed
        hash: 05dc5159151571bafa5e11309367b9ac9ede8d6dec708fafab01a2cd4b6fe90f
     image=0 slot=1
        version: 1.1.1
        bootable: true
        flags: pending permanent
        hash: 3f99475cc81181793e4dbc2f8ba97669270978c8bb318741aa755c118baf9ff7
    Split status: N/A (0)
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>nrfjprog --reset
    Applying system reset.
    Run.
    
    C:\Nordic\samples_for_nrf_connect_sdk\bootloader_samples\updatable_bootloader\nsib_mcuboot_smp>mcumgr -c acm0 image list
    Images:
     image=0 slot=0
        version: 1.1.1
        bootable: true
        flags: active confirmed
        hash: 05dc5159151571bafa5e11309367b9ac9ede8d6dec708fafab01a2cd4b6fe90f
     image=0 slot=1
        version: 1.1.1
        bootable: true
        flags:
        hash: fe6a5916233647d89cda6d245e41b3b4cb30399cf12fb46a2f073786bff6be05
    Split status: N/A (0)

    Kind regards,
    Andreas

  • Hi,

    The main difference I see is for "mcuboot_secondary". I see you haven't configured "CONFIG_SINGLE_APPLICATION_SLOT=y". I had to provide 0x10000 bytes for mcuboot_secondary in order not to have compilation errors but I would like not to have mcuboot_secondary if possible (or as small as possible).

    Could you try by enabling "CONFIG_SINGLE_APPLICATION_SLOT=y"? (I think my problem comes from this option)

    Here are my partitions:

  • Hello,

    Were you able to test with the "CONFIG_SINGLE_APPLICATION_SLOT=y" option?

  • Hi,

    QuentinD said:
    Were you able to test with the "CONFIG_SINGLE_APPLICATION_SLOT=y" option?

    I was just about to write you a reply when I saw this one came in! First of I'm sorry it took a week to get back to you (yet again)

    QuentinD said:
    I see you haven't configured "CONFIG_SINGLE_APPLICATION_SLOT=y"

    Secondly, yes I did and I see that I had misunderstood that aspect of your project

    So as I had explained this earlier

    AHaug said:
     Regarding MCUboot images. Correct me if I am wrong, but I suspect that you may believe that MCUboot updates work the same as "regular" application updates. It's not quite the same, as the new MCUboot image is uploaded to mcuboot_secondary before it is swapped to s1. Then NSIB reads a flag stating which slot it should run MCUBOOT from, i.e s0 or s1 depending on which is the latest update, and then MCUboot starts the application.

    Which is still valid and this is the reason for why you need to have a secondary MCUboot application slot. The new MCUboot image has to be temporarily stored in MCuboot secondary before it is placed in s0 or s1 depending on the file you've uploaded. The implementation is made in such a way that that MCUboot only knows about its own slots, and since we're following the protocol we're sending things by default to MCUboot i.e the secondary slot.

    MCUboot also assumes that the primary and secondary slot is equally large, with the exception of single bank serial recovery DFU. In this case, and with the addition that you have an uppdatable bootloader, MCUboot only expects the secondary slot to be atleast as large as s0 and s1 such that you can upload the new Mcuboot/bootloader image. In your case your s0 s1 is ~64kB, meaning you should be able to set the secondary to the same size (which you've shown in the partition in your previous reply)

    AHaug said:
    If I do the upload command without the "-n 2", it overwrites my application (mcuboot_primary). So that's why I put "-n 2" so that the application is not deleted and that it puts the bootloader file in the only partition that I have access to (mcuboot_secondary).

    This also makes perfect sense, and I see I've mislead you somewhat in my prior reply. As I had only tested with dual bank, the flags were not an issue and I could upload the new bootloader image without using flags since the partitioning followed the default scheme. When uploading without the -n flag, mcumgr upload image defaults to -n 1. In your case, you will have to use a 

    github.com/.../Kconfig.serial_recovery

    Do also note the tips in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/device_mgmt/mcumgr.html#image-management regarding -n and -e

    Let me know if that clarifies things for you 

    Kind regards,
    Andreas

  • Hi,

    Thanks again for your explanation but I already know all that.

    The problem I have is that I have to load the update file in the secondary but then I don't know how to make it load in s0 or s1? (as you said, I set the secondary large enough to hold the new MCUboot)
    So I can load the new MCUboot in the secondary but how do I update the bootloader? (I don't see the hash of the MCUboot I uploaded with the image list command)

Related