Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
cs_nvm.c
00001 /* 00002 * Copyright (c) 2016 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /* 00018 * NVM adaptation to Configuration Store that is storing Key-Value pairs to SRAM or flash. 00019 */ 00020 00021 /* 00022 * Application needs to enable MBED_CONF_NANOSTACK_HAL_NVM_CFSTORE in its configuration in 00023 * order to use configuration-store. Application also needs to define storage area start 00024 * address in flash (CONFIG_HARDWARE_MTD_START_ADDR) and storage size (CONFIG_HARDWARE_MTD_SIZE). 00025 */ 00026 #if MBED_CONF_NANOSTACK_HAL_NVM_CFSTORE 00027 00028 #include <stdio.h> 00029 #include <string.h> 00030 #include <ns_types.h> 00031 #include "configuration-store/configuration_store.h" 00032 // #define HAVE_DEBUG 00033 #include "ns_trace.h" 00034 #include "nsdynmemLIB.h" 00035 #include "eventOS_event_timer.h" 00036 #include "platform/arm_hal_nvm.h" 00037 00038 #define TRACE_GROUP "pnvm" 00039 00040 // Timeout for polling response from configuration store 00041 #define NVM_CB_POLLING_TIMEOUT 50 00042 00043 // Check if synchronous mode is enabled 00044 #define IS_SYNC_MODE(cs_ctx) ((cs_ctx)->capabilities.asynchronous_ops == 0) 00045 00046 // NVM internal states 00047 typedef enum cfstore_state_t { 00048 NVM_STATE_NONE, 00049 NVM_STATE_INIT_DONE, 00050 NVM_STATE_CREATING, 00051 NVM_STATE_CREATE_DONE, 00052 NVM_STATE_OPENING, 00053 NVM_STATE_OPEN_DONE, 00054 NVM_STATE_WRITING, 00055 NVM_STATE_WRITE_DONE, 00056 NVM_STATE_CLOSING, 00057 NVM_STATE_CLOSE_DONE, 00058 NVM_STATE_FLUSHING, 00059 NVM_STATE_FLUSH_DONE, 00060 NVM_STATE_READING, 00061 NVM_STATE_READ_DONE, 00062 NVM_STATE_DELETING, 00063 NVM_STATE_DELETE_DONE, 00064 NVM_STATE_UNINITIALIZING, 00065 NVM_STATE_UNINIT_DONE 00066 } nvm_state_e; 00067 00068 // NVM context 00069 typedef struct cfstore_context_s { 00070 ARM_CFSTORE_CAPABILITIES capabilities; 00071 //TODO: Fix hkey length once CFSTORE_HANDLE_BUFSIZE becomes visible 00072 uint8_t hkey[/*CFSTORE_HANDLE_BUFSIZE*/40]; // Handle to the key in process 00073 ARM_CFSTORE_SIZE data_len; // Data length cfstore is using 00074 nvm_state_e state; // current nvm_state_e 00075 timeout_t *callback_timer; // timer handle for informing client 00076 nvm_callback *client_cb; // callback provided by client 00077 void *client_context; // context provided by client 00078 platform_nvm_status client_status; // status to be returned to client 00079 uint8_t *client_buf; // buffer provided by client 00080 uint16_t *client_buf_len; // client buffer length 00081 } cs_context_t; 00082 00083 ARM_CFSTORE_DRIVER *drv = &cfstore_driver; 00084 static cs_context_t *cs_context_ptr = NULL; 00085 00086 // forward declarations 00087 static bool nvm_write_internal(cs_context_t *cf_context); 00088 static bool nvm_read_internal(cs_context_t *cf_context); 00089 static bool nvm_delete_internal(cs_context_t *cf_context); 00090 static bool nvm_close_internal(cs_context_t *cf_context); 00091 static bool nvm_status_check(cs_context_t *cf_context); 00092 static platform_nvm_status nvm_error_map(int32_t cs_error); 00093 static void nvm_fsm_timer_start(void); 00094 static void nvm_fsm_timer_cb(void *arg); 00095 00096 /** 00097 * Configuration store callback 00098 */ 00099 static void configuration_store_cb(int32_t status, ARM_CFSTORE_OPCODE cmd_code, void *ctx, ARM_CFSTORE_HANDLE handle) 00100 { 00101 tr_debug("configuration_store_cb status=%d, cmd_code=%d, ctx=%x, hndl=%x", (int)status, (int)cmd_code, (unsigned int)ctx, (unsigned int)handle); 00102 cs_context_t *cf_context = (cs_context_t*)ctx; 00103 00104 switch(cmd_code) { 00105 case CFSTORE_OPCODE_INITIALIZE: 00106 tr_debug("CFSTORE_OPCODE_INITIALIZE %d", (int)status); 00107 cf_context->state = NVM_STATE_INIT_DONE; 00108 cf_context->client_status = nvm_error_map(status); 00109 break; 00110 case CFSTORE_OPCODE_POWER_CONTROL: 00111 tr_debug("CFSTORE_OPCODE_POWER_CONTROL %d", (int)status); 00112 // do nothing for power control 00113 break; 00114 case CFSTORE_OPCODE_CREATE: 00115 tr_debug("CFSTORE_OPCODE_CREATE %d", (int)status); 00116 cf_context->client_status = nvm_error_map(status); 00117 cf_context->state = NVM_STATE_CREATE_DONE; 00118 if (status >= ARM_DRIVER_OK) { 00119 // key created successfully, close the key 00120 if (nvm_close_internal(cf_context) == false) { 00121 // closing failed 00122 // Ignore errors in close as closing recreated keys returns error 00123 // cf_context->state = NVM_STATE_CLOSE_DONE; 00124 // cf_context->client_status = PLATFORM_NVM_ERROR; 00125 } else { 00126 // closing OK, wait for CFSTORE_OPCODE_CLOSE callback 00127 } 00128 } 00129 break; 00130 case CFSTORE_OPCODE_OPEN: 00131 tr_debug("CFSTORE_OPCODE_OPEN %d", (int)status); 00132 if (status < ARM_DRIVER_OK) { 00133 // opening failed, do not continue any further 00134 cf_context->client_status = nvm_error_map(status); 00135 cf_context->state = NVM_STATE_OPEN_DONE; 00136 break; 00137 } 00138 // proceed to client action read/write/delete 00139 if (cf_context->state == NVM_STATE_WRITING) { 00140 if (nvm_write_internal(cf_context) == false) { 00141 /* reading failed set client_status */ 00142 cf_context->client_status = PLATFORM_NVM_ERROR; 00143 } else { 00144 // writing OK, wait for CFSTORE_OPCODE_WRITE callback 00145 } 00146 } else if (cf_context->state == NVM_STATE_READING) { 00147 if (nvm_read_internal(cf_context) == false) { 00148 /* reading failed set client_status */ 00149 cf_context->client_status = PLATFORM_NVM_ERROR; 00150 } else { 00151 // reading in progress, wait for CFSTORE_OPCODE_READ callback 00152 } 00153 } else if (cf_context->state == NVM_STATE_DELETING) { 00154 if (nvm_delete_internal(cf_context) == false) { 00155 /* reading failed set client_status */ 00156 cf_context->client_status = PLATFORM_NVM_ERROR; 00157 } else { 00158 // deleting in progress, wait for CFSTORE_OPCODE_DELETE callback 00159 } 00160 } 00161 00162 if (cf_context->client_status == PLATFORM_NVM_ERROR) { 00163 // read/write/delete operation failed, close the handle 00164 if (nvm_close_internal(cf_context) == false) { 00165 cf_context->state = NVM_STATE_CLOSE_DONE; 00166 cf_context->client_status = PLATFORM_NVM_ERROR; 00167 } 00168 } 00169 break; 00170 case CFSTORE_OPCODE_WRITE: 00171 tr_debug("CFSTORE_OPCODE_WRITE %d", (int)status); 00172 cf_context->state = NVM_STATE_WRITE_DONE; 00173 *cf_context->client_buf_len = cf_context->data_len; 00174 if (nvm_close_internal(cf_context) == false) { 00175 /* writing failed set status and start callback timer */ 00176 cf_context->state = NVM_STATE_CLOSE_DONE; 00177 cf_context->client_status = PLATFORM_NVM_ERROR; 00178 } else { 00179 // closing OK, wait for CFSTORE_OPCODE_CLOSE callback 00180 } 00181 break; 00182 case CFSTORE_OPCODE_READ: 00183 tr_debug("CFSTORE_OPCODE_READ %d", (int)status); 00184 cf_context->state = NVM_STATE_READ_DONE; 00185 if (nvm_close_internal(cf_context) == false) { 00186 cf_context->state = NVM_STATE_CLOSE_DONE; 00187 cf_context->client_status = PLATFORM_NVM_ERROR; 00188 } else { 00189 // closing OK, wait for CFSTORE_OPCODE_CLOSE callback 00190 *cf_context->client_buf_len = (uint16_t)status; // save the bytes read 00191 } 00192 break; 00193 case CFSTORE_OPCODE_DELETE: 00194 tr_debug("CFSTORE_OPCODE_DELETE %d", (int)status); 00195 if (nvm_close_internal(cf_context) == false) { 00196 /* closing failed set client_status */ 00197 cf_context->state = NVM_STATE_CLOSE_DONE; 00198 cf_context->client_status = PLATFORM_NVM_ERROR; 00199 } else { 00200 // closing OK, wait for CFSTORE_OPCODE_CLOSE callback 00201 } 00202 break; 00203 case CFSTORE_OPCODE_CLOSE: 00204 tr_debug("CFSTORE_OPCODE_CLOSE %d", (int)status); 00205 cf_context->state = NVM_STATE_CLOSE_DONE; 00206 // client_status is already set by read/write/delete operation, do not override it 00207 break; 00208 case CFSTORE_OPCODE_UNINITIALIZE: 00209 tr_debug("CFSTORE_OPCODE_UNINITIALIZE %d", (int)status); 00210 cf_context->state = NVM_STATE_UNINIT_DONE; 00211 cf_context->client_status = nvm_error_map(status); 00212 break; 00213 case CFSTORE_OPCODE_FLUSH: 00214 tr_debug("CFSTORE_OPCODE_FLUSH %d", (int)status); 00215 cf_context->state = NVM_STATE_FLUSH_DONE; 00216 cf_context->client_status = nvm_error_map(status); 00217 break; 00218 00219 default: 00220 tr_debug("unhandled cmd_code %d", cmd_code); 00221 break; 00222 } 00223 00224 return; 00225 } 00226 00227 static int nvm_fsm_update(cs_context_t *cs_context) 00228 { 00229 int ret_val = 0; 00230 00231 tr_debug("nvm_fsm_update() state=%d", (int)cs_context->state); 00232 switch (cs_context->state) 00233 { 00234 case NVM_STATE_UNINIT_DONE: 00235 cs_context->client_cb(cs_context->client_status, cs_context->client_context); 00236 cs_context->state = NVM_STATE_NONE; 00237 if (cs_context->client_status == PLATFORM_NVM_OK) { 00238 ns_dyn_mem_free(cs_context_ptr); 00239 cs_context_ptr = NULL; 00240 } 00241 ret_val = 1; 00242 break; 00243 case NVM_STATE_INIT_DONE: 00244 case NVM_STATE_CREATE_DONE: 00245 case NVM_STATE_OPEN_DONE: 00246 case NVM_STATE_WRITE_DONE: 00247 case NVM_STATE_READ_DONE: 00248 case NVM_STATE_DELETE_DONE: 00249 case NVM_STATE_CLOSE_DONE: 00250 case NVM_STATE_FLUSH_DONE: 00251 cs_context->state = NVM_STATE_NONE; 00252 cs_context->client_cb(cs_context->client_status, cs_context->client_context); 00253 ret_val = 1; 00254 break; 00255 00256 default: 00257 tr_error("unknown state %d", cs_context->state); 00258 break; 00259 } 00260 00261 return ret_val; 00262 } 00263 00264 /** 00265 * Initialize NVM 00266 */ 00267 platform_nvm_status platform_nvm_init(nvm_callback *callback, void *context) 00268 { 00269 int32_t ret; 00270 00271 tr_debug("platform_nvm_init()"); 00272 00273 if (callback == NULL || cs_context_ptr) { 00274 return PLATFORM_NVM_ERROR; 00275 } 00276 00277 if (cs_context_ptr == NULL) { 00278 cs_context_ptr = ns_dyn_mem_alloc(sizeof(cs_context_t)); 00279 } 00280 00281 if (cs_context_ptr == NULL) { 00282 return PLATFORM_NVM_ERROR; 00283 } 00284 00285 memset(cs_context_ptr, 0, sizeof(cs_context_t)); 00286 cs_context_ptr->client_cb = callback; 00287 cs_context_ptr->client_context = context; 00288 00289 cs_context_ptr->capabilities = drv->GetCapabilities(); 00290 00291 tr_debug("mode: %s", IS_SYNC_MODE(cs_context_ptr) ? "sync": "async" ); 00292 00293 ret = drv->Initialize(configuration_store_cb, cs_context_ptr); 00294 if (ret < ARM_DRIVER_OK) { 00295 tr_error("initialisation failed %d", (int)ret); 00296 ns_dyn_mem_free(cs_context_ptr); 00297 cs_context_ptr = NULL; 00298 return PLATFORM_NVM_ERROR; 00299 } 00300 00301 drv->PowerControl(ARM_POWER_FULL); 00302 00303 // start timer to report initialization status back to client 00304 nvm_fsm_timer_start(); 00305 return PLATFORM_NVM_OK; 00306 } 00307 00308 /* 00309 * Deinitialize NVM. 00310 */ 00311 platform_nvm_status platform_nvm_finalize(nvm_callback *callback, void *context) 00312 { 00313 int32_t ret; 00314 00315 tr_debug("platform_nvm_deinit()"); 00316 00317 if (!nvm_status_check(cs_context_ptr)) { 00318 return PLATFORM_NVM_ERROR; 00319 } 00320 00321 if (callback == NULL) { 00322 return PLATFORM_NVM_ERROR; 00323 } 00324 00325 cs_context_ptr->client_cb = callback; 00326 cs_context_ptr->client_context = context; 00327 cs_context_ptr->state = NVM_STATE_UNINITIALIZING; 00328 cs_context_ptr->client_status = PLATFORM_NVM_OK; 00329 drv->PowerControl(ARM_POWER_OFF); 00330 ret = drv->Uninitialize(); 00331 00332 if (ret < ARM_DRIVER_OK) { 00333 tr_error("deinit failed %d", (int)ret); 00334 cs_context_ptr->state = NVM_STATE_UNINIT_DONE; 00335 cs_context_ptr->client_status = nvm_error_map(ret); 00336 } 00337 00338 nvm_fsm_timer_start(); 00339 return PLATFORM_NVM_OK; 00340 } 00341 00342 /* 00343 * Create key to NVM 00344 */ 00345 platform_nvm_status platform_nvm_key_create(nvm_callback *callback, const char *key_name, uint16_t value_len, uint32_t flags, void *context) 00346 { 00347 int32_t ret; 00348 ARM_CFSTORE_KEYDESC keydesc; 00349 (void)flags; 00350 00351 tr_debug("platform_nvm_key_create() %s len=%d", key_name, value_len); 00352 00353 if (callback == NULL || key_name == NULL) { 00354 return PLATFORM_NVM_ERROR; 00355 } 00356 00357 if (!nvm_status_check(cs_context_ptr)) { 00358 return PLATFORM_NVM_ERROR; 00359 } 00360 00361 cs_context_ptr->client_cb = callback; 00362 cs_context_ptr->client_context = context; 00363 cs_context_ptr->state = NVM_STATE_CREATING; 00364 cs_context_ptr->client_status = PLATFORM_NVM_OK; 00365 00366 memset(&keydesc, 0, sizeof(ARM_CFSTORE_KEYDESC)); 00367 keydesc.drl = ARM_RETENTION_NVM; 00368 00369 ret = drv->Create(key_name, value_len, &keydesc, cs_context_ptr->hkey); 00370 if(ret < ARM_DRIVER_OK) { 00371 if (ret == ARM_CFSTORE_DRIVER_ERROR_PREEXISTING_KEY) { 00372 tr_debug("adjust value len to %d", value_len); 00373 ret = drv->Create(key_name, value_len, NULL, cs_context_ptr->hkey); 00374 } 00375 } 00376 00377 if(ret < ARM_DRIVER_OK) { 00378 tr_error("Key creation failed %d", (int)ret); 00379 cs_context_ptr->state = NVM_STATE_CREATE_DONE; 00380 cs_context_ptr->client_status = nvm_error_map(ret); 00381 } 00382 00383 nvm_fsm_timer_start(); 00384 00385 return PLATFORM_NVM_OK; 00386 } 00387 00388 /** 00389 * Delete key from NVM 00390 */ 00391 platform_nvm_status platform_nvm_key_delete(nvm_callback *callback, const char *key_name, void *context) 00392 { 00393 int32_t ret; 00394 ARM_CFSTORE_FMODE flags; 00395 00396 tr_debug("platform_nvm_key_delete() %s", key_name); 00397 00398 if (callback == NULL || key_name == NULL) { 00399 return PLATFORM_NVM_ERROR; 00400 } 00401 00402 if (!nvm_status_check(cs_context_ptr)) { 00403 return PLATFORM_NVM_ERROR; 00404 } 00405 00406 cs_context_ptr->client_cb = callback; 00407 cs_context_ptr->client_context = context; 00408 cs_context_ptr->client_status = PLATFORM_NVM_OK; 00409 cs_context_ptr->state = NVM_STATE_DELETING; 00410 00411 memset(&flags, 0, sizeof(ARM_CFSTORE_FMODE)); 00412 flags.read = 1; 00413 flags.write = 1; 00414 ret = drv->Open(key_name, flags, cs_context_ptr->hkey); 00415 00416 if(ret < ARM_DRIVER_OK) { 00417 tr_error("Key delete, open failed %d", (int)ret); 00418 cs_context_ptr->state = NVM_STATE_DELETE_DONE; 00419 cs_context_ptr->client_status = nvm_error_map(ret); 00420 } 00421 00422 // start callback timer in both asynch and synch mode 00423 nvm_fsm_timer_start(); 00424 00425 return PLATFORM_NVM_OK; 00426 } 00427 00428 /** 00429 * Reading from NVM 00430 */ 00431 platform_nvm_status platform_nvm_read(nvm_callback *callback, const char *key_name, void *buf, uint16_t *buf_len, void *context) 00432 { 00433 int32_t ret; 00434 ARM_CFSTORE_FMODE flags; 00435 00436 tr_debug("platform_nvm_read()"); 00437 00438 if (callback == NULL || key_name == NULL || buf == NULL || buf_len == NULL) { 00439 return PLATFORM_NVM_ERROR; 00440 } 00441 00442 if (!nvm_status_check(cs_context_ptr)) { 00443 return PLATFORM_NVM_ERROR; 00444 } 00445 cs_context_ptr->client_cb = callback; 00446 cs_context_ptr->client_context = context; 00447 cs_context_ptr->client_buf = buf; 00448 cs_context_ptr->client_buf_len = buf_len; 00449 cs_context_ptr->data_len = *buf_len; 00450 cs_context_ptr->client_status = PLATFORM_NVM_OK; 00451 cs_context_ptr->state = NVM_STATE_READING; 00452 00453 // Open handle for reading 00454 memset(&flags, 0, sizeof(ARM_CFSTORE_FMODE)); 00455 flags.read = 1; 00456 ret = drv->Open(key_name, flags, cs_context_ptr->hkey); 00457 00458 if(ret < ARM_DRIVER_OK) { 00459 tr_error("Read failed to open handle %d", (int)ret); 00460 cs_context_ptr->state = NVM_STATE_READ_DONE; 00461 cs_context_ptr->client_status = nvm_error_map(ret); 00462 } 00463 00464 // start callback timer in both async and synch mode 00465 nvm_fsm_timer_start(); 00466 00467 return PLATFORM_NVM_OK; 00468 } 00469 00470 /** 00471 * Write to NVM. 00472 */ 00473 platform_nvm_status platform_nvm_write(nvm_callback *callback, const char *key_name, const void *data, uint16_t *data_len, void *context) 00474 { 00475 int32_t ret; 00476 ARM_CFSTORE_FMODE flags; 00477 tr_debug("platform_nvm_write()"); 00478 00479 if (callback == NULL || key_name == NULL || data == NULL || data_len == NULL) { 00480 return PLATFORM_NVM_ERROR; 00481 } 00482 00483 if (!nvm_status_check(cs_context_ptr)) { 00484 return PLATFORM_NVM_ERROR; 00485 } 00486 cs_context_ptr->client_cb = callback; 00487 cs_context_ptr->client_context = context; 00488 cs_context_ptr->client_buf = (void*)data; 00489 cs_context_ptr->client_buf_len = data_len; 00490 cs_context_ptr->data_len = *data_len; 00491 cs_context_ptr->client_status = PLATFORM_NVM_OK; 00492 cs_context_ptr->state = NVM_STATE_WRITING; 00493 00494 // Open handle for writing, execution continues in callback 00495 memset(&flags, 0, sizeof(ARM_CFSTORE_FMODE)); 00496 flags.write = 1; 00497 ret = drv->Open(key_name, flags, cs_context_ptr->hkey); 00498 00499 if(ret < ARM_DRIVER_OK) { 00500 tr_error("Write failed %d", (int)ret); 00501 cs_context_ptr->state = NVM_STATE_WRITE_DONE; 00502 cs_context_ptr->client_status = nvm_error_map(ret); 00503 } 00504 00505 // start callback timer in both asynch and synch mode 00506 nvm_fsm_timer_start(); 00507 00508 return PLATFORM_NVM_OK; 00509 } 00510 00511 /** 00512 * Flush the NVM 00513 */ 00514 platform_nvm_status platform_nvm_flush(nvm_callback *callback, void *context) 00515 { 00516 tr_debug("platform_nvm_flush()"); 00517 00518 int32_t ret; 00519 00520 if (callback == NULL) { 00521 return PLATFORM_NVM_ERROR; 00522 } 00523 00524 if (!nvm_status_check(cs_context_ptr)) { 00525 return PLATFORM_NVM_ERROR; 00526 } 00527 00528 cs_context_ptr->client_cb = callback; 00529 cs_context_ptr->client_context = context; 00530 cs_context_ptr->client_status = PLATFORM_NVM_OK; 00531 cs_context_ptr->state = NVM_STATE_FLUSHING; 00532 00533 ret = drv->Flush(); 00534 00535 if(ret < ARM_DRIVER_OK) { 00536 cs_context_ptr->state = NVM_STATE_FLUSH_DONE; 00537 cs_context_ptr->client_status = nvm_error_map(ret); 00538 } 00539 00540 // start callback timer in both asynch and synch mode 00541 nvm_fsm_timer_start(); 00542 00543 return PLATFORM_NVM_OK; 00544 } 00545 00546 static bool nvm_write_internal(cs_context_t *cf_context) 00547 { 00548 int32_t ret; 00549 cf_context->state = NVM_STATE_WRITING; 00550 ret = drv->Write(cf_context->hkey, (const char*)cf_context->client_buf, &cf_context->data_len); 00551 00552 if(ret >= ARM_DRIVER_OK) { 00553 return true; 00554 } else { 00555 tr_error("Write failed %d", (int)ret); 00556 return false; 00557 } 00558 } 00559 00560 static bool nvm_read_internal(cs_context_t *cf_context) 00561 { 00562 int32_t ret; 00563 cf_context->state = NVM_STATE_READING; 00564 ret = drv->Read(cf_context->hkey, (void*)cf_context->client_buf, &cf_context->data_len); 00565 00566 if(ret >= ARM_DRIVER_OK) { 00567 return true; 00568 } else { 00569 tr_error("Read failed %d", (int)ret); 00570 return false; 00571 } 00572 } 00573 00574 static bool nvm_delete_internal(cs_context_t *cf_context) 00575 { 00576 int32_t ret; 00577 cf_context->state = NVM_STATE_DELETING; 00578 ret = drv->Delete(cf_context->hkey); 00579 00580 if(ret >= ARM_DRIVER_OK) { 00581 return true; 00582 } else { 00583 tr_error("Delete failed %d", (int)ret); 00584 return false; 00585 } 00586 } 00587 00588 static bool nvm_close_internal(cs_context_t *cf_context) 00589 { 00590 int32_t ret; 00591 cf_context->state = NVM_STATE_CLOSING; 00592 ret = drv->Close(cf_context->hkey); 00593 00594 if(ret >= ARM_DRIVER_OK) { 00595 return true; 00596 } else { 00597 tr_error("Close failed %d", (int)ret); 00598 return false; 00599 } 00600 } 00601 00602 /* 00603 * Check NVM state before executing client action 00604 */ 00605 static bool nvm_status_check(cs_context_t *cf_context) 00606 { 00607 if (!cs_context_ptr) { 00608 // not initialized 00609 tr_error("NVM not initialized"); 00610 return false; 00611 } 00612 00613 if (cf_context->state != NVM_STATE_NONE) { 00614 tr_error("NVM busy, operation in progress %d", cf_context->state); 00615 return false; 00616 } 00617 00618 return true; 00619 } 00620 00621 static platform_nvm_status nvm_error_map(int32_t cs_error) 00622 { 00623 platform_nvm_status client_error; 00624 00625 if (cs_error >= ARM_DRIVER_OK) { 00626 return PLATFORM_NVM_OK; 00627 } 00628 00629 switch(cs_error) { 00630 case ARM_CFSTORE_DRIVER_ERROR_KEY_NOT_FOUND: 00631 client_error = PLATFORM_NVM_KEY_NOT_FOUND; 00632 break; 00633 default: 00634 client_error = PLATFORM_NVM_ERROR; 00635 break; 00636 } 00637 00638 return client_error; 00639 } 00640 00641 static void nvm_fsm_timer_cb(void *args) 00642 { 00643 (void) args; 00644 switch(nvm_fsm_update(cs_context_ptr)) { 00645 case 0: 00646 // Nothing processed, restart timer 00647 tr_debug("nvm_fsm_timer_cb not handled event in () %d", (int)cs_context_ptr->state); 00648 nvm_fsm_timer_start(); 00649 break; 00650 default: 00651 break; 00652 } 00653 } 00654 00655 /* 00656 * Start timer for polling callback from 00657 */ 00658 static void nvm_fsm_timer_start(void) 00659 { 00660 cs_context_ptr->callback_timer = eventOS_timeout_ms(nvm_fsm_timer_cb, NVM_CB_POLLING_TIMEOUT, NULL); 00661 } 00662 00663 #endif /* MBED_CONF_NANOSTACK_HAL_NVM_CFSTORE */
Generated on Tue Jul 12 2022 13:15:44 by
