static void bootloader_settings_save(bootloader_settings_t * p_settings) { //TODO. This is temporary static uint8_t ant_boot_settings[BOOTLOADER_SETTINGS_FLASH_BLOCK_SIZE]; static pstorage_handle_t ant_boot_settings_handle; /* Backing up ant_boot_settings. */ ant_boot_settings_handle.module_id = m_bootsettings_handle.module_id; ant_boot_settings_handle.block_id = m_bootsettings_handle.block_id + (BOOTLOADER_SETTINGS_FLASH_BLOCK_SIZE * (BOOTLOADER_SETTINGS_FLASH_BLOCK_COUNT - 1)); memcpy(ant_boot_settings, (uint8_t*)ant_boot_settings_handle.block_id, BOOTLOADER_SETTINGS_FLASH_BLOCK_SIZE); /* NOTE: Must erase the whole module to prevent pstorage block erasing which uses swap space*/ uint32_t err_code = pstorage_clear(&m_bootsettings_handle, BOOTLOADER_SETTINGS_FLASH_BLOCK_SIZE * BOOTLOADER_SETTINGS_FLASH_BLOCK_COUNT); APP_ERROR_CHECK(err_code); /* Write back ant_boot_settings */ err_code = pstorage_store(&ant_boot_settings_handle, ant_boot_settings, BOOTLOADER_SETTINGS_FLASH_BLOCK_SIZE, 0); APP_ERROR_CHECK(err_code); err_code = pstorage_store(&m_bootsettings_handle, (uint8_t *)p_settings, sizeof(bootloader_settings_t), 0); APP_ERROR_CHECK(err_code); }
/**@brief Function for activating received Application image. * * @details This function will move the received application image fram swap (bank 1) to * application area (bank 0). * * @return NRF_SUCCESS on success. Error code otherwise. */ static uint32_t dfu_activate_app(void) { uint32_t err_code; // Erase BANK 0. err_code = pstorage_clear(&m_storage_handle_app, m_start_packet.app_image_size); APP_ERROR_CHECK(err_code); err_code = pstorage_store(&m_storage_handle_app, (uint8_t *)m_storage_handle_swap.block_id, m_start_packet.app_image_size, 0); if (err_code == NRF_SUCCESS) { dfu_update_status_t update_status; memset(&update_status, 0, sizeof(dfu_update_status_t )); update_status.status_code = DFU_UPDATE_APP_COMPLETE; update_status.app_crc = m_image_crc; update_status.app_size = m_start_packet.app_image_size; bootloader_dfu_update_process(update_status); } return err_code; }
void Storage::PstorageEventHandler(pstorage_handle_t* handle, u8 opCode, u32 result, u8* data, u32 dataLength) { //logt("STORAGE", "Event: %u, result:%d, len:%d", opCode, result, dataLength); if(result != NRF_SUCCESS) logt("STORAGE", "%s", Logger::getInstance().getPstorageStatusErrorString(opCode)); //if it 's a clear, we do the write if(opCode == PSTORAGE_CLEAR_OP_CODE && result == NRF_SUCCESS){ taskitem* task = (taskitem*)Storage::getInstance().taskQueue->PeekNext().data; pstorage_store(&Storage::getInstance().block_handles[task->storageBlock], task->data, task->dataLength, 0); } //If its a write or a read, we drop the last item and execute the next one else if((opCode == PSTORAGE_STORE_OP_CODE || opCode == PSTORAGE_LOAD_OP_CODE) && result == NRF_SUCCESS) { //Remove item from queue because it was successful taskitem* task = (taskitem*)Storage::getInstance().taskQueue->GetNext().data; //Notify callback if(task->operation == OPERATION_READ){ task->callback->ConfigurationLoadedHandler(); } else if(task->operation == OPERATION_WRITE){}; Storage::getInstance().bufferedOperationInProgress = false; Storage::getInstance().ProcessQueue(); } else if(result != NRF_SUCCESS){ Storage::getInstance().bufferedOperationInProgress = false; Storage::getInstance().ProcessQueue(); } }
static void bootloader_settings_save(bootloader_settings_t * p_settings) { uint32_t err_code = pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t)); APP_ERROR_CHECK(err_code); err_code = pstorage_store(&m_bootsettings_handle, (uint8_t *)p_settings, sizeof(bootloader_settings_t), 0); APP_ERROR_CHECK(err_code); }
uint32_t ble_ans_c_service_store(void) { uint32_t err_code; err_code = pstorage_store(&m_flash_handle, (uint8_t *) m_service_db, DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t), 0); return err_code; }
/* Platform-specific implementation for persistence on the nRF5x. Based on the * pstorage module provided by the Nordic SDK. */ void saveEddystoneServiceConfigParams(const EddystoneService::EddystoneParams_t *paramsP) { memcpy(&persistentParams.params, paramsP, sizeof(EddystoneService::EddystoneParams_t)); if (persistentParams.persistenceSignature != PersistentParams_t::MAGIC) { persistentParams.persistenceSignature = PersistentParams_t::MAGIC; pstorage_store(&pstorageHandle, reinterpret_cast<uint8_t *>(&persistentParams), sizeof(PersistentParams_t), 0 /* offset */); } else { pstorage_update(&pstorageHandle, reinterpret_cast<uint8_t *>(&persistentParams), sizeof(PersistentParams_t), 0 /* offset */); } }
/** * \callgraph * \brief When the Ladybug needs to store info, it calls the flash_write routine. * \details This routine assumes the flash storage to be used has been initialized by a call to flash_init. Match the handle to * flash storage to the info the caller wants to write. * \note As directed by the nRF51822 documentation, the flash storage is first cleared before a write to flash happens. * @param what_data_to_write Whether to write out plant info, calibration values, or the device name. * @param p_bytes_to_write A pointer to the bytes to be written to flash. * @param num_bytes_to_write The number of bytes to write to flash * @param did_flash_action Function caller passes in to be informed of the outcome of the Flash request. The pointer to the function must be valid. */ void ladybug_flash_write(flash_rw_t what_data_to_write, uint8_t *p_bytes_to_write,pstorage_size_t num_bytes_to_write,void(*did_flash_action)(uint32_t err_code)){ SEGGER_RTT_WriteString(0,"==> IN ladybug_flash_write\n"); // Check parameters. The what_data_to_write param is checked below in the switch statement. if (p_bytes_to_write == NULL || (did_flash_action == NULL)){ APP_ERROR_HANDLER(LADYBUG_ERROR_NULL_POINTER); } if (num_bytes_to_write <= 0){ APP_ERROR_HANDLER(LADYBUG_ERROR_NUM_BYTES_TO_WRITE); } // Set the static variable used to hold the location of the callback function to the pointer passed in by the caller. m_flash_return = did_flash_action; // Must clear the Flash block before write (or get unpredictable results). pstorage_handle_t *p_handle; switch (what_data_to_write) { case plantInfo: p_handle = &m_block_plantInfo_store_handle; break; case calibrationValues: p_handle = &m_block_calibration_store_handle; break; case deviceName: p_handle = &m_block_device_name_store_handle; break; default: APP_ERROR_HANDLER(LADYBUG_ERROR_INVALID_COMMAND); break; } //clearing the pstorage/flash sets the bytes to 0xFF // m_mypstorage_wait_flag is set to 0 within ladybug_flash_handler(). This way the system lets us know the Flash activity happened. m_mypstorage_wait_flag = 1; // There is a chance the Flash activity doesn't happen so we use a timer to prevent waiting forever. start_timer(); uint32_t err_code = pstorage_clear(p_handle, BLOCK_SIZE); while(m_mypstorage_wait_flag) { } APP_ERROR_CHECK(err_code); // The flash action happened, so turn off the timer before it goes off. stop_timer(); // Start the timer up again to timeout if writing to flash doesn't happen start_timer(); m_mypstorage_wait_flag = 1; err_code = pstorage_store(p_handle, p_bytes_to_write, num_bytes_to_write, 0); while(m_mypstorage_wait_flag) { } APP_ERROR_CHECK(err_code); stop_timer(); }
H_U32 _StorageWrite(pstorage_handle_t *flash_handle,H_U8 *data,H_U32 size,H_U32 offset,H_U16 user_block_size) { H_U32 err_code = 0; H_U32 correct_offset = 0; pstorage_handle_t redirect_handle; wy_memset(&redirect_handle, 0, sizeof(pstorage_handle_t)); correct_offset = (offset * user_block_size); err_code= pstorage_block_identifier_get(flash_handle, 0, &redirect_handle); APP_ERROR_CHECK(err_code); WYPrintf(MODULE_DEBUG_STORAGE,LEVEL_DEBUG,"before write2 for module:%d",flash_handle->module_id); err_code = pstorage_store(&redirect_handle,(H_U8 *)data,size,correct_offset); wy_tools_op()->_delay_us(100); return err_code; //APP_ERROR_CHECK(err_code); }
/* Saves only the TimeParams (a subset of Config Params) for speed/power efficiency * Platform-specific implementation for persistence on the nRF5x. Based on the * pstorage module provided by the Nordic SDK. */ void saveEddystoneTimeParams(const TimeParams_t *timeP) { // Copy the time params object to the main datastructure memcpy(&persistentParams.params.timeParams, timeP, sizeof(TimeParams_t)); // Test if this is the first pstorage update, or an update if (persistentParams.persistenceSignature != PersistentParams_t::MAGIC) { persistentParams.persistenceSignature = PersistentParams_t::MAGIC; pstorage_store(&pstorageHandle, reinterpret_cast<uint8_t *>(&persistentParams), sizeof(TimeParams_t), offsetof(PersistentParams_t, params.timeParams) /* offset */); } else { pstorage_update(&pstorageHandle, reinterpret_cast<uint8_t *>(&persistentParams), sizeof(TimeParams_t), offsetof(PersistentParams_t, params.timeParams) /* offset */); } }
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 (!is_word_aligned(p_packet->params.data_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: case DFU_STATE_RX_INIT_PKT: return NRF_ERROR_INVALID_STATE; case DFU_STATE_RX_DATA_PKT: data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t); if ((m_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_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->params.data_packet.p_data_packet; err_code = pstorage_store(mp_storage_handle_active, (uint8_t *)p_data, data_length, m_data_received); if (err_code != NRF_SUCCESS) { return err_code; } m_data_received += data_length; if (m_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 data_length; uint32_t err_code; uint32_t * p_data; VERIFY_PARAM_NOT_NULL(p_packet); // Check pointer alignment. if (!is_word_aligned(p_packet->params.data_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: case DFU_STATE_RX_INIT_PKT: return NRF_ERROR_INVALID_STATE; case DFU_STATE_RX_DATA_PKT: data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t); if ((m_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_data_received = 0xFFFFFFFF; return NRF_ERROR_DATA_SIZE; } // Valid peer activity detected. Hence restart the DFU timer. err_code = dfu_timer_restart(); VERIFY_SUCCESS(err_code); p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet; // Do AES Decrption. dfu_aes_128_ofb_decrypt(p_data, data_length/sizeof(uint32_t), m_data_received); // Check the protected data before copying it and make sure its retain or update the data. uint32_t bootloader_position = m_data_received - m_start_packet.sd_image_size; for (int w = 0; w < data_length/sizeof(uint32_t); w++) { bootloader_position = bootloader_position + 4; if(m_start_packet.bl_image_size > 0 && (m_data_received > m_start_packet.sd_image_size) && (bootloader_position >= ((uint32_t)(&__start_protected_data) - m_uicr_bootloader_start_address))) { if(p_data[w] == 0x00000000) { p_data[w] = 0xFFFFFFFF; } else if(p_data[w] == 0xFFFFFFFF) p_data[w] = (uint32_t)(*((uint32_t *)(bootloader_position - 4 + m_uicr_bootloader_start_address))); } } err_code = pstorage_store(mp_storage_handle_active, (uint8_t *)p_data, data_length, m_data_received); VERIFY_SUCCESS(err_code); m_data_received += data_length; if (m_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; }