Denislam Valeev / Mbed OS Nucleo_rtos_basic
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nvstore.h Source File

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