Hello,
I am developing DFU over a custom IEEE802.15.4 Protocol in our own embedded OS. I managed to write the new Firmware starting at bank1_start address. Now I need to tell the Bootloader (the BTL from SDK16) to do its magic (verifying and copying the Firmware to bank0). For now I fill the init_command in the nrf_dfu_settings_t at BOOTLOADER_SETTINGS_ADDRESS with the values I get from nrfutil and write it back to flash, but that doesn't impress the bootloader. What else do I need to do so the bootloader knows that there is a new Firmware it should take care of?
This is what I am doing right now:
> nrfutil settings generate --application ./Firmware.hex --application-version 0x0100 --family NRF52840 --bootloader-version 1 --bl-settings-version 2 Firmware_btl_settings.hex
Note: Generating a DFU settings page with backup page included.
This is only required for bootloaders from nRF5 SDK 15.1 and newer.
If you want to skip backup page generation, use --no-backup option.
Generated Bootloader DFU settings .hex file and stored it in: Firmware_btl_settings.hex
Bootloader DFU Settings:
* File: MPS_Master_btl_settings.hex
* Family: NRF52840
* Start Address: 0x000FF000
* CRC: 0x8800843F
* Settings Version: 0x00000002 (2)
* App Version: 0x00000100 (256)
* Bootloader Version: 0x00000001 (1)
* Bank Layout: 0x00000000
* Current Bank: 0x00000000
* Application Size: 0x00024C3C (150588 bytes)
* Application CRC: 0xF899D96C
* Bank0 Bank Code: 0x00000001
* Softdevice Size: 0x00000000 (0 bytes)
* Boot Validation CRC: 0x5FF8E2DA
* SD Boot Validation Type: 0x00000000 (0)
* App Boot Validation Type: 0x00000001 (1)
----------------------------------------------------------------------
nrf_dfu_settings_t * p_dfu_settings = (nrf_dfu_settings_t *)BOOTLOADER_SETTINGS_ADDRESS;
nrf_dfu_settings_t dfu_settings;
dfu_init_command_t init_cmd;
memcpy(&dfu_settings, p_dfu_settings, sizeof(nrf_dfu_settings_t));
init_cmd.has_fw_version = true;
init_cmd.fw_version = 0x0100;
init_cmd.has_hw_version = false;
init_cmd.hw_version = 0xFFF00000;
init_cmd.sd_req_count = 0;
// init_cmd.sd_req[16] = ;
init_cmd.has_type = true;
init_cmd.type = DFU_FW_TYPE_APPLICATION;
init_cmd.has_sd_size = false;
// init_cmd.sd_size = ;
init_cmd.has_bl_size = false;
// init_cmd.bl_size = ;
init_cmd.has_app_size = true;
init_cmd.app_size = 0x00024C3C;
init_cmd.has_hash = false;
// init_cmd.hash = ;
init_cmd.has_is_debug = false;
init_cmd.is_debug = false;
init_cmd.boot_validation_count = 1;
init_cmd.boot_validation[0].type = DFU_VALIDATION_TYPE_VALIDATE_GENERATED_CRC;
init_cmd.boot_validation[0].bytes.size = 4;
init_cmd.boot_validation[0].bytes.bytes[0] = 0xF8;
init_cmd.boot_validation[0].bytes.bytes[1] = 0x99;
init_cmd.boot_validation[0].bytes.bytes[2] = 0xD9;
init_cmd.boot_validation[0].bytes.bytes[3] = 0x6C;
memcpy(dfu_settings.init_command, &init_cmd, sizeof(init_cmd));
nrf_dfu_settings_write(&dfu_settings);
enter_bootloader(); // set NRF_POWER->GPREGRET and reboot
----------------------------------------------------------------------
void nrf_dfu_settings_write(nrf_dfu_settings_t * pData) {
/* g_btl_info need to be the start of a page */
assert(((uint32_t)p_dfu_settings % NRF_FICR->CODEPAGESIZE) == 0);
assert(pData);
if (0 == memcmp(pData, &p_dfu_settings, sizeof(nrf_dfu_settings_t))) {
return;
}
nrf_nvmc_page_erase((uint32_t)p_dfu_settings);
nrf_nvmc_bytes_write((uint32_t)p_dfu_settings, pData, sizeof(nrf_dfu_settings_t));
}
