How to add BLE DFU to a NCS firmware application?

Dear Nordic experts,
 
Considering a Bluetooth Mesh application based on NCS 1.7.1 and running on an nRF52832:
What steps need to be done to add DFU over Bluetooth LE? Is there a user guide somewhere?  
 
Although there's quite some information on Bootloaders and Device Firmware Updates available, I'm still lacking the bigger picture of what exactly needs to be done.
 
Bootloaders:
If I understand it correctly, (and please correct me if I'm wrong) MCUboot is required for DFU over BLE.

If MCUboot is used, is the nRF Secure Immutable Bootloader (NSIB) really needed? Or would MCUboot alone be sufficient?
Available flash space is already getting low, and considering that the device is not connected to the internet (but only controlled through our own smartphone app), the risk of getting compromised is not a concern. Hence the idea to skip NSIB completely in favor of some additional Flash space. Under that circumstance, what bootloader(s) would you choose?

Any advise is very much welcome,
Thank you,
Michael.

 
 

  • Hi BlueMike, 
    I assume you are looking for DFU over BLE for individual node not "Mesh DFU" ? 

    If it's the case you are correct that you would need MCUBoot and the application firmware to receive image via BLE . Please have a look at this guide

    It's possible to not include the NSIB but that means you will not able to update the MCUBoot which can be an issue in the long run. 
    Also please take into account that it's in general not possible to do "single bank" update meaning the new image is always received on an 2nd slot. You would need a flash space that is 2x the size of the application. 

  • Hi Hung Bui,

    Thanks for your help. Yes, it's about DFU over BLE. So let's use both, NSIB and MCUBoot then...

    I've followed the steps from the link. Beside that, I've added a configuration file for mcuboot to CMakeLists.txt:

    if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")
        list(APPEND mcuboot_OVERLAY_CONFIG
          "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf"
          )
    endif()


    And then created the matching file mcuboot.conf in the project directory with the following content:

    CONFIG_BOOT_SIGNATURE_KEY_FILE="/home/mike/nrf-dev/projects/utterly_awesome_project/signing_keys/utterly_awesome_project_key.pem"
    CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=y


    Build now fails because s1_image.hex isn't found. The error message is:

    ninja: error: 'zephyr/s1_image.hex', needed by 'zephyr/nrf/subsys/bootloader/generated/s1_image_firmware.signature', missing and no known rule to make it
    FATAL ERROR: command exited with status 1: /home/mike/.local/bin/cmake --build /home/mike/nrf-dev/projects/utterly_awesome_project/build_debug


    Question now is, how do you get the s1_image.hex? Shouldn't that be built automatically?

    About Partition Manager:

    Beside that, another thing I'm uncertain about is the Partition Manager. According to the docs, it's necessary to include it, so I've added these lines to Cmakelists.txt:

    set(PM_STATIC_YML_FILE
    	${CMAKE_CURRENT_SOURCE_DIR}/boards/pm_static_${BOARD}.yml
    )


    And copied (and renamed) pm_static{Board}.yml from the peripheral_lbs example.

    Is this all that needs to be done to setup Partition Manager? Now when building a few messages like this one show up:

    Partition 'mcuboot_primary_app' is not included in the dynamic resolving since it is statically defined.

    The "dynamic resolving" at the above message sounds as if partition manager is able configure the partitions itself. Is that the case? Can the partition manager configuration be skipped?

    I'm still missing the bigger picture, so any clarification is welcome,
    Thanke you,
    Michael.

  • Hi Michael, 

    I assume you want to test only the MCUBoot, not with the immutable bootloader ? 
    If it's the case you just need to follow what described in the guide. 
    Please make sure you don't have something like this CONFIG_SECURE_BOOT=y in your prj.conf or in the script when you call west. 
    Note that if you create an overlay mcuboot.conf you would need to put it in the child_image folder of your application project folder. 
    You shouldn't see any s1_image.hex because the S0 should not be included so there shouldn't be S1. 

    Regarding Partition Manager, it will be generated dynamically and automatically in your build folder. I would suggest to test with that first before you move on and add the pm_static.yml to your application (As far as I know you just need to leave it in the application folder without changing configuration, see here.

  • Hi Hung Bui,

    Again, thanks for your help.

    I assume you want to test only the MCUBoot, not with the immutable bootloader?

    THB, I'd prefer to test with both, immutable bootloader and MCUBoot.

    Good to know that partition manager is generated automatically. However, when adding DFU to my project by just following the examples from the link you've provided, linking fails because FLASH seems to overflow. The output is:

    [254/254] Linking C executable zephyr/zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       32864 B        48 KB     66.86%
                SRAM:       23680 B        64 KB     36.13%
            IDT_LIST:          0 GB         2 KB      0.00%
    [289/304] Linking C executable zephyr/zephyr_prebuilt.elf
    FAILED: zephyr/zephyr_prebuilt.elf zephyr/zephyr_prebuilt.map /*exact command removed for simplicity...*/
    
    /home/mike/nrf-dev/tools/gnuarmemb/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.bfd: zephyr/zephyr_prebuilt.elf section `text' will not fit in region `FLASH'
    /home/mike/nrf-dev/tools/gnuarmemb/gcc-arm-none-eabi-9-2019-q4-major/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.bfd: region `FLASH' overflowed by 136676 bytes
    collect2: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.
    FATAL ERROR: command exited with status 1: /home/mike/.local/bin/cmake --build /home/mike/nrf-dev/projects/awesome_project/build_debug
    The terminal process terminated with exit code: 1.
    


    Which lead to the partition manager configuration... Question now is, what's wrong, and how to fix it?

  • Hi Mike, 
    How large is your application in flash size ? 
    I can see in the linking log the FLASH size is 32864B, but in the error log it says `FLASH' overflowed by 136676 bytes. It's quite strange. Could you check the generated partition file in $BUILD_DIR/partitions.yml 

    Have you tried to test with one of our example ? for example the peripheral_hr ? 

Related