uint32_t dfu_ap_image_swap(void) { uint32_t err_code = NRF_SUCCESS; const bootloader_settings_t * p_bootloader_settings; bootloader_util_settings_get(&p_bootloader_settings); uint32_t ap_image_start = p_bootloader_settings->src_image_address + p_bootloader_settings->sd_image.st.size + p_bootloader_settings->bl_image.st.size; if (ap_image_start == CODE_REGION_1_START) { return NRF_SUCCESS; // no need to do anything since the code is already in the correct place. } if (p_bootloader_settings->ap_image.st.size != 0) { if (m_storage_handle_app.block_id == CODE_REGION_1_START) { // Erase BANK 0. err_code = pstorage_raw_clear(&m_storage_handle_app, p_bootloader_settings->ap_image.st.size); if (err_code == NRF_SUCCESS) { err_code = pstorage_raw_store(&m_storage_handle_app, (uint8_t*) m_storage_handle_swap.block_id,p_bootloader_settings->ap_image.st.size, 0); } } } return err_code; }
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) { uint32_t err_code; uint32_t data_length; uint8_t * p_data; if (p_packet == NULL) { return NRF_ERROR_NULL; } // Check pointer alignment. if (!is_word_aligned(p_packet->p_data_packet)) { // The p_data_packet is not word aligned address. return NRF_ERROR_INVALID_ADDR; } switch (m_dfu_state) { case DFU_STATE_RDY: // Fall-through. case DFU_STATE_RX_INIT_PKT: m_dfu_state = DFU_STATE_RX_DATA_PKT; // Fall-through. case DFU_STATE_RX_DATA_PKT: data_length = p_packet->packet_length * sizeof(uint32_t); if ((uint32_t)(m_received_data + data_length) > m_image_size) { // The caller is trying to write more bytes into the flash than the size provided to // the dfu_image_size_set function. return NRF_ERROR_DATA_SIZE; } p_data = (uint8_t *)p_packet->p_data_packet; err_code = pstorage_raw_store(&m_storage_handle_app, p_data, data_length, m_received_data); if (err_code != NRF_SUCCESS) { return err_code; } m_received_data += data_length; break; default: err_code = NRF_ERROR_INVALID_STATE; break; } return err_code; }
uint32_t dfu_image_activate() { uint32_t err_code; switch (m_dfu_state) { case DFU_STATE_WAIT_4_ACTIVATE: // Stop the DFU Timer because the peer activity need not be monitored any longer. err_code = app_timer_stop(m_dfu_timer_id); APP_ERROR_CHECK(err_code); // Erase BANK 0. err_code = pstorage_raw_clear(&m_storage_handle_app, m_image_size); APP_ERROR_CHECK(err_code); err_code = pstorage_raw_store(&m_storage_handle_app, (uint8_t*) m_storage_handle_swap.block_id, m_image_size, 0); if (err_code == NRF_SUCCESS) { dfu_update_status_t update_status; update_status.status_code = DFU_UPDATE_COMPLETE; update_status.app_crc = m_image_crc; update_status.app_size = m_image_size; bootloader_dfu_update_process(update_status); } break; default: err_code = NRF_ERROR_INVALID_STATE; break; } return err_code; }
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) { uint32_t data_length; uint32_t err_code; uint32_t * p_data; if (p_packet == NULL) { return NRF_ERROR_NULL; } // Check pointer alignment. if(((uint32_t) (p_packet->p_data_packet)) & (sizeof(uint32_t) - 1)) { // The p_data_packet is not word aligned address. return NRF_ERROR_INVALID_ADDR; } switch (m_dfu_state) { case DFU_STATE_RDY: case DFU_STATE_RX_INIT_PKT: m_dfu_state = DFU_STATE_RX_DATA_PKT; // fall-through. case DFU_STATE_RX_DATA_PKT: data_length = p_packet->packet_length * sizeof(uint32_t); if ((m_app_data_received + data_length) > m_image_size) { // The caller is trying to write more bytes into the flash than the size provided to // the dfu_image_size_set function. This is treated as a serious error condition and // an unrecoverable one. Hence point the variable mp_app_write_address to the top of // the flash area. This will ensure that all future application data packet writes // will be blocked because of the above check. m_app_data_received = 0xFFFFFFFF;; return NRF_ERROR_DATA_SIZE; } // Valid peer activity detected. Hence restart the DFU timer. err_code = dfu_timer_restart(); if (err_code != NRF_SUCCESS) { return err_code; } p_data = (uint32_t *)p_packet->p_data_packet; err_code = pstorage_raw_store(&m_storage_handle_swap, (uint8_t*) p_data, data_length, m_app_data_received); if (err_code != NRF_SUCCESS) { return err_code; } m_app_data_received += data_length; if (m_app_data_received != m_image_size) { // The entire image is not received yet. More data is expected. err_code = NRF_ERROR_INVALID_LENGTH; } else { // The entire image has been received. Return NRF_SUCCESS. err_code = NRF_SUCCESS; } break; default: err_code = NRF_ERROR_INVALID_STATE; break; } return err_code; }
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) { uint32_t err_code; uint32_t data_length; uint8_t * p_data; if (p_packet == NULL) { return NRF_ERROR_NULL; } // Check pointer alignment. if (!is_word_aligned(p_packet->p_data_packet)) { // The p_data_packet is not word aligned address. return NRF_ERROR_INVALID_ADDR; } switch (m_dfu_state) { case DFU_STATE_RDY: // Fall-through. case DFU_STATE_RX_INIT_PKT: m_dfu_state = DFU_STATE_RX_DATA_PKT; // Fall-through. case DFU_STATE_RX_DATA_PKT: data_length = p_packet->packet_length * sizeof(uint32_t); if ((uint32_t)(m_received_data + data_length) > m_image_size) { // The caller is trying to write more bytes into the flash than the size provided to // the dfu_image_size_set function. return NRF_ERROR_DATA_SIZE; } p_data = (uint8_t *)p_packet->p_data_packet; err_code = pstorage_raw_store(&m_storage_handle_app, p_data, data_length, m_received_data); if (err_code != NRF_SUCCESS) { return err_code; } m_received_data += data_length; // SINGLEBANK PATCH: added so that it will return NRF_ERROR_INVALID_LENGTH instead of NRF_SUCCESS if the full image is not received. if (m_received_data != m_image_size) { // The entire image is not received yet. More data is expected. err_code = NRF_ERROR_INVALID_LENGTH; } else { // The entire image has been received. Return NRF_SUCCESS. err_code = NRF_SUCCESS; } //PATCH END break; default: err_code = NRF_ERROR_INVALID_STATE; break; } return err_code; }