uint32_t dfu_sd_image_swap(void) { bootloader_settings_t boot_settings; bootloader_settings_get(&boot_settings); if (boot_settings.sd_image_size == 0) { return NRF_SUCCESS; } if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start) { uint32_t err_code; uint32_t sd_start = SOFTDEVICE_REGION_START; uint32_t block_size = (boot_settings.sd_image_start - sd_start) / 2; uint32_t image_end = boot_settings.sd_image_start + boot_settings.sd_image_size; uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size; uint32_t sd_block_start = sd_start + 2 * block_size; if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size) { // This will clear a page thus ensuring the old image is invalidated before swapping. err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size), (uint32_t *)(sd_start + block_size), sizeof(uint32_t)); if (err_code != NRF_SUCCESS) { return err_code; } err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t)); if (err_code != NRF_SUCCESS) { return err_code; } } return dfu_sd_img_block_swap((uint32_t *)img_block_start, (uint32_t *)sd_block_start, image_end - img_block_start, block_size); } else { if (boot_settings.sd_image_size != 0) { return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start, (uint32_t *)SOFTDEVICE_REGION_START, boot_settings.sd_image_size); } } return NRF_SUCCESS; }
/**@brief Function for validating that new application has been correctly installed. */ uint32_t dfu_app_image_validate(void) { bootloader_settings_t bootloader_settings; uint32_t err_code = NRF_SUCCESS; bootloader_settings_load(&bootloader_settings); if ((bootloader_settings.bank_1 & BANK_VALID_MASK) & (BANK_VALID_APP)) { err_code = compare((uint32_t *)(SD_SIZE_GET(MBR_SIZE)), (uint32_t *)get_address(APPLICATION_PART), bootloader_settings.app_image_size); } return err_code; }
/**@brief Function for swapping existing application with newly received. */ uint32_t dfu_app_image_swap(void) { bootloader_settings_t bootloader_settings; bootloader_settings_load(&bootloader_settings); if ((bootloader_settings.bank_1 & BANK_VALID_MASK) & (BANK_VALID_APP)) { bootloader_settings.bank_1 &= ~(BANK_VALID_APP); bootloader_settings.bank_0 = BANK_VALID_APP; bootloader_settings_save(&bootloader_settings); return copy((uint32_t *)get_address(APPLICATION_PART), (uint32_t *)(SD_SIZE_GET(MBR_SIZE)), bootloader_settings.app_image_size); } return NRF_SUCCESS; }
uint32_t dfu_sd_image_validate(void) { bootloader_settings_t bootloader_settings; sd_mbr_command_t sd_mbr_cmd; bootloader_settings_get(&bootloader_settings); if (bootloader_settings.sd_image_size == 0) { return NRF_SUCCESS; } if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start) { uint32_t sd_start = SOFTDEVICE_REGION_START; uint32_t block_size = (bootloader_settings.sd_image_start - sd_start) / 2; uint32_t image_end = bootloader_settings.sd_image_start + bootloader_settings.sd_image_size; uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size; uint32_t sd_block_start = sd_start + 2 * block_size; if (SD_SIZE_GET(MBR_SIZE) < bootloader_settings.sd_image_size) { return NRF_ERROR_NULL; } return dfu_sd_img_block_swap((uint32_t *)img_block_start, (uint32_t *)sd_block_start, image_end - img_block_start, block_size); } sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START; sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start; sd_mbr_cmd.params.compare.len = bootloader_settings.sd_image_size / sizeof(uint32_t); return sd_mbr_command(&sd_mbr_cmd); }