Mistake on this page?
Report an issue in GitHub or email us
nvstore.h
1 /*
2  * Copyright (c) 2018 ARM Limited. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  * Licensed under the Apache License, Version 2.0 (the License); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MBED_NVSTORE_H
18 #define MBED_NVSTORE_H
19 
20 // These addresses need to be configured according to board (in mbed_lib.json)
21 #if !DEVICE_FLASH
22 #undef NVSTORE_ENABLED
23 #define NVSTORE_ENABLED 0
24 #endif
25 
26 #if (NVSTORE_ENABLED) || defined(DOXYGEN_ONLY)
27 #include <stdint.h>
28 #include <stdio.h>
29 #include "platform/NonCopyable.h"
30 #include "PlatformMutex.h"
31 #include "FlashIAP.h"
32 
33 typedef enum {
34  NVSTORE_SUCCESS = 0,
35  NVSTORE_READ_ERROR = -1,
36  NVSTORE_WRITE_ERROR = -2,
37  NVSTORE_NOT_FOUND = -3,
38  NVSTORE_DATA_CORRUPT = -4,
39  NVSTORE_BAD_VALUE = -5,
40  NVSTORE_BUFF_TOO_SMALL = -6,
41  NVSTORE_FLASH_AREA_TOO_SMALL = -7,
42  NVSTORE_OS_ERROR = -8,
43  NVSTORE_ALREADY_EXISTS = -9,
44  NVSTORE_NO_FREE_KEY = -10,
45 } nvstore_status_e;
46 
47 typedef enum {
48  NVSTORE_FIRST_PREDEFINED_KEY = 0,
49 
50  // All predefined keys used for internal features should be defined here
51 
52  NVSTORE_DEVICEKEY_KEY = 4,
53 
54  NVSTORE_LAST_PREDEFINED_KEY = 15,
55  NVSTORE_NUM_PREDEFINED_KEYS
56 } nvstore_predefined_keys_e;
57 
58 typedef enum {
59  NVSTORE_UNSPECIFIED_OWNER = 0,
60  // All owners (by features) should be specified here.
61  NVSTORE_MAX_OWNERS = 16
62 } nvstore_owner_e;
63 
64 #ifndef NVSTORE_MAX_KEYS
65 #define NVSTORE_MAX_KEYS ((uint16_t)NVSTORE_NUM_PREDEFINED_KEYS)
66 #endif
67 
68 // defines 2 areas - active and nonactive, not configurable
69 #define NVSTORE_NUM_AREAS 2
70 
71 /** NVStore class
72  *
73  * Class for storing data by keys in the internal flash
74  */
75 
76 class NVStore : private mbed::NonCopyable<NVStore> {
77 public:
78 
79  /**
80  * @brief As a singleton, return the single instance of the class.
81  * Reason for this class being a singleton is the following:
82  * - Ease the use for users of this class not having to coordinate instantiations.
83  * - Lazy instantiation of internal data (which we can't achieve with simple static classes).
84  *
85  * @returns Singleton instance reference.
86  */
88  {
89  // Use this implementation of singleton (Meyer's) rather than the one that allocates
90  // the instance on the heap because it ensures destruction at program end (preventing warnings
91  // from memory checking tools).
92  static NVStore instance;
93  return instance;
94  }
95 
96  virtual ~NVStore();
97 
98  /**
99  * @brief Returns number of keys.
100  *
101  * @returns Number of keys.
102  */
103  uint16_t get_max_keys() const;
104 
105  /**
106  * @brief Set number of keys.
107  *
108  * @returns None.
109  */
110  void set_max_keys(uint16_t num_keys);
111 
112  /**
113  * @brief Return maximal possible number of keys (in this flash configuration).
114  *
115  * @returns Max possible number of keys.
116  */
117  uint16_t get_max_possible_keys();
118 
119  /**
120  * @brief Returns one item of data programmed on Flash, given key.
121  *
122  * @param[in] key Key of stored item.
123  * @param[in] buf_size Length of input buffer in bytes.
124  * @param[in] buf Buffer to store data on.
125  *
126  * @param[out] actual_size Actual size of returned data.
127  *
128  * @returns NVSTORE_SUCCESS Value was found on Flash.
129  * NVSTORE_NOT_FOUND Value was not found on Flash.
130  * NVSTORE_READ_ERROR Physical error reading data.
131  * NVSTORE_DATA_CORRUPT Data on Flash is corrupt.
132  * NVSTORE_BAD_VALUE Bad value in any of the parameters.
133  * NVSTORE_BUFF_TOO_SMALL Not enough memory in user buffer.
134  */
135  int get(uint16_t key, uint16_t buf_size, void *buf, uint16_t &actual_size);
136 
137  /**
138  * @brief Returns size of the data programmed on Flash, given key.
139  *
140  * @param[in] key Key of stored item.
141  * @param[out] actual_size Actual size of item
142  *
143  * @returns NVSTORE_SUCCESS Value was found on Flash.
144  * NVSTORE_NOT_FOUND Value was not found on Flash.
145  * NVSTORE_READ_ERROR Physical error reading data.
146  * NVSTORE_DATA_CORRUPT Data on Flash is corrupt.
147  * NVSTORE_BAD_VALUE Bad value in any of the parameters.
148  */
149  int get_item_size(uint16_t key, uint16_t &actual_size);
150 
151 
152  /**
153  * @brief Programs one item of data on Flash, given key.
154  *
155  * @param[in] key Key of stored item.
156  * @param[in] buf_size Item size in bytes.
157  * @param[in] buf Buffer containing data.
158  *
159  * @returns NVSTORE_SUCCESS Value was successfully written on Flash.
160  * NVSTORE_WRITE_ERROR Physical error writing data.
161  * NVSTORE_BAD_VALUE Bad value in any of the parameters.
162  * NVSTORE_FLASH_AREA_TOO_SMALL
163  * Not enough space in Flash area.
164  * NVSTORE_ALREADY_EXISTS Item set with write once API already exists.
165  *
166  */
167  int set(uint16_t key, uint16_t buf_size, const void *buf);
168 
169  /**
170  * @brief Allocate a free key (to be used later in a set operation).
171  *
172  * @param[out] key Returned key of stored item.
173  * @param[in] owner Owner of allocated key.
174  *
175  * @returns NVSTORE_SUCCESS Key was successfully allocated.
176  * NVSTORE_NO_FREE_KEY Couldn't allocate a key for this call.
177  *
178  */
179  int allocate_key(uint16_t &key, uint8_t owner = NVSTORE_UNSPECIFIED_OWNER);
180 
181  /**
182  * @brief Free all allocated keys that belong to a specific owner.
183  *
184  * @param[in] owner Owner.
185  *
186  * @returns NVSTORE_SUCCESS Value was successfully written on Flash.
187  * NVSTORE_WRITE_ERROR Physical error writing data.
188  * NVSTORE_BAD_VALUE Bad value in any of the parameters.
189  *
190  */
191  int free_all_keys_by_owner(uint8_t owner);
192 
193  /**
194  * @brief Programs one item of data on Flash, given key, allowing no consequent sets to this key.
195  *
196  * @param[in] key Key of stored item.
197  * @param[in] buf_size Item size in bytes.
198  * @param[in] buf Buffer containing data.
199  *
200  * @returns NVSTORE_SUCCESS Value was successfully written on Flash.
201  * NVSTORE_WRITE_ERROR Physical error writing data.
202  * NVSTORE_BAD_VALUE Bad value in any of the parameters.
203  * NVSTORE_FLASH_AREA_TOO_SMALL
204  * Not enough space in Flash area.
205  * NVSTORE_ALREADY_EXISTS Item set with write once API already exists.
206  *
207  */
208  int set_once(uint16_t key, uint16_t buf_size, const void *buf);
209 
210 
211  /**
212  * @brief Remove an item from flash.
213  *
214  * @param[in] key Key of stored item.
215  *
216  * @returns NVSTORE_SUCCESS Value was successfully written on Flash.
217  * NVSTORE_WRITE_ERROR Physical error writing data.
218  * NVSTORE_BAD_VALUE Bad value in any of the parameters.
219  * NVSTORE_FLASH_AREA_TOO_SMALL
220  * Not enough space in Flash area.
221  *
222  */
223  int remove(uint16_t key);
224 
225  /**
226  * @brief Initializes NVStore component.
227  *
228  * @returns NVSTORE_SUCCESS Initialization completed successfully.
229  * NVSTORE_READ_ERROR Physical error reading data.
230  * NVSTORE_WRITE_ERROR Physical error writing data (on recovery).
231  * NVSTORE_FLASH_AREA_TOO_SMALL
232  * Not enough space in Flash area.
233  */
234  int init();
235 
236  /**
237  * @brief Deinitializes NVStore component.
238  * Warning: This function is not thread safe and should not be called
239  * concurrently with other NVStore functions.
240  *
241  * @returns NVSTORE_SUCCESS Deinitialization completed successfully.
242  */
243  int deinit();
244 
245  /**
246  * @brief Reset Flash NVStore areas.
247  * Warning: This function is not thread safe and should not be called
248  * concurrently with other NVStore functions.
249  *
250  * @returns NVSTORE_SUCCESS Reset completed successfully.
251  * NVSTORE_READ_ERROR Physical error reading data.
252  * NVSTORE_WRITE_ERROR Physical error writing data.
253  */
254  int reset();
255 
256  /**
257  * @brief Return NVStore size (area size).
258  *
259  * @returns NVStore size.
260  */
261  size_t size();
262 
263  /**
264  * @brief Return address and size of an NVStore area.
265  *
266  * @param[in] area Area.
267  * @param[out] address Area address.
268  * @param[out] size Area size (bytes).
269  *
270  * @returns NVSTORE_SUCCESS Success.
271  * NVSTORE_BAD_VALUE Bad area parameter.
272  */
273  int get_area_params(uint8_t area, uint32_t &address, size_t &size);
274 
275 private:
276  typedef struct {
277  uint32_t address;
278  size_t size;
279  } nvstore_area_data_t;
280 
281  int _init_done;
282  uint32_t _init_attempts;
283  uint8_t _active_area;
284  uint16_t _max_keys;
285  uint16_t _active_area_version;
286  uint32_t _free_space_offset;
287  size_t _size;
288  PlatformMutex *_mutex;
289  uint32_t *_offset_by_key;
290  nvstore_area_data_t _flash_area_params[NVSTORE_NUM_AREAS];
291  static nvstore_area_data_t initial_area_params[NVSTORE_NUM_AREAS];
292  mbed::FlashIAP *_flash;
293  uint32_t _min_prog_size;
294  uint8_t *_page_buf;
295 
296  // Private constructor, as class is a singleton
297  NVStore();
298 
299  /**
300  * @brief Read a block from an area.
301  *
302  * @param[in] area Area.
303  * @param[in] offset Offset in area.
304  * @param[in] size Number of bytes to read.
305  * @param[in] buf Output buffer.
306  *
307  * @returns 0 for success, nonzero for failure.
308  */
309  int flash_read_area(uint8_t area, uint32_t offset, uint32_t size, void *buf);
310 
311  /**
312  * @brief Write a block to an area.
313  *
314  * @param[in] area Area.
315  * @param[in] offset Offset in area.
316  * @param[in] size Number of bytes to write.
317  * @param[in] buf Input buffer.
318  *
319  * @returns 0 for success, non-zero for failure.
320  */
321  int flash_write_area(uint8_t area, uint32_t offset, uint32_t size, const void *buf);
322 
323  /**
324  * @brief Erase an area.
325  *
326  * @param[in] area Area.
327  *
328  * @returns 0 for success, nonzero for failure.
329  */
330  int flash_erase_area(uint8_t area);
331 
332  /**
333  * @brief Calculate addresses and sizes of areas (in case no user configuration is given),
334  * or validate user configuration (if given).
335  */
336  void calc_validate_area_params();
337 
338  /**
339  * @brief Calculate empty (unprogrammed) continuous space at the end of the area.
340  *
341  * @param[in] area Area.
342  * @param[out] offset Offset of empty space.
343  *
344  * @returns 0 for success, nonzero for failure.
345  */
346  int calc_empty_space(uint8_t area, uint32_t &offset);
347 
348  /**
349  * @brief Read an NVStore record from a given location.
350  *
351  * @param[in] area Area.
352  * @param[in] offset Offset of record in area.
353  * @param[in] buf_size Buffer size (bytes).
354  * @param[in] buf Output Buffer.
355  * @param[out] actual_size Actual data size (bytes).
356  * @param[in] validate_only Just validate (without reading to buffer).
357  * @param[out] valid Is the record valid.
358  * @param[out] key Record key.
359  * @param[out] flags Record flags.
360  * @param[out] owner Owner.
361  * @param[out] next_offset Offset of next record.
362  *
363  * @returns 0 for success, nonzero for failure.
364  */
365  int read_record(uint8_t area, uint32_t offset, uint16_t buf_size, void *buf,
366  uint16_t &actual_size, int validate_only, int &valid,
367  uint16_t &key, uint16_t &flags, uint8_t &owner, uint32_t &next_offset);
368 
369  /**
370  * @brief Write an NVStore record from a given location.
371  *
372  * @param[in] area Area.
373  * @param[in] offset Offset of record in area.
374  * @param[in] key Record key.
375  * @param[in] flags Record flags.
376  * @param[in] owner Owner.
377  * @param[in] data_size Data size (bytes).
378  * @param[in] data_buf Data buffer.
379  * @param[out] next_offset Offset of next record.
380  *
381  * @returns 0 for success, nonzero for failure.
382  */
383  int write_record(uint8_t area, uint32_t offset, uint16_t key, uint16_t flags, uint8_t owner,
384  uint32_t data_size, const void *data_buf, uint32_t &next_offset);
385 
386  /**
387  * @brief Write a master record of a given area.
388  *
389  * @param[in] area Area.
390  * @param[in] version Area version.
391  * @param[out] next_offset Offset of next record.
392  *
393  * @returns 0 for success, nonzero for failure.
394  */
395  int write_master_record(uint8_t area, uint16_t version, uint32_t &next_offset);
396 
397  /**
398  * @brief Copy a record from one area to the other one.
399  *
400  * @param[in] from_area Area to copy record from.
401  * @param[in] from_offset Offset in source area.
402  * @param[in] to_offset Offset in destination area.
403  * @param[out] next_offset Offset of next record.
404  *
405  * @returns 0 for success, nonzero for failure.
406  */
407  int copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_offset,
408  uint32_t &next_offset);
409 
410  /**
411  * @brief Garbage collection (compact all records from active area to nonactive ones).
412  * All parameters belong to a record that needs to be written before the process.
413  *
414  * @param[in] key Record key.
415  * @param[in] flags Record flags.
416  * @param[in] owner Owner.
417  * @param[in] buf_size Data size (bytes).
418  * @param[in] buf Data buffer.
419  * @param[in] num_keys number of keys.
420  *
421  * @returns 0 for success, nonzero for failure.
422  */
423  int garbage_collection(uint16_t key, uint16_t flags, uint8_t owner, uint16_t buf_size, const void *buf, uint16_t num_keys);
424 
425  /**
426  * @brief Actual logics of get API (covers also get size API).
427  *
428  * @param[in] key key.
429  * @param[in] buf_size Buffer size (bytes).
430  * @param[in] buf Output Buffer.
431  * @param[out] actual_size Actual data size (bytes).
432  * @param[in] validate_only Just validate (without reading to buffer).
433  *
434  * @returns 0 for success, nonzero for failure.
435  */
436  int do_get(uint16_t key, uint16_t buf_size, void *buf, uint16_t &actual_size,
437  int validate_only);
438 
439  /**
440  * @brief Actual logics of set API (covers also set_once and remove APIs).
441  *
442  * @param[in] key key.
443  * @param[in] buf_size Buffer size (bytes).
444  * @param[in] buf Input Buffer.
445  * @param[in] flags Record flags.
446  *
447  * @returns 0 for success, nonzero for failure.
448  */
449  int do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t flags);
450 
451 };
452 /** @}*/
453 
454 #endif // NVSTORE_ENABLED
455 
456 #endif
int set_once(uint16_t key, uint16_t buf_size, const void *buf)
Programs one item of data on Flash, given key, allowing no consequent sets to this key...
uint16_t get_max_keys() const
Returns number of keys.
void set_max_keys(uint16_t num_keys)
Set number of keys.
int allocate_key(uint16_t &key, uint8_t owner=NVSTORE_UNSPECIFIED_OWNER)
Allocate a free key (to be used later in a set operation).
int free_all_keys_by_owner(uint8_t owner)
Free all allocated keys that belong to a specific owner.
uint16_t get_max_possible_keys()
Return maximal possible number of keys (in this flash configuration).
int get_area_params(uint8_t area, uint32_t &address, size_t &size)
Return address and size of an NVStore area.
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:168
NVStore class.
Definition: nvstore.h:76
size_t size()
Return NVStore size (area size).
The PlatformMutex class is used to synchronize the execution of threads.
Definition: PlatformMutex.h:47
int deinit()
Deinitializes NVStore component.
int reset()
Reset Flash NVStore areas.
int get_item_size(uint16_t key, uint16_t &actual_size)
Returns size of the data programmed on Flash, given key.
Flash IAP driver.
Definition: FlashIAP.h:59
static NVStore & get_instance()
As a singleton, return the single instance of the class.
Definition: nvstore.h:87
int init()
Initializes NVStore component.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.