nRF51/52 : Pstorage (Flash , Non-volatile Memory) Operation
发布时间:2020-12-15 19:57:40 所属栏目:百科 来源:网络整理
导读:? ? It is very requisite for internet of thing (IoT) application to have a non-volatile memory,it could keep the status when the battery runs out. ?? In nRF51/52 series,the flash is called as "Persistent storage",the APIs of this kind are
? ? It is very requisite for internet of thing (IoT) application to have a non-volatile memory,it could keep the status when the battery runs out. ?? In nRF51/52 series,the flash is called as "Persistent storage",the APIs of this kind are begin from pstorage. ?? There are examples and guild for how to exploit the pstorag,but I found those are not concise enough. So in here,I would demonstrate how to call the pstorage api in practice case. ? Continue from my previous post,I want to add code of pstorage in that. ? Add Below code about line 603 : static void power_manage(void) { uint32_t err_code = sd_app_evt_wait(); APP_ERROR_CHECK(err_code); } #ifndef FALSE #define FALSE (0) #define TRUE (1) #endif #define UART_TX_BUF_SIZE (256) #define UART_RX_BUF_SIZE (256) #define APP_BLOCK_SIZE (32) pstorage_handle_t m_app_storage_base_handle; static uint8_t m_is_need_to_wait_pstorage_operation = FALSE; static pstorage_block_t m_pstorage_operation_block_id = 0; unsigned char m_pstorage_buffer[APP_BLOCK_SIZE]; void app_storage_save_data(void); void app_storage_print_stored_data(void); /** * @brief UART events handler. */ void uart_events_handler(app_uart_evt_t * p_event) { switch (p_event->evt_type) { case APP_UART_DATA_READY: { unsigned char received_char; UNUSED_VARIABLE(app_uart_get(&received_char)); if('~' == received_char) { app_storage_print_stored_data(); NVIC_SystemReset(); } { sprintf((char*)&m_pstorage_buffer[0], " received char = %crn", received_char); pstorage_handle_t block_handle; pstorage_block_identifier_get(&m_app_storage_base_handle, 0, &block_handle); /* m_pstorage_operation_block_id = block_handle.block_id; m_is_need_to_wait_pstorage_operation = TRUE; */ uint32_t err_code; err_code = pstorage_update(&block_handle, &m_pstorage_buffer[0], APP_BLOCK_SIZE, 0); APP_ERROR_CHECK(err_code); printf("storing str :"%s" into flashrn", (char*)&m_pstorage_buffer[0]); }/*store data to flash block*/ } break; case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication); break; case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER(p_event->data.error_code); break; case APP_UART_TX_EMPTY: break; case APP_UART_DATA: break; default: break; } } /** * @brief UART initialization. */ void uart_config(void) { uint32_t err_code; const app_uart_comm_params_t comm_params = { RX_PIN_NUMBER, TX_PIN_NUMBER, RTS_PIN_NUMBER, CTS_PIN_NUMBER, APP_UART_FLOW_CONTROL_DISABLED, false, UART_BAUDRATE_BAUDRATE_Baud38400 }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_events_handler, APP_IRQ_PRIORITY_LOW, err_code); APP_ERROR_CHECK(err_code); }/*uart_config*/ // Event Notification Handler. static void app_storage_callback_handler(pstorage_handle_t * handle, uint8_t op_code, uint32_t result, uint8_t * p_data, uint32_t data_len) { if(handle->block_id == m_pstorage_operation_block_id) m_is_need_to_wait_pstorage_operation = FALSE; switch(op_code) { case PSTORAGE_STORE_OP_CODE: if(NRF_SUCCESS != result) printf("pstorage STORE ERROR callback received rn"); break; case PSTORAGE_LOAD_OP_CODE: if(NRF_SUCCESS != result) printf("pstorage LOAD ERROR callback received rn"); break; case PSTORAGE_CLEAR_OP_CODE: if(NRF_SUCCESS != result) printf("pstorage CLEAR ERROR callback received rn"); break; case PSTORAGE_UPDATE_OP_CODE: if(NRF_SUCCESS != result) printf("pstorage UPDATE ERROR callback received rn"); break; default: printf("pstorage ERROR callback received rn"); break; } }/*app_storage_callback_handler*/ /** * @brief pstorage initializing and block register */ void app_storage_init() { uint32_t err_code; err_code = pstorage_init(); APP_ERROR_CHECK(err_code); pstorage_module_param_t pstorage_param; pstorage_param.block_size = APP_BLOCK_SIZE; pstorage_param.block_count = 1; pstorage_param.cb = app_storage_callback_handler; err_code = pstorage_register(&pstorage_param, &m_app_storage_base_handle); APP_ERROR_CHECK(err_code); #if(0) { pstorage_handle_t block_handle; pstorage_block_identifier_get(&m_app_storage_base_handle, 0, &block_handle); m_pstorage_operation_block_id = block_handle.block_id; m_is_need_to_wait_pstorage_operation = TRUE; err_code = pstorage_clear(&block_handle, APP_BLOCK_SIZE); APP_ERROR_CHECK(err_code); while(FALSE != m_is_need_to_wait_pstorage_operation) power_manage(); }/*clear data block*/ #endif }/*pstorage_init_store_and_update*/ void app_storage_save_data(void) { uint32_t err_code; #if(0) { pstorage_handle_t block_handle; pstorage_block_identifier_get(&m_app_storage_base_handle, APP_BLOCK_SIZE); APP_ERROR_CHECK(err_code); while(FALSE != m_is_need_to_wait_pstorage_operation) power_manage(); }/*clear data block*/ #endif { pstorage_handle_t block_handle; pstorage_block_identifier_get(&m_app_storage_base_handle, 0, &block_handle); m_pstorage_operation_block_id = block_handle.block_id; m_is_need_to_wait_pstorage_operation = TRUE; //err_code = pstorage_store(&block_handle,&m_pstorage_buffer[0], // APP_BLOCK_SIZE,0); err_code = pstorage_update(&block_handle, APP_BLOCK_SIZE, 0); APP_ERROR_CHECK(err_code); while(FALSE != m_is_need_to_wait_pstorage_operation) power_manage(); }/*store code block*/ }/*app_storage_save_data*/ void app_storage_print_stored_data(void) { uint32_t err_code; unsigned char storedData[APP_BLOCK_SIZE]; pstorage_handle_t block_handle; err_code = pstorage_block_identifier_get(&m_app_storage_base_handle, 0, &block_handle); APP_ERROR_CHECK(err_code); err_code = pstorage_load(&storedData[0], &block_handle, APP_BLOCK_SIZE, 0); APP_ERROR_CHECK(err_code); { printf("%srn", &storedData[0]); } }/*app_storage_print_stored_data*/ /**@brief Function for application main entry. */ int main(void) { uint32_t err_code; bool erase_bonds; uart_config(); printf("Start...rn"); // Initialize. timers_init(); buttons_leds_init(&erase_bonds); ble_stack_init(); app_storage_init(); app_storage_print_stored_data(); sprintf((char*)&m_pstorage_buffer[0], "new boot stringnr"); { pstorage_handle_t block_handle; pstorage_block_identifier_get(&m_app_storage_base_handle, &m_pstorage_buffer[0], 0); APP_ERROR_CHECK(err_code); while(FALSE != m_is_need_to_wait_pstorage_operation) power_manage(); }/*store code block*/ app_storage_print_stored_data(); device_manager_init(erase_bonds); gap_params_init();? You could use serial tool (like sscom..etc) to write data (a character) to pstorage. ?for example,when I send 'a' via uart,the flash would be written the string" received char = a". When you send '~' the nRF51/52 would reboot,? you could find that the string in pstorage would be kept. Here is the knacks for using pstorage: 零. The block size should be align of 4,of course. 一. The initialization function pstorage_init (in my case,within the function pstorage_init),should be called after function ble_stack_init. If you call it before? ble_stack_init,the function pstorage_init might lead the system reboot ceaselessly. It is not necessary to call pstorage_init after? ble_stack_init Immediately,you could call it after the advertise has been started. 二. Before calling the function pstorage_store,it is necessary to call function pstorage_clear,Or the storing action should not be done : the flash contain would not be update. The alternative way is to call function pstorage_update,which is the combination of pstorage_clear and pstorage_store. 三. When the functions pstorage_store/pstorage_update/pstorage_clear,it costs time to complete the action after the functions have returned. In the main "thread",I adopt a global flag (m_is_need_to_wait_pstorage_operation),while loop and function power_manage to wait the pstorage has been updated indeed,that is like: { pstorage_handle_t block_handle; pstorage_block_identifier_get(&m_app_storage_base_handle, &block_handle); m_pstorage_operation_block_id = block_handle.block_id; m_is_need_to_wait_pstorage_operation = TRUE; //err_code = pstorage_store(&block_handle, 0); APP_ERROR_CHECK(err_code); while(FALSE != m_is_need_to_wait_pstorage_operation) power_manage(); }/*store code block*/ In the pstorage handler callback function : // Event Notification Handler. static void app_storage_callback_handler(pstorage_handle_t * handle, uint32_t data_len) { if(handle->block_id == m_pstorage_operation_block_id) m_is_need_to_wait_pstorage_operation = FALSE; switch(op_code) { case PSTORAGE_STORE_OP_CODE: that could ensure the data be stored into pstorage. But inside the interrupt callback,calling power_manage would lead system hanging. Therefore,in the uart event handler callback,i do not call the power_manage function: /** * @brief UART events handler. */ void uart_events_handler(app_uart_evt_t * p_event) { switch (p_event->evt_type) { case APP_UART_DATA_READY: { unsigned char received_char; UNUSED_VARIABLE(app_uart_get(&received_char)); if('~' == received_char) { app_storage_print_stored_data(); NVIC_SystemReset(); } { sprintf((char*)&m_pstorage_buffer[0], &block_handle); /* m_pstorage_operation_block_id = block_handle.block_id; m_is_need_to_wait_pstorage_operation = TRUE; */ uint32_t err_code; err_code = pstorage_update(&block_handle, (char*)&m_pstorage_buffer[0]); }/*store data to flash block*/ } break; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |