123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- #include "nrf_dfu_utils.h"
- #include "nrf_dfu_settings.h"
- #include "nrf_bootloader_info.h"
- #include "crc32.h"
- #include "nrf_log.h"
- #include "nrf_dfu_validation.h"
- void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank)
- {
-
- memset(p_bank, 0, sizeof(nrf_dfu_bank_t));
-
- s_dfu_settings.write_offset = 0;
- }
- #if !defined(BLE_STACK_SUPPORT_REQD) && !defined(ANT_STACK_SUPPORT_REQD)
- void nrf_dfu_softdevice_invalidate(void)
- {
- static const uint32_t all_zero = 0UL;
- if (SD_PRESENT && !NRF_DFU_IN_APP)
- {
- ret_code_t err_code = nrf_dfu_flash_store(SD_MAGIC_NUMBER_ABS_OFFSET_GET(MBR_SIZE), &all_zero, 4, NULL);
- if (err_code != NRF_SUCCESS)
- {
- NRF_LOG_ERROR("Could not invalidate SoftDevice.")
- }
- else
- {
-
- if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
- {
- s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
- }
-
-
-
- s_dfu_settings.bank_0.image_size += SD_SIZE_GET(MBR_SIZE) - MBR_SIZE;
- }
- }
- }
- #endif
- uint32_t nrf_dfu_bank0_start_addr(void)
- {
- if (SD_PRESENT)
- {
- return ALIGN_TO_PAGE(SD_SIZE_GET(MBR_SIZE));
- }
- else
- {
- return MBR_SIZE;
- }
- }
- uint32_t nrf_dfu_bank1_start_addr(void)
- {
- uint32_t bank0_addr = nrf_dfu_bank0_start_addr();
- return ALIGN_TO_PAGE(bank0_addr + s_dfu_settings.bank_0.image_size);
- }
- uint32_t nrf_dfu_app_start_address(void)
- {
- return nrf_dfu_bank0_start_addr();
- }
- uint32_t nrf_dfu_softdevice_start_address(void)
- {
- return MBR_SIZE;
- }
- uint32_t nrf_dfu_cache_prepare(const uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice)
- {
- ret_code_t err_code;
- bool cache_too_small;
- enum
- {
- INITIAL_DELETE_APP = 0,
- APP_DELETED_DELETE_SOFTDEVICE = 1,
- SOFTDEVICE_DELETED = 2
- } pass;
- NRF_LOG_DEBUG("Enter nrf_dfu_cache_prepare()");
- NRF_LOG_DEBUG("required_size: 0x%x.", required_size);
- NRF_LOG_DEBUG("single_bank: %s.", single_bank ? "true" : "false");
- NRF_LOG_DEBUG("keep_app: %s.", keep_app ? "true" : "false");
- NRF_LOG_DEBUG("keep_softdevice: %s.", keep_softdevice ? "true" : "false");
- NRF_LOG_DEBUG("SD_PRESENT: %s.", SD_PRESENT ? "true" : "false");
- NRF_LOG_DEBUG("Bank contents:");
- NRF_LOG_DEBUG("Bank 0 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_0.bank_code, s_dfu_settings.bank_0.image_size);
- NRF_LOG_DEBUG("Bank 1 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_1.bank_code, s_dfu_settings.bank_1.image_size);
-
-
-
- for (pass = INITIAL_DELETE_APP; pass <= SOFTDEVICE_DELETED; pass++)
- {
- uint32_t cache_address;
- const uint32_t bootloader_start_addr = BOOTLOADER_START_ADDR;
- bool keep_firmware = true;
- bool delete_more;
- switch (pass)
- {
- case INITIAL_DELETE_APP:
- cache_address = nrf_dfu_bank1_start_addr();
-
- keep_firmware = keep_app && (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP);
- break;
- case APP_DELETED_DELETE_SOFTDEVICE:
- cache_address = nrf_dfu_bank0_start_addr();
-
-
- keep_firmware = keep_softdevice || !SD_PRESENT;
- break;
- case SOFTDEVICE_DELETED:
- cache_address = nrf_dfu_softdevice_start_address();
- break;
- default:
- ASSERT(false);
- cache_address = 0;
- break;
- }
- ASSERT(cache_address <= DFU_REGION_END(bootloader_start_addr));
- cache_too_small = required_size > (DFU_REGION_END(bootloader_start_addr) - cache_address);
- delete_more = cache_too_small || single_bank;
- NRF_LOG_DEBUG("pass: %d.", pass);
- NRF_LOG_DEBUG("cache_address: 0x%x.", cache_address);
- NRF_LOG_DEBUG("cache_too_small: %s.", cache_too_small ? "true" : "false");
- NRF_LOG_DEBUG("keep_firmware: %s.", keep_firmware ? "true" : "false");
- NRF_LOG_DEBUG("delete_more: %s.", delete_more ? "true" : "false");
- if (!delete_more || keep_firmware || (pass >= SOFTDEVICE_DELETED))
- {
-
- break;
- }
- }
- if (cache_too_small)
- {
- NRF_LOG_WARNING("Aborting. Cannot fit new firmware on device");
- err_code = NRF_ERROR_NO_MEM;
- }
- else
- {
-
- #if !defined(BLE_STACK_SUPPORT_REQD) && !defined(ANT_STACK_SUPPORT_REQD)
- if (pass >= SOFTDEVICE_DELETED)
- {
- NRF_LOG_DEBUG("Invalidating SoftDevice.");
- nrf_dfu_softdevice_invalidate();
- }
- #endif
- if (pass >= APP_DELETED_DELETE_SOFTDEVICE)
- {
- NRF_LOG_DEBUG("Invalidating app.");
- nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
- }
- err_code = NRF_SUCCESS;
- }
- return err_code;
- }
|