BLE and OTA(modem) DFU is it compatible?

Hi everyone, 

I try to implement DFU on nrf52840 with SDK15.3 and softdevice s140. 

I use the secure bootloader ble example and in BLE it works well. But I have an issue in modem(OTA). 

In the application I received the .bin and .dat files from the server. I write the .bin file into the bank 1 of the internal flash of the nrf52840. 

But after receiving the firmware I rewrite the setting to match with the new firmware. 

But when I restart on the bootloader the device does not take the new firmware and the setting memory region is corrupted and the device is stuck in DFU mode. 

Is there any precaution to have when I set the new setting ? 

Here my new settings:

 

void execute_nrf52_dfu (nrf_dfu_settings_t *dfu_settings, uint32_t bank1_addr)
{
    uint32_t err_code;

    // Fill the structure of DFU settings
     if (*(uint8_t *)(DFU_INIT_CMD_ADDRESS + DFU_BLSD_APP_POS) == DFU_FW_TYPE_APP) {
        // DFU for application
        dfu_settings->bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
        dfu_settings->bank_0.bank_code = NRF_DFU_BANK_INVALID;
        dfu_settings->bank_1.image_crc = crc32((uint8_t*) bank1_addr, dfu_settings->bank_1.image_size);
        memcpy(dfu_settings->boot_validation_app.bytes, &dfu_settings->bank_1.image_crc, sizeof(uint32_t));
    } else if (*(uint8_t *)(DFU_INIT_CMD_ADDRESS + DFU_BLSD_APP_POS) == DFU_FW_TYPE_BL_SD) {
        // DFU for bootloader and SoftDevice
        dfu_settings->bank_1.bank_code = NRF_DFU_BANK_VALID_SD_BL;
        dfu_settings->bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
        dfu_settings->sd_size = read_sd_size ((uint8_t *)DFU_INIT_CMD_ADDRESS);
    } else {
        NRF_LOG_ERROR  ("Error in downloaded firmware: bad firmware type.");
    }
    memcpy(&(dfu_settings->init_command), (void*) DFU_INIT_CMD_ADDRESS, dfu_settings->progress.command_size);
    dfu_settings->progress.command_crc = crc32(dfu_settings->init_command, dfu_settings->progress.command_size);
    dfu_settings->progress.update_start_address = bank1_addr;
    dfu_settings->enter_buttonless_dfu = 1;
    dfu_settings->bank_current = NRF_DFU_CURRENT_BANK_1;
    dfu_settings->bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
    dfu_settings->boot_validation_softdevice.type = NO_VALIDATION;
    dfu_settings->boot_validation_app.type = VALIDATE_CRC;
    dfu_settings->boot_validation_bootloader.type = NO_VALIDATION;
    dfu_settings->settings_version = NRF_DFU_SETTINGS_VERSION; // NRF_DFU_SETTINGS_VERSION must be 2 with SDK 15.3
    dfu_settings->crc = crc32((uint8_t*) &(dfu_settings->settings_version), (uint8_t*) dfu_settings->init_command - (uint8_t*) &(dfu_settings->settings_version)); // number of bytes between crc and init command

    // Erase previous settings
    NRF_LOG_INFO("%s, %d", __FUNCTION__, __LINE__);
    err_code = nrf_dfu_flash_erase(DFU_SETTINGS_ADDRESS, DFU_SETTINGS_PAGE_ERASE, dfu_flash_erase_done);
    APP_ERROR_CHECK(err_code);
    xEventGroupWaitBits(downloadEventGroup, DFU_ERASE_DONE, pdTRUE, pdFALSE, portMAX_DELAY);

    // Write new settings in Flash memory
    NRF_LOG_INFO("%s, %d", __FUNCTION__, __LINE__);
    dfu_flash_write(DFU_SETTINGS_ADDRESS, (uint8_t*) dfu_settings, sizeof(nrf_dfu_settings_t), true);

    // Start DFU, this function will not return
    LOG_EEPROM_INFO("Start DFU");
    reboot_dfu();
}

Thank you for your help.

Etienne 

Parents Reply
  • Etienne,

    Try putting a breakpoint when you do normal Bootloader update (not background) right at the moment when the setting is written by the bootloader. Before it's swapped by the MBR.

    By having that setting, you just need to match what you need to write in the application when they do background DFU. You can read the setting out either by reading flash, or just looking at the memory at the breakpoint and then compare it with what they write using the application in background dfu

Children
No Data
Related