Bank 1 DFU settings empty in bootloader after custom DFU in app

Hi

I am currently developing a custom dfu in my app in background through LTE communication. I am working with nRF5 SDK 17.0.2, softdevice s132 7.2.0 and nRF52832.

I am using the secure bootloader given in the SDK in which I set NRF_BL_DFU_ALLOW_UPDATE_FROM_APP to 1.

So far I've used nrf_dfu_req_handler module to write first init packet and then new firmware to flash memory in bank 1.

In the app everything seems to be working well: the signature from the init packet is successfully verified, init packet is written to flash, then firmware is written to flash through several objects and it ends with postvalidation. Here are the last logs I get before resetting to bootloader. There are my own logs starting with [] in the middle.

If I understand well, at the end of firmware update in bank1, the app "postvalidation" just writes new dfu settings to flash memory in order for the bootloader to make the actual postvalidation and activate this new image to copy it to bank0.

I have checked that at the end the debugger goes through the line s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1; in function postvalidate() in nrf_dfu_validation.c

When DFU is finished I request a software reset by calling nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_RESET); like in the example of background DFU you have made (nRF_SDK_15.3.0_background_dfu_3 found on devzone).

After the reset, the bootloader starts and launches the app in bank0 instead of bank1.

In the bootloader when I reach the section below I have noticed that s_dfu_settings.bank_current is 0 so that postvalidate() function is not executed.

ret_val = nrf_dfu_settings_init(false);
    if (ret_val != NRF_SUCCESS)
    {
        return NRF_ERROR_INTERNAL;
    }

    #if NRF_BL_DFU_ALLOW_UPDATE_FROM_APP
    // Postvalidate if DFU has signaled that update is ready.
    if (s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_1)
    {
				postvalidate();
    }
    #endif

    // Check if an update needs to be activated and activate it.
    activation_result = nrf_bootloader_fw_activate();

I have tried to put a breakpoint right after nrf_dfu_settings_init(false); function and noticed that s_dfu_settings is all empty for bank1 : 

Maybe I am mistaken but I thought that s_dfu_settings in the bootloader would be the same value as set in the app at the end of custom DFU process. So I would expect bank_current to be NRF_DFU_CURRENT_BANK_1.

1. Is my understanding of postvalidation ok ? The app dfu modules write the necessary settings to flash for the bootloader to postvalidate, activate and swap bank1 and 0. The postvalidation is made in the bootloader since I set NRF_DFU_IN_APP to 1 in my app sdk_config.h.

2. Why is s_dfu_settings empty for bank1 in the bootloader ?

3. More generally, do you have an idea why my bootloader does not copy the new firmware from bank1 to bank0 ?

Best regards

Parents
  • Hi,

    1. Is my understanding of postvalidation ok ? The app dfu modules write the necessary settings to flash for the bootloader to postvalidate, activate and swap bank1 and 0. The postvalidation is made in the bootloader since I set NRF_DFU_IN_APP to 1 in my app sdk_config.h.

    Yes, this is correct. I do not see all you have done, but I wonder if the issue here is related to the backup and restoration of the bootloader settings page. The current bank is overwritten as you can see from the implementation of settings_forbidden_parts_copy_from_backup() in components/libraries/bootloader/dfu/nrf_dfu_settings.c. Based on what you write, it could be that it would be enough to remove the line that copies the bank_current from the backup. Byt normally the bootloader would handle this for you, as long as you have copied the init packet to the bootloader settings (this is not overwritten by the backup when you have NRF_BL_DFU_ALLOW_UPDATE_FROM_APP enabled).  See this post for more on that.

    2. Why is s_dfu_settings empty for bank1 in the bootloader ?

    If s_dfu_settings.bank_1 was not empty before, then the only reason I can think of that would make it empty is if nrf_dfu_bank_invalidate() was called with it's address. And this happens close to the end of postvalidate().

    3. More generally, do you have an idea why my bootloader does not copy the new firmware from bank1 to bank0 ?

    I believe it is because of the backup restoration explained above, which means that the active bank will be reverted to bank0.

    PS: I recommend that you use nRF5 SDK 17.1.0 instead of 17.0.2, as that has support for the latest revision of the nRF52832 (alternatively you must update the MDK as explained in IN142).

  • Could it be that dfu settings is write protected by ACL and though the write operation returns success, it actually failed to write?

    // <i> The settings page may be used to exchange information between the bootloader and the application.
    // <i> In that case it should not be protected.

    #ifndef NRF_BL_SETTINGS_PAGE_PROTECT
    #define NRF_BL_SETTINGS_PAGE_PROTECT 1
    #endif

  • Check ACL register for what regions are protected:

  • Hi erk1313,

    Thanks for helping ! It seems that ACL registers are only for nrf52840. On nrf52832 only BPROT peripheral is used to protect memory but I did not find any related issue in my case.

    BR

Reply Children
No Data
Related