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