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