Single bank DFU update in SDK16 fails

Hello,

I am trying to do a single bank DFU update using nRF Connect app and have SDK 16 on my device. I have set NRF_DFU_SINGLE_BANK_APP_UPDATES to 1. Bot looking at postvalidate (attached below) in nrf_dfu_validation.c, it automatically swicthes to Bank 1. Is there some settings that I am missing?

Thank you.

nrf_dfu_result_t postvalidate(uint32_t data_addr, uint32_t data_len, bool is_trusted)
{
nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
dfu_init_command_t const * p_init = mp_init;

if (!fw_hash_ok(p_init, data_addr, data_len))
{
ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_VERIFICATION_FAILED);
}
else
{
if (p_init->type == DFU_FW_TYPE_APPLICATION)
{
if (!postvalidate_app(p_init, data_addr, data_len, is_trusted))
{
ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
}
}
#if NRF_DFU_SUPPORTS_EXTERNAL_APP
else if (p_init->type == DFU_FW_TYPE_EXTERNAL_APPLICATION)
{
if (!is_trusted)
{
// This function must be implemented externally
ret_val = nrf_dfu_validation_post_external_app_execute(p_init, is_trusted);
}
else
{
s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_EXT_APP;
}
}
#endif // NRF_DFU_SUPPORTS_EXTERNAL_APP
else
{
bool with_sd = p_init->type & DFU_FW_TYPE_SOFTDEVICE;
bool with_bl = p_init->type & DFU_FW_TYPE_BOOTLOADER;

if (!postvalidate_sd_bl(p_init, with_sd, with_bl, data_addr, data_len, is_trusted))
{
ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
if (is_trusted && with_sd && !DFU_REQUIRES_SOFTDEVICE &&
(data_addr == nrf_dfu_softdevice_start_address()))
{
nrf_dfu_softdevice_invalidate();
}
}
}
}

if (!is_trusted)
{
if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
{
s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
}
else
{
dfu_progress_reset();
}
}
else
{
if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
{
// Mark the update as complete and valid.
s_dfu_settings.bank_1.image_crc = crc32_compute((uint8_t *)data_addr, data_len, NULL);
s_dfu_settings.bank_1.image_size = data_len;
}
else
{
nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
}

dfu_progress_reset();
s_dfu_settings.progress.update_start_address = data_addr;
}

return ret_val;
}

  • Hi,

    The references to bank 1 that you refer to are to the value stored in the DFU settings. From what I understand, those settings will contain the correct values for when doing single bank DFU, so that the functionality of the DFU bootloader is correct for that scenario. (E.g. containing same data for both bank_0 and bank_1 when single bank is used.)

    Setting NRF_DFU_SINGLE_BANK_APP_UPDATES should ensure single-bank update is used for the application.

    In addition, there is an NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES (which may conflict with NRF_DFU_SINGLE_BANK_APP_UPDATES), please check that you have not set that one as well.

    Apart from that, do you see any error or is it failing in any way, or is your inquiry based only on code inspection?

    Regards,
    Terje

  • Hey Terje,

    I am seeing a failure with my code. I am setting NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES to 0.

    I send a DFU package (zip file created by nrfutil) using nRFConnect app. Before the update, when reading the MBR and Bootloader settings I get:

    nrfjprog --memrd 0x7E000 --n 128 --family nrf52
    0x0007F000: B77F69C5 00000002 00000001 00000002 |.i..............|
    0x0007F010: 00000000 00000000 0004625C FFDD4169 |........\b..iA..|
    0x0007F020: 00000001 00000000 00000000 00000000 |................|
    0x0007F030: 00000000 00000000 00000000 00000000 |................|
    0x0007F040: 00000000 00000000 00019000 00000000 |................|
    0x0007F050: 00000000 00000000 00000000 FFFFFFFF |................|
    0x0007F060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    0x0007F070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|

    Here, bank 0 has the correct details of size and crc. After the update, I get

    nrfjprog --memrd 0x7E000 --n 128 --family nrf52
    0x0007F000: 2869FC68 00000002 00000001 00000002 |h.i(............|
    0x0007F010: 00000000 00000000 00000000 00000000 |................|
    0x0007F020: 00000001 0004625C FFDD4169 00000000 |....\b..iA......|
    0x0007F030: 00000000 00000000 00000000 00000000 |................|
    0x0007F040: 00000000 00000000 00019000 00000000 |................|
    0x0007F050: 00000000 00000000 00000000 FFFFFFFF |................|
    0x0007F060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    0x0007F070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|

    Here bank 0 is the active bank, but the size of code is 0. This makes the check for valid application fail in line 301 in nrf_bootloader.c:

    else if (!boot_validate(&s_dfu_settings.boot_validation_app, nrf_dfu_bank0_start_addr(), s_dfu_settings.bank_0.image_size, do_crc))

    My file size before and after the update is the same since I am only changing a version number as a test.

  • Hi,

    Yes, this looks a bit strange. What is the full command you used for generating the DFU package, and with what version of nrfutil?

    Regards,
    Terje

  • Here is my command to generate the application package:

    nrfutil pkg generate --hw-version 52 --sd-req 0x00 --key-file private.pem --application-version 0x01 --application main.hex app_dfu_package.zip

    Version for nrfutil: v6.1.3.

    Btw, if I ignore the error from nrf_bootloader.c and let the application code boot anyway, it works. So the code is written to the correct place.

  • Hi,

    Have you tried setting the --sd-req to the SoftDevice used (or is this serial DFU / no SoftDevice installed)?

    Also, application version, has it strictly increased from what was already stored?

    Regards,
    Terje

Related