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

dfu_activate_app fail to swap bank 1 to bank 0

Hi, We have being producing ble items with nrf51822 QFAAG , S110 SD 7.0, SDK 6.1, Dual bank DFU. When updating the application throught Android, the bootloader hangs, because bootloader_app_is_valid returns true, but bank 0 is broken.

We did a little change in dfu_init, so as to set the application flag to BANK_INVALID_APP.

uint32_t dfu_init(void) {

uint32_t                err_code;
bootloader_settings_t   bootloader_settings;
dfu_update_status_t     update_status;
pstorage_module_param_t storage_module_param = {.cb = pstorage_callback_handler};

// Clear swap area.
uint32_t * p_bank_start_address = (uint32_t *)DFU_BANK_1_REGION_START;

**// Erase Bank0
update_status.status_code = DFU_BANK_0_ERASED;
bootloader_dfu_update_process(update_status);**
....

}

static uint32_t dfu_activate_app(void) {

uint32_t err_code;
// Erase BANK 0.
err_code = pstorage_raw_clear(&m_storage_handle_app, m_start_packet.app_image_size);
APP_ERROR_CHECK(err_code);
err_code = pstorage_raw_store(&m_storage_handle_app,
                              (uint8_t *)m_storage_handle_swap.block_id,
                              m_start_packet.app_image_size,
                              0);
if (err_code == NRF_SUCCESS)
{
    dfu_update_status_t update_status;

    update_status.status_code = DFU_UPDATE_APP_COMPLETE;
    update_status.app_crc     = m_image_crc;
    update_status.app_size    = m_start_packet.app_image_size;

    bootloader_dfu_update_process(update_status);
}
...

}

After interviewing the hex, we can confirm that:

  1. bootloader is not broken
  2. 0x3fc00 is 0x00000001(which means BANK_VALID_APP, and bootloader_settings_save has changed the app flag from INVALID to VALID)
  3. application is successfully downloaded to bank 1
  4. the upper part(maybe 10~99 percent) of bank 0 is the same with bank 1, but the remaining part is 0xff(which means pstorage_raw_clear works)

Now we can conclude that something goes wrong when copy from bank 1 to bank 0. According to the bug reports from our customer, 20% of 51822 failed in dfu_activate_app.

We can decrease the percentage of failure by adding a delay of 2 seconds before the Android code send "validate and reset" command.

void add_delay_before_validate_reset(void) {

try {
     	Thread.sleep(2000);
} catch (InterruptedException e) {
        e.printStackTrace();
}

writeOpCode(gatt, controlPointCharacteristic, OP_CODE_ACTIVATE_AND_RESET);
sendLogBroadcast(Level.APPLICATION, "Activate and Reset request sent");

}

That delay can decrease the failure to 5%, do you have any other way to oversome this issue. Please help.

  • Our device have left no j-link interface to customer, so the failure just sentences the device to death. We have stopped manufacturing and it will not be restarted until the problem is targeted and solved.

  • @knightmare: please correct me if I am wrong, you have modified the dfu_init, so that it set settings.bank_0 = BANK_ERASED; at the begining, regardless if the image is actually tranmistted or not ? Could you explain the purpose for doing that? You won't be able to fallback to original application if there is smth wrong when updating.

    It's pretty strange that adding a delay fixed the issue. Please be noted that in our code we will wait (for BOOTLOADER_COMPLETE) until the pstorage has finished with storing the bootloader setting has finished before it trigger a reset, as in pstorage_callback_handler. And bootloader setting is only stored after we have finished with storing code with pstorage_raw_store().

    So if you can have a breakpoint at m_update_status = BOOTLOADER_COMPLETE; in pstorage_callback_handler() you can check if bank0 is copied with correct image.

    Could you send us your bootloader, hex file before and after application update ?

    Do you have the same issue with the stock bootloader example ?

Related