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.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
ns_nvm_helper.c
00001 /* 00002 * Copyright (c) 2016 ARM Limited. All rights reserved. 00003 */ 00004 00005 #include <string.h> 00006 #include <ns_types.h> 00007 #include <nsdynmemLIB.h> 00008 #define HAVE_DEBUG 00009 #include "ns_trace.h" 00010 #include "ns_list.h" 00011 #include "platform/arm_hal_nvm.h" 00012 #include "ns_nvm_helper.h" 00013 00014 #define TRACE_GROUP "nnvm" 00015 00016 /* NVM operations */ 00017 #define NS_NVM_NONE 0x00 00018 #define NS_NVM_INIT 0x01 00019 #define NS_NVM_KEY_CREATE 0x02 00020 #define NS_NVM_KEY_READ 0x03 00021 #define NS_NVM_KEY_WRITE 0x04 00022 #define NS_NVM_FLUSH 0x05 00023 #define NS_NVM_KEY_DELETE 0x06 00024 00025 typedef struct { 00026 ns_nvm_callback *callback; 00027 const char *client_key_name; 00028 void *client_context; 00029 int operation; 00030 uint8_t *buffer; 00031 uint16_t *buffer_len; 00032 void *original_request; 00033 ns_list_link_t link; 00034 } ns_nvm_request_t; 00035 00036 static bool ns_nvm_initialized = false; 00037 static bool ns_nvm_operation_in_progress = false; 00038 00039 static ns_nvm_request_t *ns_nvm_create_request(ns_nvm_callback *callback, void *context, const char *key_name, uint8_t *buf, uint16_t *buf_len, uint8_t operation); 00040 static int ns_nvm_operation_start(ns_nvm_request_t *request); 00041 static int ns_nvm_operation_continue(ns_nvm_request_t *request, bool free_request); 00042 static void ns_nvm_operation_end(ns_nvm_request_t *ns_nvm_request_ptr, int client_retval); 00043 00044 static NS_LIST_DEFINE(ns_nvm_request_list, ns_nvm_request_t, link); 00045 00046 /* 00047 * Callback from platform NVM adaptation 00048 */ 00049 void ns_nvm_callback_func(platform_nvm_status status, void *args) 00050 { 00051 ns_nvm_request_t *ns_nvm_request_ptr = (ns_nvm_request_t*)args; 00052 int client_retval = NS_NVM_OK; 00053 00054 if (status == PLATFORM_NVM_ERROR) { 00055 client_retval = NS_NVM_ERROR; 00056 } else if (status == PLATFORM_NVM_KEY_NOT_FOUND) { 00057 client_retval = NS_NVM_DATA_NOT_FOUND; 00058 } 00059 00060 switch(ns_nvm_request_ptr->operation) { 00061 case NS_NVM_INIT: 00062 ns_nvm_operation_continue(ns_nvm_request_ptr->original_request, true); 00063 ns_dyn_mem_free(ns_nvm_request_ptr); 00064 break; 00065 case NS_NVM_FLUSH: 00066 case NS_NVM_KEY_READ: 00067 ns_nvm_operation_end(ns_nvm_request_ptr, client_retval); 00068 break; 00069 case NS_NVM_KEY_CREATE: 00070 if (status == PLATFORM_NVM_OK) { 00071 ns_nvm_request_ptr->operation = NS_NVM_KEY_WRITE; 00072 platform_nvm_write(ns_nvm_callback_func, ns_nvm_request_ptr->client_key_name, ns_nvm_request_ptr->buffer, ns_nvm_request_ptr->buffer_len, ns_nvm_request_ptr); 00073 } else { 00074 ns_nvm_operation_end(ns_nvm_request_ptr, client_retval); 00075 } 00076 break; 00077 case NS_NVM_KEY_DELETE: 00078 case NS_NVM_KEY_WRITE: 00079 if (status == PLATFORM_NVM_OK) { 00080 // write ok, flush the changes 00081 ns_nvm_request_ptr->operation = NS_NVM_FLUSH; 00082 platform_nvm_flush(ns_nvm_callback_func, ns_nvm_request_ptr); 00083 } else { 00084 // write failed, inform client 00085 ns_nvm_operation_end(ns_nvm_request_ptr, client_retval); 00086 } 00087 break; 00088 } 00089 } 00090 00091 int ns_nvm_key_delete(ns_nvm_callback *callback, const char *key_name, void *context) 00092 { 00093 if (!callback || !key_name) { 00094 return NS_NVM_ERROR; 00095 } 00096 tr_debug("ns_nvm_key_delete() key=%s, ctx=%p", key_name, context); 00097 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(callback, context, key_name, NULL, NULL, NS_NVM_KEY_DELETE); 00098 return ns_nvm_operation_start(ns_nvm_request_ptr); 00099 } 00100 00101 int ns_nvm_data_read(ns_nvm_callback *callback, const char *key_name, uint8_t *buf, uint16_t *buf_len, void *context) 00102 { 00103 if (!callback || !key_name || !buf || !buf_len) { 00104 return NS_NVM_ERROR; 00105 } 00106 tr_debug("ns_nvm_data_read() key=%s, len=%d, ctx=%p", key_name, (int)*buf_len, context); 00107 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(callback, context, key_name, buf, buf_len, NS_NVM_KEY_READ); 00108 return ns_nvm_operation_start(ns_nvm_request_ptr); 00109 } 00110 00111 int ns_nvm_data_write(ns_nvm_callback *callback, const char *key_name, uint8_t *buf, uint16_t *buf_len, void *context) 00112 { 00113 if (!callback || !key_name || !buf || !buf_len) { 00114 return NS_NVM_ERROR; 00115 } 00116 tr_debug("ns_nvm_data_write() key=%s, len=%d, ctx=%p", key_name, (int)*buf_len, context); 00117 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(callback, context, key_name, buf, buf_len, NS_NVM_KEY_WRITE); 00118 return ns_nvm_operation_start(ns_nvm_request_ptr); 00119 } 00120 00121 static int ns_nvm_operation_start(ns_nvm_request_t *nvm_request) 00122 { 00123 int ret = NS_NVM_OK; 00124 platform_nvm_status pnvm_status; 00125 00126 if (!nvm_request) { 00127 return NS_NVM_MEMORY; 00128 } 00129 if (ns_nvm_initialized == true) { 00130 // NVM already initialized, continue directly 00131 if (!ns_nvm_operation_in_progress) { 00132 ret = ns_nvm_operation_continue(nvm_request, true); 00133 } else { 00134 // add request to list and handle when existing calls has been handled. 00135 ns_list_add_to_end(&ns_nvm_request_list, nvm_request); 00136 } 00137 } else { 00138 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(NULL, NULL, NULL, NULL, NULL, NS_NVM_INIT); 00139 if (!ns_nvm_request_ptr) { 00140 ns_dyn_mem_free(nvm_request); 00141 ns_dyn_mem_free(ns_nvm_request_ptr); 00142 return NS_NVM_MEMORY; 00143 } 00144 ns_nvm_request_ptr->original_request = nvm_request; 00145 pnvm_status = platform_nvm_init(ns_nvm_callback_func, ns_nvm_request_ptr); 00146 if (pnvm_status != PLATFORM_NVM_OK) { 00147 ns_dyn_mem_free(nvm_request); 00148 ns_dyn_mem_free(ns_nvm_request_ptr); 00149 return NS_NVM_ERROR; 00150 } 00151 ns_list_init(&ns_nvm_request_list); 00152 ns_nvm_initialized = true; 00153 ns_nvm_operation_in_progress = true; 00154 } 00155 return ret; 00156 } 00157 00158 static ns_nvm_request_t *ns_nvm_create_request(ns_nvm_callback *callback, void *context, const char *key_name, uint8_t *buf, uint16_t *buf_len, uint8_t operation) 00159 { 00160 ns_nvm_request_t *ns_nvm_request_ptr = ns_dyn_mem_temporary_alloc(sizeof(ns_nvm_request_t)); 00161 if (!ns_nvm_request_ptr) { 00162 return NULL; 00163 } 00164 ns_nvm_request_ptr->client_context = context; 00165 ns_nvm_request_ptr->callback = callback; 00166 ns_nvm_request_ptr->client_key_name = key_name; 00167 ns_nvm_request_ptr->operation = operation; 00168 ns_nvm_request_ptr->buffer = buf; 00169 ns_nvm_request_ptr->buffer_len = buf_len; 00170 00171 return ns_nvm_request_ptr; 00172 } 00173 00174 static int ns_nvm_operation_continue(ns_nvm_request_t *request, bool free_request) 00175 { 00176 platform_nvm_status ret = PLATFORM_NVM_OK; 00177 00178 ns_nvm_operation_in_progress = true; 00179 switch(request->operation) { 00180 case NS_NVM_KEY_WRITE: 00181 request->operation = NS_NVM_KEY_CREATE; 00182 ret = platform_nvm_key_create(ns_nvm_callback_func, request->client_key_name, *request->buffer_len, 0, request); 00183 break; 00184 case NS_NVM_KEY_READ: 00185 ret = platform_nvm_read(ns_nvm_callback_func, request->client_key_name, request->buffer, request->buffer_len, request); 00186 break; 00187 case NS_NVM_KEY_DELETE: 00188 ret = platform_nvm_key_delete(ns_nvm_callback_func, request->client_key_name, request); 00189 break; 00190 } 00191 00192 if (ret != PLATFORM_NVM_OK) { 00193 if (free_request == true) { 00194 // free request if requested 00195 ns_dyn_mem_free(request); 00196 } 00197 ns_nvm_operation_in_progress = false; 00198 return NS_NVM_ERROR; 00199 } 00200 00201 return NS_NVM_OK; 00202 } 00203 00204 static void ns_nvm_operation_end(ns_nvm_request_t *ns_nvm_request_ptr, int client_retval) 00205 { 00206 ns_nvm_request_ptr->callback(client_retval, ns_nvm_request_ptr->client_context); 00207 ns_dyn_mem_free(ns_nvm_request_ptr); 00208 ns_nvm_operation_in_progress = false; 00209 00210 ns_list_foreach_safe(ns_nvm_request_t, pending_req, &ns_nvm_request_list) { 00211 // there are pending requests to be processed 00212 ns_list_remove(&ns_nvm_request_list, pending_req); 00213 int ret = ns_nvm_operation_continue(pending_req, false); 00214 if (ret != NS_NVM_OK) { 00215 ns_nvm_operation_end(pending_req, ret); 00216 } else { 00217 break; 00218 } 00219 } 00220 }
Generated on Tue Jul 12 2022 11:02:48 by
