Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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