Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DFU update from nRF5 SDK to nRF Connect SDK?

Hi there,

We currently have ~500 nRF52832 devices running nRF5 SDK (bootloader, S132, application). These devices are updated using the nRF5 SDK Secure Bootloader UART DFU.

I have rewritten the application firmware using NCS (nRF Connect SDK) and I would like to update these devices to NCS using the nRF5 SDK Secure Bootloader UART DFU. 

I followed some instructions included in a similar question, however I have had issues:

------------------------------------------------------------------

I am testing with Nordic example projects as much as possible to help customer support replicate any issues.

I am flashing the PCA10040 (nRF52 DK) with the 'examples/dfu/secure_bootloader/pca10040_uart_debug' application included in the latest nRF_SDK_17.0.2. This application allows me to enter UART DFU bootloader. I can test writing the included test application 'examples/dfu/secure_dfu_test_images/uart/nrf52832/blinky_mbr.zip'. This process works fine as expected (nRF5 SDK -> nRF5 SDK).

To begin testing from nRF5 SDK -> NCS:

1. I again flash the same secure_bootloader DFU example application to enter DFU mode.

2. I then follow the instructions linked here to flash the Zephyr blinky.zip application (I also add the --key-file parameter to sign it).

west build -b nrf52dk_nrf52832 zephyr/samples/basic/blinky
nrfutil pkg generate --hw-version 52 --sd-req=0x00 --application build/zephyr/zephyr.hex --application-version 1 blinky.zip --key-file private.key
nrfutil dfu serial -pkg blinky.zip -p /dev/ttyACM0

However, after the DFU seems to complete, the application does not boot (LEDs are not blinking). You can find the device DFU logs here.

I can step through the nRF5 bootloader and see that a hardfault is triggered when the bootloader eventually attempts to jump to the new application.

These are the local variable values in nrf_bootloader_app_start_final.c: jump_to_addr()

Name Value Location
current_isr_num 0000 0000 2000 FF84
new_msp 1136 1B36 2000 FF80
reset_handler DB00 42B5 2000 FF7C
vector_table_address 0000 1000 2000 FF64

I suspect it is caused by the reset_handler value? This does not seem to be a valid address.

Some questions/points:

  1. Flashing the Zephyr blinky example directly works fine as you would expect.
  2. I also added the small change to the nRF5 bootloader that checks the SD magic number, as suggested by mtsunstrum.
  3. As there is no private.key provided with the secure_bootloader DFU example applications I use my own dfu_public_key.c and private.key files to sign the bootloader and NCS Blinky application.
  4. The instructions in the link provided are only included in the nRF52840 Dongle board page, they are not included in the nRF52 DK board page. Are these instructions not compatible with nRF52 DK? I see the nRF52840 comes with the open bootloader installed, when I am using secure bootloader?
Parents
  • Hi Sean, 

    As the log (<debug> app: Running nrf_bootloader_app_start with address: 0x00001000) indicated, the app start address is 0x1000. Adding CONFIG_FLASH_LOAD_OFFSET=0x1000 to prj.conf should fix the issue. 

    Regards,
    Amanda 

  • Thanks for your reply  you beat me too it. I was in the middle of posting:

    ----------------------------------

    I have made some progress on this..

    I was able to update and run the Zephyr blinky application (no MCUboot) using the instructions above, however I needed to change the Zephyr application FLASH_LOAD_OFFSET Kconfig option from 0x0 to 0x1000. From what I've understood so far, this is to place the application after the MBR region in flash (which resides at 0x0).

    I have also tested that I can re-enter the bootloader from the new application by setting the GREGRET register and then resetting the device. This allows me to continue triggering new DFU updates from the new Zephyr based application.

    I am currently attempting to get the MCUboot + Application updated and running.

    • Do you know if it is possible to have the MCUboot updated to become the 1st stage bootloader? Or can it only become the 2nd stage bootloader (nRF5 SDK Bootloader -> MCUboot -> Application). Could I write the MCUboot + Application to offset 0x0 (therefore overwriting the MBR)? I understand this process would prevent from recovering from a failed update.
  • Hi Sean, 

    FARLY7 said:
    Do you know if it is possible to have the MCUboot updated to become the 1st stage bootloader?

    After updating with MCUboot + Application, the nRF5 bootloader will be replaced with mcuboot and you will have the MBR as the first entry point. MCUboot can be used as a 1st stage bootloader and usually is if you use the 52 series. 

     

    FARLY7 said:
    Could I write the MCUboot + Application to offset 0x0 (therefore overwriting the MBR)?

    No,  it won't be possible. The mbr protects itself with BPROT/ACL and any unexpected resets will obviously brick the device

     

    -Amanda 

  • Hi Amanda,

    After updating with MCUboot + Application, the nRF5 bootloader will be replaced with mcuboot and you will have the MBR as the first entry point. MCUboot can be used as a 1st stage bootloader and usually is if you use the 52 series. 

    I cannot get an MCUboot + Application to boot successfully. Do you have a list of steps to get this working and any additional KConfig options required?

    1. I enable the CONFIG_BOOTLOADER_MCUBOOT option, and the linker options are shown as:

    FLASH_LOAD_OFFSET 0xC000 (Unconfigurable, set from the .dts it seems)
    FLASH_LOAD_SIZE 0x32000 (Unconfigurable, set from the .dts it seems)
    ROM_START_OFFSET 0x1000

    2. I then create a DFU package from the zephyr/merged.hex file and proceed as before, passing the merged.hex as an --application parameter.

    3. When I perform the DFU update, I have the same error as in the original post, where the reset_vector address is all wrong and the device hardfaults.

    Do I need to pass the MCUboot hex as a separate --bootloader parameter? nrfutil does not allow the combination of App + BL, these must be separate packages. I am unsure which .hex file is MCUboot, and in what order to delivery the updates.

    Also, how does the nRF5 bootloader get 'replaced' by MCUboot? I don't understand this. If the Application+MCUboot is being flashed as an Application in nRF5 bootloader terms, then the bootloader is untouched. The device still boots up, checks the MBR, and then the nRF5 bootloader points it to the start of the 'Application' which is the MCUboot? Is my understanding wrong? 

    Thanks a lot for your help so far!

  • Hi Amanda,

    Do you have any information on how it is possible to replace the nRF5 Bootloader with MCUBoot from NCS?

    Please see my other reply on how I have unsuccessfully attempted this already.

    Thanks,

    Sean

Reply Children
  • Hi Sean, 

    Sorry for the delay.

    You can use partition manager to locate mcuboot. The memory layout could be defined in pm_static.yml as
     

    FOTA from nRF5 SDK to NCSv1.6.1 over uart test

    1033.dfu_nRF5_NCS_over_uart_0928.zip

    Some quick notes about the test:

    1. This test updats MCUboot and the zephyr application image in one go by calling it a Softdevice+bootloader (SoftDevice and bootloader) update. This to be able to overwrite the softdevice with the zephyr app. However, it did require some minor modifications to the existing bootloader to make it accept zephyr application as a Softdevice image.Use dfu_nRF5_NCS\nRF5_SDK_17.0.2_d674dde to build and run the bootloader.
    2. There are several *_pm_static.yml for nRF52832/52840 ble/USB/UART. Rename the "pm_static.yml" to pm_static.yml for your target.
    3. 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.Disabled mcuboot flash protection is as the config under
    4. Modify the OVERLAY_CONFIG path in build_blinky.bat and run the script to build NCS_blinky_over_uart project.
    5. The mcuboot image is zephyr.hex under build\mcuboot\zephyr and you can use app_update.bin to generate the updated package.
    6. After updating withNCS_blinky_over_uart, you can use mcumgr to update via DFU. See  this tutorial device-firmware-update-dfu-with-mcuboot-bootloader and this thread. If you update with NCS_peripheral_uart, you can refer to Bluetooth: Peripheral UART to test.

    FARLY7 said:
    how does the nRF5 bootloader get 'replaced' by MCUboot?

    It's not updated as an application+bootloader, but rather Softdevice + bootloader. SoftDevice and bootloader

    -Amanda

  • Hi Amanda,

    Thanks for all this information. I have been working on this for the past 1-2 weeks and I can now successfully replace the nRF5 secure_bootloader with MCUBoot and Zephyr application. I have only tested this over serial so far, I will try and test over BLE soon.

    My update process has been:

    1. (Original app and secure_bootloader already exist on the device).
    2. Update secure_bootloader with secure_bootloader_patched by issuing a BL DFU update.
    3. Update the device with my Zephyr app + MCUboot by issuing an SD + BL DFU update. 

    I have one question/possible issue. After performing a DFU update using secure_bootloader to replace it with Zephyr app + MCUBoot, when I use mcumgr to list the images on the device, I get:

    Images:
     image=0 slot=0
        version: 0.0.0.0
        bootable: false
        flags: 
        hash: Unavailable
    Split status: N/A (0)

    Compared to when I flash an application directly using 'west flash' 

    Images:
    image=0 slot=0
        version: 0.0.0
        bootable: true
        flags: active confirmed
        hash: 38771b4b3c567a292ab579e7e0f8709857c241ef4d890bde267637a60cc74279
    Split status: N/A (0)

    Do you know what is causing these differences (version number missing a .0, bootable=false, flags empty, hash unavailable)?

    • The application runs fine, even between resets (so is 'booting').
    • I am using the nRF52832_UART_pm_static.yml file included in the NCS_blinky project you shared.
    • Updating the app again from the app_update.bin does not change the info, and still works fine.
    • The app doesn't call any 'image ok' type API after booting to signal that the image is ok to continue running.

    Thanks,

    Sean

  • Hi Amanda,

    Just adding to my reply I sent a few days ago.. as I was successful in updating App + MCUBoot over UART I have now began testing the same process over BLE.

    Unfortunately, when I attempt to update over BLE I am getting an INSUFFICIENT RESOURCES error from the device. From reading online this means there is not enough space on the device for the update?

    1. I am using the nRF52832_XXAA (512KB flash)
    2. I tried flashing the smaller (peripheral-only) S112 SoftDevice.
    3. I tried updating with the NCS_Blinky application and not my own, so it is much smaller.
    4. There is a line in the uart_log_recovery.conf file 'CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x18000'. I don't understand why the partition size is set to 98KB when the MCUBoot compiles down to 37KB?
    5. The output from the NCS_blinky build shows the MCUBoot region size as 112KB, could this be reserving unused memory in the update package that is making the image seem larger and unable to fit?

    [258/258] Linking C executable zephyr/zephyr.elf
    Memory region Used Size Region Size %age Used
    FLASH:        37476 B   112 KB      32.68%
    SRAM:         25952 B   64 KB       39.60%
    IDT_LIST:     0 GB      2 KB        0.00%
    [147/165] Linking C executable zephyr/zephyr_prebuilt.elf

    [154/165] Linking C executable zephyr/zephyr.elf
    Memory region Used Size Region Size %age Used
    FLASH:        16636 B   243200 B    6.84%
    SRAM:         5376 B    64 KB       8.20%
    IDT_LIST:     0 GB      2 KB        0.00%
    [165/165] Generating zephyr/merged.hex

    Since the NCS_Blinky + MCUBoot application is pretty small, I don't think it is a resources issue? Could it be something to do with the flash layout defined in the pm_static.yml file? I am using the nRF52832_UART_pm_static.yml file included in your NCS_blinky folder. There was not an equivalent BLE file for the nRF52832, only the nRF52840. Was there a reason for this? Would providing a 'BLE version' of the pm_static.yml for the nRF52832 be the solution?

    Thanks again for your help so far.

  • Hi, 

    FARLY7 said:
    Do you know what is causing these differences (version number missing a .0, bootable=false, flags empty, hash unavailable)?

    I'd recommend asking questions regarding the mcumgr in their slack channel, as described in the repos readme.md:

    We have little to no knowledge about this in tech support.

    FARLY7 said:
    There was not an equivalent BLE file for the nRF52832, only the nRF52840. Was there a reason for this?

     If one were to modify MCUBoot’s settings then the size of MCUBoot will change.  In case the size of MCUBoot is larger than the allocated partition size, the value of 0x18000 would have to be increased.  Similarly, if MCUBoot’s size shrinks due to different build options, then the value of 0x18000 can be reduced.

    FARLY7 said:
    Would providing a 'BLE version' of the pm_static.yml for the nRF52832 be the solution?

    You can use the nRF52832_UART_pm_static.yml under the NCS_blinky folder, but you have to modify the FLASH_START of the nRF5 bootloader to 0x64000 the same as the mcuboot address. Here is my test file. dfu_nRF5_NCS_over_DFU_1102.zip I have added pca10040_s112_ble and pca10040_s112_ble_debug under secure_bootloader with FLASH_START at 0x64000 and updated with NCS_blinky and NCS_peripheral_uart generated by nRF52832_UART_pm_static.yml without issue.  

    -Amanda

  • You can use the nRF52832_UART_pm_static.yml under the NCS_blinky folder, but you have to modify the FLASH_START of the nRF5 bootloader to 0x64000 the same as the mcuboot address. Here is my test file. dfu_nRF5_NCS_over_DFU_1102.zip I have added pca10040_s112_ble and pca10040_s112_ble_debug under secure_bootloader with FLASH_START at 0x64000 and updated with NCS_blinky and NCS_peripheral_uart generated by nRF52832_UART_pm_static.yml without issue. 

    Ok thank you, I will test your project tomorrow and let you know. I have two questions:

    1. From the .zip you shared a few weeks ago, I checked the file 'pca10040_s132_ble/armgcc/secure_bootloader_gcc_nrf52.ld' and the bootloader address is set to FLASH (rx) : ORIGIN = 0x78000, LENGTH = 0x6000. The pm_static.yml file from the NCS_Blinky project has set the MCUBoot address to 0x64000. However, this configuration works fine when I was testing with the UART DFU method. Do you know why it works and why the BLE DFU is different and requires this change?

    2. In my production devices, the bootloader begins at 0x76000 and has a length of 0x8000 (32KB). The MCUBoot bootloader compiles a 'Used size' of just less than 32KB, however, the 'Region size' is 48KB. In the scenario where the MCUBoot bootloader does not fit into this area, is it possible to first update the secure_bootloader to move it slightly and increase its flash allocation so MCUBoot can fit in the next update?

    Thanks,

    Sean

Related