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

  • Hi,

    TOCGRE said:
    What can happen during the reset that can change flash in bootloader settings section ?

    The reset itself does not cause any writing to flash, so it would have to be either the application before the reset, or the bootloader after. And the bootloader will normally only write to bootloader settings during a DFU update, and if some of the "forbidden" parts have been changed. If this change does not happen during settings_forbidden_parts_copy_from_backup(), perhaps you can experiment with setting a breakpoint (or an eternal loop to prevent further execution or something else) in the bootloader and moving it around to try to narrow down where the data is changed (there are not that many part of the bootloader that writes to the bootloder settings page)?

  • Hi,

    I've found the issue : the nrf52832 does not behave the same way with or without debugger attached when logs are enabled in release config.

    As my app size is  too big in debug config to do a dual bank DFU, I just added some logs to the release config to make the app smaller and enable dual bank DFU.

    When debugger is attached, the whole dfu process goes on without any error and new bootloader settings are written correctly. However if I attach debugger in the app project the program gets stuck when resetting to the bootloader (I still don't know why). So the only way I found to debug the bootloader was to wait for the app to make DFU without attaching the debugger and attach the debugger as soons as the bootloader starts (supposedly at the end of the DFU process in app) thanks to a LED blink. But when running app without attaching debugger, I discovered that an error occurs and leads to a reset (which I thought was the one at the end of successful DFU process). Thus the bootloader I'm debugging does not find new firmware info in bootloader settings. Hence the bootloader starts and launches the current app in bank0.

    I found that this error occuring during the in app DFU was due to logs. So I just disabled the logs in release config and copying the bank1 to bank0 and jumping to it works !

    So I don't know exactly what the problem is but I guess that mayby logs in release are in conflict with dfu modules or share a common area in flash...

    Anyway thanks for helping me

    BR

Related