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
nvm_ram.c
00001 /* 00002 * Copyright (c) 2016, ARM Limited, All Rights Reserved. 00003 */ 00004 00005 #ifdef MBED_CONF_NANOSTACK_HAL_NVM_CFSTORE 00006 # if MBED_CONF_NANOSTACK_HAL_NVM_CFSTORE 00007 # define IGNORE_SIMULATED_NVM_STORAGE 00008 # else 00009 # undef IGNORE_SIMULATED_NVM_STORAGE 00010 # endif 00011 #endif 00012 00013 /* 00014 * Define flag IGNORE_SIMULATED_NVM_STORAGE to ignore usage of simulated NVM and use 00015 * platform specific NVM instead. 00016 */ 00017 #ifndef IGNORE_SIMULATED_NVM_STORAGE 00018 00019 #include <stdlib.h> 00020 #include <string.h> 00021 #include "ns_types.h" 00022 #include "ns_list.h" 00023 #include "nsdynmemLIB.h" 00024 #include "eventOS_event_timer.h" 00025 #include "platform/arm_hal_nvm.h" 00026 00027 #include "ns_trace.h" 00028 #define TRACE_GROUP "rnvm" 00029 00030 /** 00031 * NVM to RAM/heap, targeted for testing. 00032 * Key/values are stored to ns_list. Otherwise functionality should be similar to 00033 * nanostack configuration-store adaptation. 00034 */ 00035 00036 #define NVM_RAM_STANDARD_MALLOC 00037 #ifdef NVM_RAM_STANDARD_MALLOC 00038 #define ALLOC malloc 00039 #define FREE free 00040 #else 00041 #define ALLOC ns_dyn_mem_alloc 00042 #define FREE ns_dyn_mem_free 00043 #endif 00044 00045 /* 00046 * Data entry stored to NVM 00047 */ 00048 typedef struct { 00049 char *key; 00050 uint8_t *data; 00051 uint32_t data_len; 00052 ns_list_link_t link; 00053 } nvm_data_entry_t; 00054 00055 /* 00056 * Client request to NVM 00057 */ 00058 typedef struct { 00059 nvm_callback *client_cb; // callback provided by client 00060 void *client_context; // context provided by client 00061 void *client_buffer; // buffer provided by client 00062 uint16_t *client_buffer_len; // buffer length provided by client 00063 platform_nvm_status client_status; // status to be returned to client 00064 ns_list_link_t link; 00065 } nvm_client_req_t; 00066 00067 /* 00068 * NVM context 00069 */ 00070 typedef struct { 00071 timeout_t *callback_timer; // timer handle for informing client 00072 bool is_initialized; 00073 } nvm_context_t; 00074 00075 static NS_LIST_DEFINE(nvm_entry_list, nvm_data_entry_t, link); 00076 static NS_LIST_DEFINE(nvm_client_req_list, nvm_client_req_t, link); 00077 00078 static nvm_context_t *nvm_context_ptr = NULL; 00079 00080 static void nvm_ram_timer_start(void *ctx); 00081 static void nvm_ram_free_entry(nvm_data_entry_t *entry); 00082 00083 00084 static platform_nvm_status create_client_request(nvm_callback *callback, void *context, void *buf, uint16_t *buf_len, platform_nvm_status status) 00085 { 00086 nvm_client_req_t *nvm_client_req_ptr; 00087 nvm_client_req_ptr = ALLOC(sizeof(nvm_client_req_t)); 00088 if (!nvm_client_req_ptr) { 00089 return PLATFORM_NVM_ERROR; 00090 } 00091 nvm_client_req_ptr->client_cb = callback; 00092 nvm_client_req_ptr->client_context = context; 00093 nvm_client_req_ptr->client_buffer = buf; 00094 nvm_client_req_ptr->client_buffer_len = buf_len; 00095 nvm_client_req_ptr->client_status = status; 00096 ns_list_add_to_end(&nvm_client_req_list, nvm_client_req_ptr); 00097 00098 if (nvm_context_ptr->callback_timer == NULL) { 00099 nvm_ram_timer_start(nvm_client_req_ptr); 00100 } 00101 00102 return PLATFORM_NVM_OK; 00103 } 00104 00105 platform_nvm_status platform_nvm_init(nvm_callback *callback, void *context) 00106 { 00107 if (nvm_context_ptr == NULL) { 00108 nvm_context_ptr = ALLOC(sizeof(nvm_context_t)); 00109 if (!nvm_context_ptr) { 00110 return PLATFORM_NVM_ERROR; 00111 } 00112 nvm_context_ptr->callback_timer = NULL; 00113 nvm_context_ptr->is_initialized = true; 00114 ns_list_init(&nvm_entry_list); 00115 ns_list_init(&nvm_client_req_list); 00116 } else { 00117 if (nvm_context_ptr->is_initialized == true) { 00118 return PLATFORM_NVM_ERROR; 00119 } 00120 } 00121 00122 return create_client_request(callback, context, NULL, NULL, PLATFORM_NVM_OK); 00123 } 00124 00125 platform_nvm_status platform_nvm_finalize(nvm_callback *callback, void *context) 00126 { 00127 platform_nvm_status ret; 00128 if (nvm_context_ptr->is_initialized == false) { 00129 return PLATFORM_NVM_ERROR; 00130 } 00131 00132 ret = create_client_request(callback, context, NULL, NULL, PLATFORM_NVM_OK); 00133 if (ret == PLATFORM_NVM_OK) { 00134 nvm_context_ptr->is_initialized = false; 00135 } 00136 00137 return ret; 00138 } 00139 00140 platform_nvm_status platform_nvm_key_create(nvm_callback *callback, const char *key_name, uint16_t value_len, uint32_t flags, void *context) 00141 { 00142 (void)flags; 00143 tr_debug("platform_nvm_key_create() %s len=%d", key_name, (int)value_len); 00144 00145 ns_list_foreach(nvm_data_entry_t, current_entry, &nvm_entry_list) { 00146 if (strcmp(current_entry->key, key_name)==0) { 00147 // resizing existing key 00148 ns_list_remove(&nvm_entry_list, current_entry); 00149 nvm_ram_free_entry(current_entry); 00150 break; 00151 } 00152 } 00153 00154 nvm_data_entry_t *entry = ALLOC(sizeof(nvm_data_entry_t)); 00155 if (!entry) { 00156 return PLATFORM_NVM_ERROR; 00157 } 00158 memset(entry, 0, sizeof(nvm_data_entry_t)); 00159 size_t key_len = strlen(key_name) + 1; 00160 entry->key = ALLOC(key_len); 00161 if (!entry->key) { 00162 FREE(entry); 00163 return PLATFORM_NVM_ERROR; 00164 } 00165 memcpy(entry->key, key_name, key_len); 00166 entry->data_len = value_len; 00167 entry->data = ALLOC(value_len); 00168 if (!entry->data) { 00169 FREE(entry->key); 00170 FREE(entry); 00171 return PLATFORM_NVM_ERROR; 00172 } 00173 00174 ns_list_add_to_end(&nvm_entry_list, entry); 00175 00176 return create_client_request(callback, context, NULL, NULL, PLATFORM_NVM_OK); 00177 } 00178 00179 platform_nvm_status platform_nvm_key_delete(nvm_callback *callback, const char *key_name, void *context) 00180 { 00181 platform_nvm_status client_status = PLATFORM_NVM_KEY_NOT_FOUND; 00182 tr_debug("platform_nvm_key_delete() %s", key_name); 00183 00184 ns_list_foreach(nvm_data_entry_t, current_entry, &nvm_entry_list) { 00185 if (strcmp(current_entry->key, key_name)==0) { 00186 client_status = PLATFORM_NVM_OK; 00187 ns_list_remove(&nvm_entry_list, current_entry); 00188 nvm_ram_free_entry(current_entry); 00189 break; 00190 } 00191 } 00192 00193 return create_client_request(callback, context, NULL, NULL, client_status); 00194 } 00195 00196 platform_nvm_status platform_nvm_write(nvm_callback *callback, const char *key_name, const void *data, uint16_t *data_len, void *context) 00197 { 00198 platform_nvm_status client_status = PLATFORM_NVM_KEY_NOT_FOUND; 00199 tr_debug("platform_nvm_write() %s len=%d", key_name, (int)*data_len); 00200 00201 ns_list_foreach(nvm_data_entry_t, current_entry, &nvm_entry_list) { 00202 if (strcmp(current_entry->key, key_name)==0) { 00203 if (current_entry->data_len >= *data_len) { 00204 memcpy(current_entry->data, data, *data_len); 00205 } else { 00206 memcpy(current_entry->data, data, current_entry->data_len); 00207 *data_len = current_entry->data_len; 00208 } 00209 client_status = PLATFORM_NVM_OK; 00210 break; 00211 } 00212 } 00213 00214 return create_client_request(callback, context, (void*)data, data_len, client_status); 00215 } 00216 00217 platform_nvm_status platform_nvm_read(nvm_callback *callback, const char *key_name, void *buf, uint16_t *buf_len, void *context) 00218 { 00219 platform_nvm_status client_status = PLATFORM_NVM_KEY_NOT_FOUND; 00220 tr_debug("platform_nvm_read() %s len=%d", key_name, (int)*buf_len); 00221 00222 ns_list_foreach(nvm_data_entry_t, current_entry, &nvm_entry_list) { 00223 if (strcmp(current_entry->key, key_name)==0) { 00224 if (*buf_len >= current_entry->data_len) { 00225 memcpy(buf, current_entry->data, current_entry->data_len); 00226 *buf_len = current_entry->data_len; 00227 } else { 00228 memcpy(buf, current_entry->data, *buf_len); 00229 } 00230 client_status = PLATFORM_NVM_OK; 00231 break; 00232 } 00233 } 00234 00235 return create_client_request(callback, context, buf, buf_len, client_status); 00236 } 00237 00238 platform_nvm_status platform_nvm_flush(nvm_callback *callback, void *context) 00239 { 00240 tr_debug("platform_nvm_flush()"); 00241 return create_client_request(callback, context, NULL, NULL, PLATFORM_NVM_OK); 00242 } 00243 00244 static void nvm_ram_timer_cb(void *args) 00245 { 00246 nvm_client_req_t *nvm_client_req_ptr = (nvm_client_req_t *)args; 00247 nvm_client_req_ptr->client_cb(nvm_client_req_ptr->client_status, nvm_client_req_ptr->client_context); 00248 ns_list_remove(&nvm_client_req_list, nvm_client_req_ptr); 00249 FREE(nvm_client_req_ptr); 00250 00251 nvm_context_ptr->callback_timer = NULL; 00252 00253 if (!ns_list_is_empty(&nvm_client_req_list)) { 00254 // there are more client requests to process 00255 nvm_client_req_ptr = ns_list_get_first(&nvm_client_req_list); 00256 nvm_ram_timer_start(nvm_client_req_ptr); 00257 } 00258 } 00259 00260 static void nvm_ram_timer_start(void *ctx) 00261 { 00262 nvm_context_ptr->callback_timer = eventOS_timeout_ms(nvm_ram_timer_cb, 50, ctx); 00263 } 00264 00265 static void nvm_ram_free_entry(nvm_data_entry_t *entry) 00266 { 00267 FREE(entry->key); 00268 FREE(entry->data); 00269 FREE(entry); 00270 } 00271 00272 #endif /* IGNORE_SIMULATED_NVM_STORAGE */
Generated on Tue Jul 12 2022 13:16:02 by
