robo 8080
/
BLE_TEST_konashi
konashi/SBBLEのテスト
Fork of BLE_LoopbackUART by
Embed:
(wiki syntax)
Show/hide line numbers
pstorage.cpp
00001 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 #if NEED_PSTORAGE /* disabled by default */ 00014 00015 #include <stdlib.h> 00016 #include <stdint.h> 00017 #include <string.h> 00018 #include "nordic_common.h" 00019 #include "nrf_error.h" 00020 #include "nrf_assert.h" 00021 //#include "nrf.h" 00022 #include "nrf_soc.h" 00023 #include "app_util.h " 00024 #include "pstorage.h " 00025 00026 00027 #define INVALID_OPCODE 0x00 /**< Invalid op code identifier. */ 00028 #define SOC_MAX_WRITE_SIZE 1024 /**< Maximum write size allowed for a single call to \ref sd_flash_write as specified in the SoC API. */ 00029 00030 /** 00031 * @defgroup api_param_check API Parameters check macros. 00032 * 00033 * @details Macros that verify parameters passed to the module in the APIs. These macros 00034 * could be mapped to nothing in final versions of code to save execution and size. 00035 * 00036 * @{ 00037 */ 00038 /** 00039 * @brief Check if the input pointer is NULL, if it is returns NRF_ERROR_NULL. 00040 */ 00041 #define NULL_PARAM_CHECK(PARAM) \ 00042 if ((PARAM) == NULL) \ 00043 { \ 00044 return NRF_ERROR_NULL; \ 00045 } 00046 00047 /** 00048 * @brief Verifies the module identifier supplied by the application is within permissible 00049 * range. 00050 */ 00051 #define MODULE_ID_RANGE_CHECK(ID) \ 00052 if ((((ID)->module_id) >= PSTORAGE_MAX_APPLICATIONS) || \ 00053 (m_app_table[(ID)->module_id].cb == NULL)) \ 00054 { \ 00055 return NRF_ERROR_INVALID_PARAM; \ 00056 } 00057 00058 /** 00059 * @brief Verifies the block identifier supplied by the application is within the permissible 00060 * range. 00061 */ 00062 #define BLOCK_ID_RANGE_CHECK(ID) \ 00063 if (((ID)->block_id) >= (m_app_table[(ID)->module_id].base_id + \ 00064 (m_app_table[(ID)->module_id].block_count * MODULE_BLOCK_SIZE(ID)))) \ 00065 { \ 00066 return NRF_ERROR_INVALID_PARAM; \ 00067 } 00068 00069 00070 /** 00071 * @brief Verifies the block size requested by the application can be supported by the module. 00072 */ 00073 #define BLOCK_SIZE_CHECK(X) \ 00074 if (((X) > PSTORAGE_MAX_BLOCK_SIZE) || ((X) < PSTORAGE_MIN_BLOCK_SIZE)) \ 00075 { \ 00076 return NRF_ERROR_INVALID_PARAM; \ 00077 } 00078 00079 /** 00080 * @brief Verifies block size requested by Application in registration API. 00081 */ 00082 #define BLOCK_COUNT_CHECK(COUNT, SIZE) \ 00083 if (((COUNT) == 0) || ((m_next_page_addr + ((COUNT) *(SIZE)) > PSTORAGE_DATA_END_ADDR))) \ 00084 { \ 00085 return NRF_ERROR_INVALID_PARAM; \ 00086 } 00087 00088 /** 00089 * @brief Verifies size parameter provided by application in API. 00090 */ 00091 #define SIZE_CHECK(ID, SIZE) \ 00092 if(((SIZE) == 0) || ((SIZE) > MODULE_BLOCK_SIZE(ID))) \ 00093 { \ 00094 return NRF_ERROR_INVALID_PARAM; \ 00095 } 00096 00097 /** 00098 * @brief Verifies offset parameter provided by application in API. 00099 */ 00100 #define OFFSET_CHECK(ID, OFFSET, SIZE) \ 00101 if(((SIZE) + (OFFSET)) > MODULE_BLOCK_SIZE(ID)) \ 00102 { \ 00103 return NRF_ERROR_INVALID_PARAM; \ 00104 } 00105 00106 #ifdef PSTORAGE_RAW_MODE_ENABLE 00107 00108 /** 00109 * @brief Verifies the module identifier supplied by the application is registered for raw mode. 00110 */ 00111 #define MODULE_RAW_ID_RANGE_CHECK(ID) \ 00112 if ((PSTORAGE_MAX_APPLICATIONS+1 != ((ID)->module_id)) || \ 00113 (m_raw_app_table.cb == NULL)) \ 00114 { \ 00115 return NRF_ERROR_INVALID_PARAM; \ 00116 } 00117 00118 #endif // PSTORAGE_RAW_MODE_ENABLE 00119 00120 /**@} */ 00121 00122 /**@brief Verify module's initialization status. 00123 * 00124 * @details Verify module's initialization status. Returns NRF_ERROR_INVALID_STATE in case a 00125 * module API is called without initializing the module. 00126 */ 00127 #define VERIFY_MODULE_INITIALIZED() \ 00128 do \ 00129 { \ 00130 if (!m_module_initialized) \ 00131 { \ 00132 return NRF_ERROR_INVALID_STATE; \ 00133 } \ 00134 } while(0) 00135 00136 /**@brief Macro to fetch the block size registered for the module. */ 00137 #define MODULE_BLOCK_SIZE(ID) (m_app_table[(ID)->module_id].block_size) 00138 00139 /**@} */ 00140 00141 /** 00142 * @brief Application registration information. 00143 * 00144 * @details Define application specific information that application needs to maintain to be able 00145 * to process requests from each one of them. 00146 */ 00147 typedef struct 00148 { 00149 pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of result of flash access. */ 00150 pstorage_block_t base_id; /**< Base block id assigned to the module */ 00151 pstorage_size_t block_size; /**< Size of block for the module */ 00152 pstorage_size_t block_count; /**< Number of block requested by application */ 00153 pstorage_size_t no_of_pages; /**< Variable to remember how many pages have been allocated for this module. This information is used for clearing of block, so that application does not need to have knowledge of number of pages its using. */ 00154 } pstorage_module_table_t; 00155 00156 #ifdef PSTORAGE_RAW_MODE_ENABLE 00157 /** 00158 * @brief Application registration information. 00159 * 00160 * @details Define application specific information that application registered for raw mode. 00161 */ 00162 typedef struct 00163 { 00164 pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of result of flash access. */ 00165 uint16_t no_of_pages; /**< Variable to remember how many pages have been allocated for this module. This information is used for clearing of block, so that application does not need to have knowledge of number of pages its using. */ 00166 } pstorage_raw_module_table_t; 00167 #endif // PSTORAGE_RAW_MODE_ENABLE 00168 00169 00170 00171 00172 /** 00173 * @brief Defines command queue element. 00174 * 00175 * @details Defines command queue element. Each element encapsulates needed information to process 00176 * a flash access command. 00177 */ 00178 typedef struct 00179 { 00180 uint8_t op_code; /**< Identifies flash access operation being queued. Element is free is op-code is INVALID_OPCODE */ 00181 pstorage_size_t size; /**< Identifies size in bytes requested for the operation. */ 00182 pstorage_size_t offset; /**< Offset requested by the application for access operation. */ 00183 pstorage_handle_t storage_addr; /**< Address/Identifier for persistent memory. */ 00184 uint8_t * p_data_addr; /**< Address/Identifier for data memory. This is assumed to be resident memory. */ 00185 } cmd_queue_element_t; 00186 00187 00188 /** 00189 * @brief Defines command queue, an element is free is op_code field is not invalid. 00190 * 00191 * @details Defines commands enqueued for flash access. At any point of time, this queue has one or 00192 * more flash access operation pending if the count field is not zero. When the queue is 00193 * not empty, the rp (read pointer) field points to the flash access command in progress 00194 * or to requested next. The queue implements a simple first in first out algorithm. 00195 * Data addresses are assumed to be resident. 00196 */ 00197 typedef struct 00198 { 00199 uint8_t rp; /**< Read pointer, pointing to flash access that is ongoing or to be requested next. */ 00200 uint8_t count; /**< Number of elements in the queue. */ 00201 bool flash_access; /**< Flag to ensure an flash event received is for an request issued by the module. */ 00202 cmd_queue_element_t cmd[PSTORAGE_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details */ 00203 }cmd_queue_t; 00204 00205 static cmd_queue_t m_cmd_queue; /**< Flash operation request queue. */ 00206 static pstorage_module_table_t m_app_table[PSTORAGE_MAX_APPLICATIONS]; /**< Registered application information table. */ 00207 00208 #ifdef PSTORAGE_RAW_MODE_ENABLE 00209 static pstorage_raw_module_table_t m_raw_app_table; /**< Registered application information table for raw mode. */ 00210 #endif // PSTORAGE_RAW_MODE_ENABLE 00211 00212 static pstorage_size_t m_next_app_instance; /**< Points to the application module instance that can be allocated next */ 00213 static uint32_t m_next_page_addr; /**< Points to the flash address that can be allocated to a module next, this is needed as blocks of a module can span across flash pages. */ 00214 static bool m_module_initialized = false; /**< Flag for checking if module has been initialized. */ 00215 static pstorage_size_t m_round_val; /**< Round value for multiple round operations. For erase operations, the round value will contain current round counter which is identical to number of pages erased. For store operations, the round value contains current round of operation * SOC_MAX_WRITE_SIZE to ensure each store to the SoC Flash API is within the SoC limit. */ 00216 00217 static uint32_t process_cmd(void); 00218 static void app_notify (uint32_t reason); 00219 00220 /** 00221 * @defgroup utility_functions Utility internal functions. 00222 * @{ 00223 * @details Utility functions needed for interfacing with flash through SoC APIs. 00224 * SoC APIs are non blocking and provide the result of flash access through an event. 00225 * 00226 * @note Only one flash access operation is permitted at a time by SoC. Hence a queue is 00227 * maintained by this module. 00228 */ 00229 00230 /** 00231 * @brief Initializes command queue element. 00232 */ 00233 static void cmd_queue_init_element(uint32_t index) 00234 { 00235 // Internal function and checks on range of index can be avoided 00236 m_cmd_queue.cmd[index].op_code = INVALID_OPCODE; 00237 m_cmd_queue.cmd[index].size = 0; 00238 m_cmd_queue.cmd[index].storage_addr.module_id = PSTORAGE_MAX_APPLICATIONS; 00239 m_cmd_queue.cmd[index].storage_addr.block_id = 0; 00240 m_cmd_queue.cmd[index].p_data_addr = NULL; 00241 m_cmd_queue.cmd[index].offset = 0; 00242 } 00243 00244 00245 /** 00246 * @brief Initializes command queue. 00247 */ 00248 static void cmd_queue_init (void) 00249 { 00250 uint32_t cmd_index; 00251 00252 m_round_val = 0; 00253 m_cmd_queue.rp = 0; 00254 m_cmd_queue.count = 0; 00255 m_cmd_queue.flash_access = false; 00256 00257 for(cmd_index = 0; cmd_index < PSTORAGE_CMD_QUEUE_SIZE; cmd_index++) 00258 { 00259 cmd_queue_init_element(cmd_index); 00260 } 00261 } 00262 00263 00264 /** 00265 * @brief Routine to enqueue a flash access operation. 00266 */ 00267 static uint32_t cmd_queue_enqueue(uint8_t opcode, pstorage_handle_t * p_storage_addr,uint8_t * p_data_addr, pstorage_size_t size, pstorage_size_t offset) 00268 { 00269 uint32_t retval; 00270 uint8_t write_index = 0; 00271 retval = NRF_ERROR_NO_MEM; 00272 00273 // Check if flash access is ongoing. 00274 if ((m_cmd_queue.flash_access == false) && (m_cmd_queue.count == 0)) 00275 { 00276 m_cmd_queue.rp = 0; 00277 m_cmd_queue.cmd[m_cmd_queue.rp].op_code = opcode; 00278 m_cmd_queue.cmd[m_cmd_queue.rp].p_data_addr = p_data_addr; 00279 m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr = (*p_storage_addr); 00280 m_cmd_queue.cmd[m_cmd_queue.rp].size = size; 00281 m_cmd_queue.cmd[m_cmd_queue.rp].offset = offset; 00282 m_cmd_queue.count++; 00283 retval = process_cmd(); 00284 if ((retval == NRF_SUCCESS) || (retval == NRF_ERROR_BUSY)) 00285 { 00286 // In case of busy error code, it is possible to attempt to access flash 00287 retval = NRF_SUCCESS; 00288 } 00289 } 00290 else if (m_cmd_queue.count != PSTORAGE_CMD_QUEUE_SIZE) 00291 { 00292 // Enqueue the command if it is queue is not full 00293 write_index = m_cmd_queue.rp + m_cmd_queue.count; 00294 00295 if (write_index >= PSTORAGE_CMD_QUEUE_SIZE) 00296 { 00297 write_index -= PSTORAGE_CMD_QUEUE_SIZE; 00298 } 00299 00300 m_cmd_queue.cmd[write_index].op_code = opcode; 00301 m_cmd_queue.cmd[write_index].p_data_addr = p_data_addr; 00302 m_cmd_queue.cmd[write_index].storage_addr = (*p_storage_addr); 00303 m_cmd_queue.cmd[write_index].size = size; 00304 m_cmd_queue.cmd[write_index].offset = offset; 00305 m_cmd_queue.count++; 00306 00307 retval = NRF_SUCCESS; 00308 00309 } 00310 00311 return retval; 00312 } 00313 00314 00315 /** 00316 * @brief Dequeues a command element. 00317 */ 00318 static uint32_t cmd_queue_dequeue(void) 00319 { 00320 uint32_t retval; 00321 00322 cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 00323 // Update count and read pointer to process any queued requests 00324 if(m_round_val >= p_cmd->size) 00325 { 00326 // Initialize/free the element as it is now processed. 00327 cmd_queue_init_element(m_cmd_queue.rp); 00328 m_round_val = 0; 00329 m_cmd_queue.count--; 00330 m_cmd_queue.rp++; 00331 } 00332 00333 retval = NRF_SUCCESS; 00334 00335 // If any flash operation is enqueued, schedule 00336 if (m_cmd_queue.count) 00337 { 00338 retval = process_cmd(); 00339 00340 if (retval != NRF_SUCCESS) 00341 { 00342 // Flash could be accessed by modules other than Bond Manager, hence a busy error is 00343 // acceptable, but any other error needs to be indicated to the bond manager 00344 if (retval != NRF_ERROR_BUSY) 00345 { 00346 app_notify (retval); 00347 } 00348 else 00349 { 00350 // In case of busy next trigger will be a success or a failure event 00351 } 00352 } 00353 } 00354 else 00355 { 00356 // No flash access request pending 00357 } 00358 00359 return retval; 00360 } 00361 00362 00363 /** 00364 * @brief Routine to notify application of any errors. 00365 */ 00366 static void app_notify (uint32_t result) 00367 { 00368 pstorage_ntf_cb_t ntf_cb; 00369 uint8_t op_code = m_cmd_queue.cmd[m_cmd_queue.rp].op_code; 00370 00371 #ifdef PSTORAGE_RAW_MODE_ENABLE 00372 if(m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr.module_id == (PSTORAGE_MAX_APPLICATIONS + 1)) 00373 { 00374 ntf_cb = m_raw_app_table.cb; 00375 } 00376 else 00377 #endif // PSTORAGE_RAW_MODE_ENABLE 00378 { 00379 ntf_cb = m_app_table[m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr.module_id].cb; 00380 } 00381 00382 // Indicate result to client. 00383 // For PSTORAGE_CLEAR_OP_CODE no size is returned as the size field is used only internally 00384 // for clients registering multiple pages. 00385 ntf_cb(&m_cmd_queue.cmd[m_cmd_queue.rp].storage_addr, 00386 op_code, 00387 result, 00388 m_cmd_queue.cmd[m_cmd_queue.rp].p_data_addr, 00389 op_code == PSTORAGE_CLEAR_OP_CODE ? 0 : m_cmd_queue.cmd[m_cmd_queue.rp].size); 00390 } 00391 00392 00393 /** 00394 * @brief Handles Flash Access Result Events. 00395 */ 00396 void pstorage_sys_event_handler (uint32_t sys_evt) 00397 { 00398 uint32_t retval; 00399 00400 retval = NRF_SUCCESS; 00401 00402 // Its possible the flash access was not initiated by bond manager, hence 00403 // event is processed only if the event triggered was for an operation requested by the 00404 // bond manager. 00405 if (m_cmd_queue.flash_access == true) 00406 { 00407 cmd_queue_element_t * p_cmd; 00408 m_cmd_queue.flash_access = false; 00409 switch (sys_evt) 00410 { 00411 case NRF_EVT_FLASH_OPERATION_SUCCESS: 00412 p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 00413 if ((p_cmd->op_code != PSTORAGE_CLEAR_OP_CODE) || (m_round_val >= p_cmd->size)) 00414 { 00415 app_notify(retval); 00416 } 00417 // Schedule any queued flash access operations 00418 retval = cmd_queue_dequeue (); 00419 if (retval != NRF_SUCCESS) 00420 { 00421 app_notify(retval); 00422 } 00423 00424 break; 00425 case NRF_EVT_FLASH_OPERATION_ERROR: 00426 app_notify(NRF_ERROR_TIMEOUT); 00427 break; 00428 default: 00429 // No implementation needed. 00430 break; 00431 } 00432 } 00433 } 00434 00435 00436 /** 00437 * @brief Routine called to actually issue the flash access request to the SoftDevice. 00438 */ 00439 static uint32_t process_cmd(void) 00440 { 00441 uint32_t retval; 00442 uint32_t storage_addr; 00443 cmd_queue_element_t * p_cmd; 00444 00445 retval = NRF_ERROR_FORBIDDEN; 00446 00447 p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; 00448 00449 storage_addr = p_cmd->storage_addr.block_id; 00450 00451 if (p_cmd->op_code == PSTORAGE_CLEAR_OP_CODE) 00452 { 00453 // Calculate page number before copy. 00454 uint32_t page_number; 00455 00456 page_number = ((storage_addr / PSTORAGE_FLASH_PAGE_SIZE) + 00457 m_round_val); 00458 00459 retval = sd_flash_page_erase(page_number); 00460 00461 if (NRF_SUCCESS == retval) 00462 { 00463 m_round_val++; 00464 } 00465 } 00466 else if (p_cmd->op_code == PSTORAGE_STORE_OP_CODE) 00467 { 00468 uint32_t size; 00469 uint8_t * p_data_addr = p_cmd->p_data_addr; 00470 00471 p_data_addr += m_round_val; 00472 00473 storage_addr += (p_cmd->offset + m_round_val); 00474 00475 size = p_cmd->size - m_round_val; 00476 00477 if (size < SOC_MAX_WRITE_SIZE) 00478 { 00479 retval = sd_flash_write(((uint32_t *)storage_addr), 00480 (uint32_t *)p_data_addr, 00481 size / sizeof(uint32_t)); 00482 } 00483 else 00484 { 00485 retval = sd_flash_write(((uint32_t *)storage_addr), 00486 (uint32_t *)p_data_addr, 00487 SOC_MAX_WRITE_SIZE / sizeof(uint32_t)); 00488 } 00489 00490 00491 if (retval == NRF_SUCCESS) 00492 { 00493 m_round_val += SOC_MAX_WRITE_SIZE; 00494 } 00495 } 00496 else 00497 { 00498 // Should never reach here. 00499 } 00500 00501 if (retval == NRF_SUCCESS) 00502 { 00503 m_cmd_queue.flash_access = true; 00504 } 00505 00506 return retval; 00507 } 00508 /** @} */ 00509 00510 00511 /** 00512 * @brief Module initialization routine to be called once by the application. 00513 */ 00514 uint32_t pstorage_init(void) 00515 { 00516 unsigned int index; 00517 cmd_queue_init(); 00518 00519 m_next_app_instance = 0; 00520 m_next_page_addr = PSTORAGE_DATA_START_ADDR; 00521 m_round_val = 0; 00522 00523 for(index = 0; index < PSTORAGE_MAX_APPLICATIONS; index++) 00524 { 00525 m_app_table[index].cb = NULL; 00526 m_app_table[index].block_size = 0; 00527 m_app_table[index].no_of_pages = 0; 00528 m_app_table[index].block_count = 0; 00529 } 00530 00531 #ifdef PSTORAGE_RAW_MODE_ENABLE 00532 m_raw_app_table.cb = NULL; 00533 m_raw_app_table.no_of_pages = 0; 00534 #endif //PSTORAGE_RAW_MODE_ENABLE 00535 00536 m_module_initialized = true; 00537 return NRF_SUCCESS; 00538 } 00539 00540 /** 00541 * @brief Registration routine to request persistent memory of certain sizes based on 00542 * application module requirements. 00543 */ 00544 uint32_t pstorage_register(pstorage_module_param_t * p_module_param, 00545 pstorage_handle_t * p_block_id) 00546 { 00547 uint16_t page_count; 00548 uint32_t total_size; 00549 00550 VERIFY_MODULE_INITIALIZED(); 00551 NULL_PARAM_CHECK(p_module_param); 00552 NULL_PARAM_CHECK(p_block_id); 00553 NULL_PARAM_CHECK(p_module_param->cb); 00554 BLOCK_SIZE_CHECK(p_module_param->block_size); 00555 BLOCK_COUNT_CHECK(p_module_param->block_count, p_module_param->block_size); 00556 00557 if (m_next_app_instance == PSTORAGE_MAX_APPLICATIONS) 00558 { 00559 return NRF_ERROR_NO_MEM; 00560 } 00561 00562 p_block_id->module_id = m_next_app_instance; 00563 p_block_id->block_id = m_next_page_addr; 00564 m_app_table[m_next_app_instance].base_id = p_block_id->block_id; 00565 m_app_table[m_next_app_instance].cb = p_module_param->cb; 00566 m_app_table[m_next_app_instance].block_size = p_module_param->block_size; 00567 m_app_table[m_next_app_instance].block_count = p_module_param->block_count; 00568 00569 // Calculate number of flash pages allocated for the device. 00570 page_count = 0; 00571 total_size = p_module_param->block_size * p_module_param->block_count; 00572 do 00573 { 00574 page_count++; 00575 if (total_size > PSTORAGE_FLASH_PAGE_SIZE) 00576 { 00577 total_size -= PSTORAGE_FLASH_PAGE_SIZE; 00578 } 00579 else 00580 { 00581 total_size = 0; 00582 } 00583 m_next_page_addr += PSTORAGE_FLASH_PAGE_SIZE; 00584 }while(total_size >= PSTORAGE_FLASH_PAGE_SIZE); 00585 00586 m_app_table[m_next_app_instance].no_of_pages = page_count; 00587 m_next_app_instance++; 00588 00589 return NRF_SUCCESS; 00590 } 00591 00592 00593 /** 00594 * @brief API to get the next block identifier. 00595 */ 00596 uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id, 00597 pstorage_size_t block_num, 00598 pstorage_handle_t * p_block_id) 00599 { 00600 pstorage_handle_t temp_id; 00601 00602 VERIFY_MODULE_INITIALIZED(); 00603 NULL_PARAM_CHECK(p_base_id); 00604 NULL_PARAM_CHECK(p_block_id); 00605 MODULE_ID_RANGE_CHECK(p_base_id); 00606 00607 temp_id = (*p_base_id); 00608 temp_id.block_id += (block_num * MODULE_BLOCK_SIZE(p_base_id)); 00609 BLOCK_ID_RANGE_CHECK(&temp_id); 00610 (*p_block_id) = temp_id; 00611 00612 return NRF_SUCCESS; 00613 } 00614 00615 00616 /** 00617 * @brief API to store data persistently. 00618 */ 00619 uint32_t pstorage_store(pstorage_handle_t * p_dest, 00620 uint8_t * p_src, 00621 pstorage_size_t size, 00622 pstorage_size_t offset) 00623 { 00624 VERIFY_MODULE_INITIALIZED(); 00625 NULL_PARAM_CHECK(p_src); 00626 NULL_PARAM_CHECK(p_dest); 00627 MODULE_ID_RANGE_CHECK (p_dest); 00628 BLOCK_ID_RANGE_CHECK(p_dest); 00629 SIZE_CHECK(p_dest,size); 00630 OFFSET_CHECK(p_dest,offset,size); 00631 00632 // Verify word alignment. 00633 if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset))) 00634 { 00635 return NRF_ERROR_INVALID_ADDR; 00636 } 00637 00638 return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); 00639 } 00640 00641 00642 /** 00643 * @brief API to load data from persistent memory. 00644 */ 00645 uint32_t pstorage_load(uint8_t * p_dest, 00646 pstorage_handle_t * p_src, 00647 pstorage_size_t size, 00648 pstorage_size_t offset) 00649 { 00650 VERIFY_MODULE_INITIALIZED(); 00651 NULL_PARAM_CHECK(p_src); 00652 NULL_PARAM_CHECK(p_dest); 00653 MODULE_ID_RANGE_CHECK (p_src); 00654 BLOCK_ID_RANGE_CHECK(p_src); 00655 SIZE_CHECK(p_src,size); 00656 OFFSET_CHECK(p_src,offset,size); 00657 00658 // Verify word alignment. 00659 if ((!is_word_aligned (p_dest)) || (!is_word_aligned (p_dest + offset))) 00660 { 00661 return NRF_ERROR_INVALID_ADDR; 00662 } 00663 00664 memcpy (p_dest, (((uint8_t *)p_src->block_id) + offset), size); 00665 00666 return NRF_SUCCESS; 00667 } 00668 00669 00670 /** 00671 * @brief API to clear data in blocks of persistent memory. 00672 */ 00673 uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size) 00674 { 00675 uint32_t retval; 00676 uint32_t pages; 00677 00678 VERIFY_MODULE_INITIALIZED(); 00679 NULL_PARAM_CHECK(p_dest); 00680 MODULE_ID_RANGE_CHECK(p_dest); 00681 BLOCK_ID_RANGE_CHECK(p_dest); 00682 00683 pages = m_app_table[p_dest->module_id].no_of_pages; 00684 00685 retval = cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL , pages , 0); 00686 00687 return retval; 00688 } 00689 00690 00691 #ifdef PSTORAGE_RAW_MODE_ENABLE 00692 00693 /** 00694 * @brief Registration routine to request persistent memory of certain sizes based on 00695 * application module requirements. 00696 */ 00697 uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param, 00698 pstorage_handle_t * p_block_id) 00699 { 00700 VERIFY_MODULE_INITIALIZED(); 00701 NULL_PARAM_CHECK(p_module_param); 00702 NULL_PARAM_CHECK(p_block_id); 00703 NULL_PARAM_CHECK(p_module_param->cb); 00704 00705 if (m_raw_app_table.cb != NULL) 00706 { 00707 return NRF_ERROR_NO_MEM; 00708 } 00709 00710 p_block_id->module_id = PSTORAGE_MAX_APPLICATIONS + 1; 00711 m_raw_app_table.cb = p_module_param->cb; 00712 00713 return NRF_SUCCESS; 00714 } 00715 00716 00717 /** 00718 * @brief API to store data persistently. 00719 */ 00720 uint32_t pstorage_raw_store(pstorage_handle_t * p_dest, 00721 uint8_t * p_src, 00722 uint32_t size, 00723 uint32_t offset) 00724 { 00725 VERIFY_MODULE_INITIALIZED(); 00726 NULL_PARAM_CHECK(p_src); 00727 NULL_PARAM_CHECK(p_dest); 00728 MODULE_RAW_ID_RANGE_CHECK(p_dest); 00729 00730 // Verify word alignment. 00731 if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset))) 00732 { 00733 return NRF_ERROR_INVALID_ADDR; 00734 } 00735 00736 return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); 00737 } 00738 00739 00740 /** 00741 * @brief API to clear data in blocks of persistent memory. 00742 */ 00743 uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, uint32_t size) 00744 { 00745 uint32_t retval; 00746 uint32_t pages; 00747 00748 VERIFY_MODULE_INITIALIZED(); 00749 NULL_PARAM_CHECK(p_dest); 00750 MODULE_RAW_ID_RANGE_CHECK(p_dest); 00751 00752 retval = NRF_SUCCESS; 00753 00754 pages = CEIL_DIV(size, PSTORAGE_FLASH_PAGE_SIZE); 00755 00756 retval = cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL , pages, 0); 00757 00758 return retval; 00759 } 00760 00761 #endif // PSTORAGE_RAW_MODE_ENABLE 00762 #endif /* #if NEED_PSTORAGE */
Generated on Tue Jul 12 2022 20:35:46 by 1.7.2