This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Custom transport layer for dfu in app and dual bank settings issue

I'm currently using a HostController with pregiven communication protocol for transfering data to the NRF52840 (over uart). The NRF is flashed with the SD140 and I'm using the SDK V16.0. The communication protocol of the host is already implemented in the NRF app. As I have to update only the application I want to implement the transport layer for dfu by myself using the dual bank update procedure. I figured out the borders of bank1 and succesfully transfere and store the new application data in bank1 (crosschecked the flash by nrfjprog -readcode). I'm receiving the most important settings (size, app_crc,...) for the new application by the host (they are generated by nrfutils, then extracted ...) which then are written and stored in the settings for bank1 (see code below). But for storing the settings I had to modify the nrf_dfu_settings.c (static bool settings_forbidden_parts_equal_to_backup(uint8_t * p_compare_addr)) to return always true like in this thread. RTT Log tells me that storing the settings worked then.

For the bootloader I took an example and reduced it by the transport layer.

BL main code:

Lauching the bootloader after receiving and storing the new application also works.

But then the bootloader does not detect the new app in bank1 and hangs in dfu mode (see RTT output).

Is it a problem in the settings storage or a non properly working bootloader?

Bootloader RTT output:

[00000000] <info> app: Inside main

[00000000] <debug> app: In nrf_bootloader_init

[00000000] <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...

[00000000] <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.

[00000000] <debug> nrf_dfu_settings: Using settings page.

[00000000] <debug> nrf_dfu_settings: Copying forbidden parts from backup page.

[00000000] <debug> nrf_dfu_settings: Writing settings...

[00000000] <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 0

[00000000] <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20003AEC, len=896 bytes), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0

[00000000] <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.

[00000000] <debug> nrf_dfu_settings: Writing settings...

[00000000] <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x20003E6C, len=896 bytes), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0

[00000000] <info> app: Postvalidating update after reset.

[00000000] <debug> nrf_dfu_settings: Writing settings...

[00000000] <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20003AEC, len=896 bytes), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0

[00000000] <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.

[00000000] <debug> nrf_dfu_settings: Writing settings...

[00000000] <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0

[00000000] <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x20003E6C, len=896 bytes), queue usage: 1

[00000000] <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0

[00000000] <debug> app: Enter nrf_bootloader_fw_activate

[00000000] <info> app: No firmware to activate.

[00000000] <debug> app: App is valid

[00000000] <debug> app: DFU mode requested via GPREGRET.

[00000000] <info> nrf_bootloader_wdt: WDT is not enabled

[00000000] <debug> app: in weak nrf_dfu_init_user

[00000000] <debug> app: timer_stop (0x2000005C)

[00000000] <debug> app: timer_activate (0x2000005C)

[00000000] <info> app: Entering DFU mode.

[00000000] <debug> app: Initializing transports (found: 0)

[00000000] <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.

[00000000] <debug> app: Enter main loop

[03932160] <debug> app: timer_stop (0x2000005C)

[03932160] <debug> app: timer_fire (0x2000005C)

[03932161] <info> app: Inactivity timeout.

[03932161] <debug> app: Resetting bootloader.

[03932161] <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.

[03932164] <debug> nrf_dfu_settings: Destination settings are identical

  • Hi Massimo, 


    Have you invalide Bank 0 and valid Bank 1 before you switch to bootloader to swap the image ?

    We do that in postvalidate_app() function. 

    We have an example of doing background DFU on UART which is quite similar to what you are trying to do. It's for SDK v15.3 but should be a good source of reference for your application I think. Please have a look here. The example named nrf_sdk_15.3.0_background_dfu_3.zip

  • Hello Hung,

    thank you for your answer. I followed the suggestion of the mentioned thread and instead of invalidating banks by myself, I called nrf_dfu_validation_post_data_execute(bank1_start, app_size);.

    Then I had to enabled the ram buffering (int sdk_config.h) and replaced the cc310_backend_hash.c with Vidar's one of the dfu example.

    But now I get a non matching hash:

    [1;32m<debug> nrf_dfu_validation: Hash verification. start address: 0x55000, size: 0x29AB4
    [1;33m<warning> nrf_dfu_validation: Hash verification failed.
    [1;32m<debug> nrf_dfu_validation: Expected FW hash:
    [1;32m<debug> nrf_dfu_validation:  08 23 00 00 08 19 00 00|.#......
    [1;32m<debug> nrf_dfu_validation:  08 0F 00 00 08 05 00 00|........
    [1;32m<debug> nrf_dfu_validation:  07 FB 00 00 07 F1 00 00|........
    [1;32m<debug> nrf_dfu_validation:  07 E7 00 00 07 DD 00 00|........
    [1;32m<debug> nrf_dfu_validation: Actual FW hash:
    [1;32m<debug> nrf_dfu_validation:  71 E0 6D D1 E1 12 E9 72|q.m....
    [1;32m<debug> nrf_dfu_validation:  ED 40 43 D1 80 6C A6 3E|[email protected].>
    [1;32m<debug> nrf_dfu_validation:  3A 12 CB 30 19 8F 94 FD|:..0....
    [1;32m<debug> nrf_dfu_validation:  C6 2A 6A 81 F8 5F 7D B1|.*j.._}.

    Where is the "expected FW" hash stored? As I just decode and store the incomming hex file (app only from 0x27000) data in bank1 I do no previous hash calculation as reference for this step.

  • Hi Massimo, 
    I think you missed the "init packet" transferring part. It's described here. It's transferred before the image is transmitted. And stored in init_command inside nrf_dfu_settings_t struct.
    The init packet not only include the hash but also the signature for authentication check. I think it's something important that you may want to implement in  your application. 

  • If I didn't understand it wrong then the .bat file in the generated zip package contains the content of the init_command.

    Is it possible just to store the content of the .bat file in the init_command[512] array, or is there any overhead in the .bat file?

  • I assume you meant the .dat file ? 
    As far as I know there is no overhead or filter. But you may need to double check.

    I would suggest the following test. You can modify the original bootloader so that it pause at the swapping phase. So that you know what exactly expected in the bootloader setting in order for the bootloader to swap the image. 

Related