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

Custom DFU Process

Hi 

I have implemented a custom DFU process, where NRF52840 sends another NRF52833 an image to program. 

The NRF52833  receives the image and validates CRC, if all OK , I am performing the following in my application : 

#define BOOTLOADER_SETTINGS_PAGE_ADDR (0x0007F000)
#define BOOTLOADER_SETTINGS_PAGE_PTR ((uint8_t*)BOOTLOADER_SETTINGS_PAGE_ADDR)

#define IMAGE_UPDATE_ADDRESS (0x00048000)
#define IMAGE_UPDATE_ADDRESS_PTR ((uint8_t*)IMAGE_UPDATE_ADDRESS)
#define BOOTLOADER_BACKUP_SETTINGS_PAGE_ADDR (0x0007E000)
#define BOOTLOADER_BACKUP_SETTINGS_PAGE_ADDR_PTR ((uint8_t*)BOOTLOADER_BACKUP_SETTINGS_PAGE_ADDR)

void apply_firmware(uint32_t length,uint32_t crc)
{
   ret_code_t ret;
  /********************************************************************
  if enter dfu , stop other Tasks here to make sure update successful
*********************************************************************/
ret = nrf_sdh_disable_request();
vTaskDelay(2000);
memcpy((void *)&s_dfu_settings, BOOTLOADER_BACKUP_SETTINGS_PAGE_ADDR_PTR, sizeof(nrf_dfu_settings_t));
s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
s_dfu_settings.bank_1.image_crc = crc32_compute(IMAGE_UPDATE_ADDRESS_PTR , length, NULL);
s_dfu_settings.bank_1.image_size = length;
s_dfu_settings.progress.update_start_address = IMAGE_UPDATE_ADDRESS;
s_dfu_settings.write_offset = 0;

s_dfu_settings.crc = crc32_compute((uint8_t*)(&s_dfu_settings) + 4, DFU_SETTINGS_INIT_COMMAND_OFFSET - 4, NULL);
//write back to flash
nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_PAGE_ADDR);
vTaskDelay(2000);
nrf_nvmc_write_bytes(BOOTLOADER_SETTINGS_PAGE_ADDR, (uint8_t *)(&s_dfu_settings), sizeof(s_dfu_settings));
vTaskDelay(2000);

NVIC_SystemReset();
}

This works, only if I modify the following in bootloader code ( nrf_dfu_settings.c ) :

void nrf_dfu_settings_reinit(void)
{
 bool settings_valid = settings_crc_ok();
 bool settings_backup_valid = settings_backup_crc_ok();
 settings_backup_valid = false;

....

}

Unless I do so , the backup settings page will be copied to the settings page : 100


void nrf_dfu_settings_reinit(void)
{
  bool settings_valid = settings_crc_ok();
  bool settings_backup_valid = settings_backup_crc_ok();
  if (settings_valid)
  { 
    NRF_LOG_DEBUG("Using settings page.");
    memcpy(&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t));
    if (settings_backup_valid)
    {
      NRF_LOG_DEBUG("Copying forbidden parts from backup page.");
      settings_forbidden_parts_copy_from_backup((uint8_t *)&s_dfu_settings);
    }
}

...

How can I avoid the call to "settings_forbidden_parts_copy_from_backup" ? I have tried to erase the BACKUP_SETTING page ( 0xfe000) but it is protected 

https://devzone.nordicsemi.com/f/nordic-q-a/47147/erasing-of-master-boot-record-parameters-page-hangs

Related