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.
nvstore.h
00001 /* 00002 * Copyright (c) 2018 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 #ifndef MBED_NVSTORE_H 00018 #define MBED_NVSTORE_H 00019 00020 // These addresses need to be configured according to board (in mbed_lib.json) 00021 #ifndef DEVICE_FLASH 00022 #undef NVSTORE_ENABLED 00023 #define NVSTORE_ENABLED 0 00024 #endif 00025 00026 #if (NVSTORE_ENABLED) || defined(DOXYGEN_ONLY) 00027 #include <stdint.h> 00028 #include <stdio.h> 00029 #include "platform/NonCopyable.h" 00030 #include "PlatformMutex.h" 00031 #include "FlashIAP.h" 00032 00033 typedef enum { 00034 NVSTORE_SUCCESS = 0, 00035 NVSTORE_READ_ERROR = -1, 00036 NVSTORE_WRITE_ERROR = -2, 00037 NVSTORE_NOT_FOUND = -3, 00038 NVSTORE_DATA_CORRUPT = -4, 00039 NVSTORE_BAD_VALUE = -5, 00040 NVSTORE_BUFF_TOO_SMALL = -6, 00041 NVSTORE_FLASH_AREA_TOO_SMALL = -7, 00042 NVSTORE_OS_ERROR = -8, 00043 NVSTORE_ALREADY_EXISTS = -9, 00044 NVSTORE_NO_FREE_KEY = -10, 00045 } nvstore_status_e; 00046 00047 typedef enum { 00048 NVSTORE_FIRST_PREDEFINED_KEY = 0, 00049 00050 // All predefined keys used for internal features should be defined here 00051 00052 NVSTORE_DEVICEKEY_KEY = 4, 00053 00054 NVSTORE_LAST_PREDEFINED_KEY = 15, 00055 NVSTORE_NUM_PREDEFINED_KEYS 00056 } nvstore_predefined_keys_e; 00057 00058 typedef enum { 00059 NVSTORE_UNSPECIFIED_OWNER = 0, 00060 // All owners (by features) should be specified here. 00061 NVSTORE_MAX_OWNERS = 16 00062 } nvstore_owner_e; 00063 00064 #ifndef NVSTORE_MAX_KEYS 00065 #define NVSTORE_MAX_KEYS ((uint16_t)NVSTORE_NUM_PREDEFINED_KEYS) 00066 #endif 00067 00068 // defines 2 areas - active and nonactive, not configurable 00069 #define NVSTORE_NUM_AREAS 2 00070 00071 /** NVStore class 00072 * 00073 * Class for storing data by keys in the internal flash 00074 */ 00075 00076 class NVStore : private mbed::NonCopyable<NVStore> { 00077 public: 00078 00079 /** 00080 * @brief As a singleton, return the single instance of the class. 00081 * Reason for this class being a singleton is the following: 00082 * - Ease the use for users of this class not having to coordinate instantiations. 00083 * - Lazy instantiation of internal data (which we can't achieve with simple static classes). 00084 * 00085 * @returns Singleton instance reference. 00086 */ 00087 static NVStore& get_instance() 00088 { 00089 // Use this implementation of singleton (Meyer's) rather than the one that allocates 00090 // the instance on the heap because it ensures destruction at program end (preventing warnings 00091 // from memory checking tools). 00092 static NVStore instance; 00093 return instance; 00094 } 00095 00096 virtual ~NVStore(); 00097 00098 /** 00099 * @brief Returns number of keys. 00100 * 00101 * @returns Number of keys. 00102 */ 00103 uint16_t get_max_keys() const; 00104 00105 /** 00106 * @brief Set number of keys. 00107 * 00108 * @returns None. 00109 */ 00110 void set_max_keys(uint16_t num_keys); 00111 00112 /** 00113 * @brief Return maximal possible number of keys (in this flash configuration). 00114 * 00115 * @returns Max possible number of keys. 00116 */ 00117 uint16_t get_max_possible_keys(); 00118 00119 /** 00120 * @brief Returns one item of data programmed on Flash, given key. 00121 * 00122 * @param[in] key Key of stored item. 00123 * @param[in] buf_size Length of input buffer in bytes. 00124 * @param[in] buf Buffer to store data on. 00125 * 00126 * @param[out] actual_size Actual size of returned data. 00127 * 00128 * @returns NVSTORE_SUCCESS Value was found on Flash. 00129 * NVSTORE_NOT_FOUND Value was not found on Flash. 00130 * NVSTORE_READ_ERROR Physical error reading data. 00131 * NVSTORE_DATA_CORRUPT Data on Flash is corrupt. 00132 * NVSTORE_BAD_VALUE Bad value in any of the parameters. 00133 * NVSTORE_BUFF_TOO_SMALL Not enough memory in user buffer. 00134 */ 00135 int get(uint16_t key, uint16_t buf_size, void *buf, uint16_t &actual_size); 00136 00137 /** 00138 * @brief Returns size of the data programmed on Flash, given key. 00139 * 00140 * @param[in] key Key of stored item. 00141 * @param[out] actual_size Actual size of item 00142 * 00143 * @returns NVSTORE_SUCCESS Value was found on Flash. 00144 * NVSTORE_NOT_FOUND Value was not found on Flash. 00145 * NVSTORE_READ_ERROR Physical error reading data. 00146 * NVSTORE_DATA_CORRUPT Data on Flash is corrupt. 00147 * NVSTORE_BAD_VALUE Bad value in any of the parameters. 00148 */ 00149 int get_item_size(uint16_t key, uint16_t &actual_size); 00150 00151 00152 /** 00153 * @brief Programs one item of data on Flash, given key. 00154 * 00155 * @param[in] key Key of stored item. 00156 * @param[in] buf_size Item size in bytes. 00157 * @param[in] buf Buffer containing data. 00158 * 00159 * @returns NVSTORE_SUCCESS Value was successfully written on Flash. 00160 * NVSTORE_WRITE_ERROR Physical error writing data. 00161 * NVSTORE_BAD_VALUE Bad value in any of the parameters. 00162 * NVSTORE_FLASH_AREA_TOO_SMALL 00163 * Not enough space in Flash area. 00164 * NVSTORE_ALREADY_EXISTS Item set with write once API already exists. 00165 * 00166 */ 00167 int set(uint16_t key, uint16_t buf_size, const void *buf); 00168 00169 /** 00170 * @brief Allocate a free key (to be used later in a set operation). 00171 * 00172 * @param[out] key Returned key of stored item. 00173 * @param[in] owner Owner of allocated key. 00174 * 00175 * @returns NVSTORE_SUCCESS Key was successfully allocated. 00176 * NVSTORE_NO_FREE_KEY Couldn't allocate a key for this call. 00177 * 00178 */ 00179 int allocate_key(uint16_t &key, uint8_t owner = NVSTORE_UNSPECIFIED_OWNER); 00180 00181 /** 00182 * @brief Free all allocated keys that belong to a specific owner. 00183 * 00184 * @param[in] owner Owner. 00185 * 00186 * @returns NVSTORE_SUCCESS Value was successfully written on Flash. 00187 * NVSTORE_WRITE_ERROR Physical error writing data. 00188 * NVSTORE_BAD_VALUE Bad value in any of the parameters. 00189 * 00190 */ 00191 int free_all_keys_by_owner(uint8_t owner); 00192 00193 /** 00194 * @brief Programs one item of data on Flash, given key, allowing no consequent sets to this key. 00195 * 00196 * @param[in] key Key of stored item. 00197 * @param[in] buf_size Item size in bytes. 00198 * @param[in] buf Buffer containing data. 00199 * 00200 * @returns NVSTORE_SUCCESS Value was successfully written on Flash. 00201 * NVSTORE_WRITE_ERROR Physical error writing data. 00202 * NVSTORE_BAD_VALUE Bad value in any of the parameters. 00203 * NVSTORE_FLASH_AREA_TOO_SMALL 00204 * Not enough space in Flash area. 00205 * NVSTORE_ALREADY_EXISTS Item set with write once API already exists. 00206 * 00207 */ 00208 int set_once(uint16_t key, uint16_t buf_size, const void *buf); 00209 00210 00211 /** 00212 * @brief Remove an item from flash. 00213 * 00214 * @param[in] key Key of stored item. 00215 * 00216 * @returns NVSTORE_SUCCESS Value was successfully written on Flash. 00217 * NVSTORE_WRITE_ERROR Physical error writing data. 00218 * NVSTORE_BAD_VALUE Bad value in any of the parameters. 00219 * NVSTORE_FLASH_AREA_TOO_SMALL 00220 * Not enough space in Flash area. 00221 * 00222 */ 00223 int remove(uint16_t key); 00224 00225 /** 00226 * @brief Initializes NVStore component. 00227 * 00228 * @returns NVSTORE_SUCCESS Initialization completed successfully. 00229 * NVSTORE_READ_ERROR Physical error reading data. 00230 * NVSTORE_WRITE_ERROR Physical error writing data (on recovery). 00231 * NVSTORE_FLASH_AREA_TOO_SMALL 00232 * Not enough space in Flash area. 00233 */ 00234 int init(); 00235 00236 /** 00237 * @brief Deinitializes NVStore component. 00238 * Warning: This function is not thread safe and should not be called 00239 * concurrently with other NVStore functions. 00240 * 00241 * @returns NVSTORE_SUCCESS Deinitialization completed successfully. 00242 */ 00243 int deinit(); 00244 00245 /** 00246 * @brief Reset Flash NVStore areas. 00247 * Warning: This function is not thread safe and should not be called 00248 * concurrently with other NVStore functions. 00249 * 00250 * @returns NVSTORE_SUCCESS Reset completed successfully. 00251 * NVSTORE_READ_ERROR Physical error reading data. 00252 * NVSTORE_WRITE_ERROR Physical error writing data. 00253 */ 00254 int reset(); 00255 00256 /** 00257 * @brief Return NVStore size (area size). 00258 * 00259 * @returns NVStore size. 00260 */ 00261 size_t size(); 00262 00263 /** 00264 * @brief Return address and size of an NVStore area. 00265 * 00266 * @param[in] area Area. 00267 * @param[out] address Area address. 00268 * @param[out] size Area size (bytes). 00269 * 00270 * @returns NVSTORE_SUCCESS Success. 00271 * NVSTORE_BAD_VALUE Bad area parameter. 00272 */ 00273 int get_area_params(uint8_t area, uint32_t &address, size_t &size); 00274 00275 00276 private: 00277 typedef struct { 00278 uint32_t address; 00279 size_t size; 00280 } nvstore_area_data_t; 00281 00282 int _init_done; 00283 uint32_t _init_attempts; 00284 uint8_t _active_area; 00285 uint16_t _max_keys; 00286 uint16_t _active_area_version; 00287 uint32_t _free_space_offset; 00288 size_t _size; 00289 PlatformMutex *_mutex; 00290 uint32_t *_offset_by_key; 00291 nvstore_area_data_t _flash_area_params[NVSTORE_NUM_AREAS]; 00292 static nvstore_area_data_t initial_area_params[NVSTORE_NUM_AREAS]; 00293 mbed::FlashIAP *_flash; 00294 uint32_t _min_prog_size; 00295 uint8_t *_page_buf; 00296 00297 // Private constructor, as class is a singleton 00298 NVStore(); 00299 00300 /** 00301 * @brief Read a block from an area. 00302 * 00303 * @param[in] area Area. 00304 * @param[in] offset Offset in area. 00305 * @param[in] size Number of bytes to read. 00306 * @param[in] buf Output buffer. 00307 * 00308 * @returns 0 for success, nonzero for failure. 00309 */ 00310 int flash_read_area(uint8_t area, uint32_t offset, uint32_t size, void *buf); 00311 00312 /** 00313 * @brief Write a block to an area. 00314 * 00315 * @param[in] area Area. 00316 * @param[in] offset Offset in area. 00317 * @param[in] size Number of bytes to write. 00318 * @param[in] buf Input buffer. 00319 * 00320 * @returns 0 for success, non-zero for failure. 00321 */ 00322 int flash_write_area(uint8_t area, uint32_t offset, uint32_t size, const void *buf); 00323 00324 /** 00325 * @brief Erase an area. 00326 * 00327 * @param[in] area Area. 00328 * 00329 * @returns 0 for success, nonzero for failure. 00330 */ 00331 int flash_erase_area(uint8_t area); 00332 00333 /** 00334 * @brief Calculate addresses and sizes of areas (in case no user configuration is given), 00335 * or validate user configuration (if given). 00336 */ 00337 void calc_validate_area_params(); 00338 00339 /** 00340 * @brief Calculate empty (unprogrammed) continuous space at the end of the area. 00341 * 00342 * @param[in] area Area. 00343 * @param[out] offset Offset of empty space. 00344 * 00345 * @returns 0 for success, nonzero for failure. 00346 */ 00347 int calc_empty_space(uint8_t area, uint32_t &offset); 00348 00349 /** 00350 * @brief Read an NVStore record from a given location. 00351 * 00352 * @param[in] area Area. 00353 * @param[in] offset Offset of record in area. 00354 * @param[in] buf_size Buffer size (bytes). 00355 * @param[in] buf Output Buffer. 00356 * @param[out] actual_size Actual data size (bytes). 00357 * @param[in] validate_only Just validate (without reading to buffer). 00358 * @param[out] valid Is the record valid. 00359 * @param[out] key Record key. 00360 * @param[out] flags Record flags. 00361 * @param[out] owner Owner. 00362 * @param[out] next_offset Offset of next record. 00363 * 00364 * @returns 0 for success, nonzero for failure. 00365 */ 00366 int read_record(uint8_t area, uint32_t offset, uint16_t buf_size, void *buf, 00367 uint16_t &actual_size, int validate_only, int &valid, 00368 uint16_t &key, uint16_t &flags, uint8_t &owner, uint32_t &next_offset); 00369 00370 /** 00371 * @brief Write an NVStore record from a given location. 00372 * 00373 * @param[in] area Area. 00374 * @param[in] offset Offset of record in area. 00375 * @param[in] key Record key. 00376 * @param[in] flags Record flags. 00377 * @param[in] owner Owner. 00378 * @param[in] data_size Data size (bytes). 00379 * @param[in] data_buf Data buffer. 00380 * @param[out] next_offset Offset of next record. 00381 * 00382 * @returns 0 for success, nonzero for failure. 00383 */ 00384 int write_record(uint8_t area, uint32_t offset, uint16_t key, uint16_t flags, uint8_t owner, 00385 uint32_t data_size, const void *data_buf, uint32_t &next_offset); 00386 00387 /** 00388 * @brief Write a master record of a given area. 00389 * 00390 * @param[in] area Area. 00391 * @param[in] version Area version. 00392 * @param[out] next_offset Offset of next record. 00393 * 00394 * @returns 0 for success, nonzero for failure. 00395 */ 00396 int write_master_record(uint8_t area, uint16_t version, uint32_t &next_offset); 00397 00398 /** 00399 * @brief Copy a record from one area to the other one. 00400 * 00401 * @param[in] from_area Area to copy record from. 00402 * @param[in] from_offset Offset in source area. 00403 * @param[in] to_offset Offset in destination area. 00404 * @param[out] next_offset Offset of next record. 00405 * 00406 * @returns 0 for success, nonzero for failure. 00407 */ 00408 int copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_offset, 00409 uint32_t &next_offset); 00410 00411 /** 00412 * @brief Garbage collection (compact all records from active area to nonactive ones). 00413 * All parameters belong to a record that needs to be written before the process. 00414 * 00415 * @param[in] key Record key. 00416 * @param[in] flags Record flags. 00417 * @param[in] owner Owner. 00418 * @param[in] buf_size Data size (bytes). 00419 * @param[in] buf Data buffer. 00420 * 00421 * @returns 0 for success, nonzero for failure. 00422 */ 00423 int garbage_collection(uint16_t key, uint16_t flags, uint8_t owner, uint16_t buf_size, const void *buf); 00424 00425 /** 00426 * @brief Actual logics of get API (covers also get size API). 00427 * 00428 * @param[in] key key. 00429 * @param[in] buf_size Buffer size (bytes). 00430 * @param[in] buf Output Buffer. 00431 * @param[out] actual_size Actual data size (bytes). 00432 * @param[in] validate_only Just validate (without reading to buffer). 00433 * 00434 * @returns 0 for success, nonzero for failure. 00435 */ 00436 int do_get(uint16_t key, uint16_t buf_size, void *buf, uint16_t &actual_size, 00437 int validate_only); 00438 00439 /** 00440 * @brief Actual logics of set API (covers also set_once and remove APIs). 00441 * 00442 * @param[in] key key. 00443 * @param[in] buf_size Buffer size (bytes). 00444 * @param[in] buf Input Buffer. 00445 * @param[in] flags Record flags. 00446 * 00447 * @returns 0 for success, nonzero for failure. 00448 */ 00449 int do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t flags); 00450 00451 }; 00452 /** @}*/ 00453 00454 #endif // NVSTORE_ENABLED 00455 00456 #endif
Generated on Tue Jul 12 2022 12:45:39 by
