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