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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
TDBStore.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_TDBSTORE_H 00018 #define MBED_TDBSTORE_H 00019 00020 #include <stdint.h> 00021 #include <stdio.h> 00022 #include "features/storage/kvstore/include/KVStore.h" 00023 #include "features/storage/blockdevice/BlockDevice.h" 00024 #include "features/storage/blockdevice/BufferedBlockDevice.h" 00025 #include "PlatformMutex.h" 00026 #include "mbed_error.h" 00027 00028 namespace mbed { 00029 00030 /** TDBStore class 00031 * 00032 * Lightweight Key Value storage over a block device 00033 */ 00034 00035 class TDBStore : public KVStore { 00036 public: 00037 00038 static const uint32_t RESERVED_AREA_SIZE = 64; 00039 00040 /** 00041 * @brief Class constructor 00042 * 00043 * @param[in] bd Underlying block device. The BlockDevice 00044 * can be any BlockDevice with flash characteristics. 00045 * If using a BlockDevice without flash, such as SDBlockDevice, 00046 * please add the FlashSimBlockDevice on top of it. 00047 * 00048 * @returns none 00049 */ 00050 TDBStore(BlockDevice *bd); 00051 00052 /** 00053 * @brief Class destructor 00054 * 00055 * @returns none 00056 */ 00057 virtual ~TDBStore(); 00058 00059 /** 00060 * @brief Initialize TDBStore. If data exists, TDBStore will check the data integrity 00061 * on initialize. If the integrity checks fails, the TDBStore will use GC to collect 00062 * the available data and clean corrupted and erroneous records. 00063 * 00064 * @returns MBED_SUCCESS Success. 00065 * @returns Negative error code on failure. 00066 */ 00067 virtual int init(); 00068 00069 /** 00070 * @brief Deinitialize TDBStore, release and free resources. 00071 * 00072 * @returns MBED_SUCCESS Success. 00073 */ 00074 virtual int deinit(); 00075 00076 00077 /** 00078 * @brief Reset TDBStore contents (clear all keys) and reserved data 00079 * 00080 * @returns MBED_SUCCESS Success. 00081 * MBED_ERROR_NOT_READY Not initialized. 00082 * MBED_ERROR_READ_FAILED Unable to read from media. 00083 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00084 */ 00085 virtual int reset(); 00086 00087 /** 00088 * @brief Set one TDBStore item, given key and value. 00089 * 00090 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00091 * @param[in] buffer Value data buffer. 00092 * @param[in] size Value data size. 00093 * @param[in] create_flags Flag mask. 00094 * 00095 * @returns MBED_SUCCESS Success. 00096 * MBED_ERROR_NOT_READY Not initialized. 00097 * MBED_ERROR_READ_FAILED Unable to read from media. 00098 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00099 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00100 * MBED_ERROR_INVALID_SIZE Invalid size given in function arguments. 00101 * MBED_ERROR_MEDIA_FULL Not enough room on media. 00102 * MBED_ERROR_WRITE_PROTECTED Already stored with "write once" flag. 00103 */ 00104 virtual int set(const char *key, const void *buffer, size_t size, uint32_t create_flags); 00105 00106 /** 00107 * @brief Get one TDBStore item by given key. 00108 * 00109 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00110 * @param[in] buffer Value data buffer. 00111 * @param[in] buffer_size Value data buffer size. 00112 * @param[out] actual_size Actual read size. 00113 * @param[in] offset Offset to read from in data. 00114 * 00115 * @returns MBED_SUCCESS Success. 00116 * MBED_ERROR_NOT_READY Not initialized. 00117 * MBED_ERROR_READ_FAILED Unable to read from media. 00118 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00119 * MBED_ERROR_INVALID_SIZE Invalid size given in function arguments. 00120 * MBED_ERROR_INVALID_DATA_DETECTED Data is corrupt. 00121 * MBED_ERROR_ITEM_NOT_FOUND No such key. 00122 */ 00123 virtual int get(const char *key, void *buffer, size_t buffer_size, size_t *actual_size = NULL, 00124 size_t offset = 0); 00125 00126 /** 00127 * @brief Get information of a given key. The returned info contains size and flags 00128 * 00129 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00130 * @param[out] info Returned information structure. 00131 * 00132 * @returns MBED_SUCCESS Success. 00133 * MBED_ERROR_NOT_READY Not initialized. 00134 * MBED_ERROR_READ_FAILED Unable to read from media. 00135 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00136 * MBED_ERROR_INVALID_DATA_DETECTED Data is corrupt. 00137 * MBED_ERROR_ITEM_NOT_FOUND No such key. 00138 */ 00139 virtual int get_info(const char *key, info_t *info); 00140 00141 /** 00142 * @brief Remove a TDBStore item by given key. 00143 * 00144 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00145 * 00146 * @returns MBED_SUCCESS Success. 00147 * MBED_ERROR_NOT_READY Not initialized. 00148 * MBED_ERROR_READ_FAILED Unable to read from media. 00149 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00150 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00151 * MBED_ERROR_MEDIA_FULL Not enough room on media. 00152 * MBED_ERROR_ITEM_NOT_FOUND No such key. 00153 * MBED_ERROR_WRITE_PROTECTED Already stored with "write once" flag. 00154 */ 00155 virtual int remove(const char *key); 00156 00157 00158 /** 00159 * @brief Start an incremental TDBStore set sequence. This operation is blocking other operations. 00160 * Any get/set/remove/iterator operation will be blocked until set_finalize is called. 00161 * 00162 * @param[out] handle Returned incremental set handle. 00163 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00164 * @param[in] final_data_size Final value data size. 00165 * @param[in] create_flags Flag mask. 00166 * 00167 * @returns MBED_SUCCESS Success. 00168 * MBED_ERROR_NOT_READY Not initialized. 00169 * MBED_ERROR_READ_FAILED Unable to read from media. 00170 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00171 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00172 * MBED_ERROR_INVALID_SIZE Invalid size given in function arguments. 00173 * MBED_ERROR_MEDIA_FULL Not enough room on media. 00174 * MBED_ERROR_WRITE_PROTECTED Already stored with "write once" flag. 00175 */ 00176 virtual int set_start(set_handle_t *handle, const char *key, size_t final_data_size, uint32_t create_flags); 00177 00178 /** 00179 * @brief Add data to incremental TDBStore set sequence. This operation is blocking other operations. 00180 * Any get/set/remove operation will be blocked until set_finalize will be called. 00181 * 00182 * @param[in] handle Incremental set handle. 00183 * @param[in] value_data Value data to add. 00184 * @param[in] data_size Value data size. 00185 * 00186 * @returns MBED_SUCCESS Success. 00187 * MBED_ERROR_NOT_READY Not initialized. 00188 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00189 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00190 * MBED_ERROR_INVALID_SIZE Invalid size given in function arguments. 00191 */ 00192 virtual int set_add_data(set_handle_t handle, const void *value_data, size_t data_size); 00193 00194 /** 00195 * @brief Finalize an incremental KVStore set sequence. 00196 * 00197 * @param[in] handle Incremental set handle. 00198 * 00199 * @returns MBED_SUCCESS Success. 00200 * MBED_ERROR_NOT_READY Not initialized. 00201 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00202 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00203 */ 00204 virtual int set_finalize(set_handle_t handle); 00205 00206 /** 00207 * @brief Start an iteration over KVStore keys. 00208 * There are no issues with any other operations while iterator is open. 00209 * 00210 * @param[out] it Returned iterator handle. 00211 * @param[in] prefix Key prefix (null for all keys). 00212 * 00213 * @returns MBED_SUCCESS Success. 00214 * MBED_ERROR_NOT_READY Not initialized. 00215 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00216 */ 00217 virtual int iterator_open(iterator_t *it, const char *prefix = NULL); 00218 00219 /** 00220 * @brief Get next key in iteration. 00221 * There are no issues with any other operations while iterator is open. 00222 * 00223 * @param[in] it Iterator handle. 00224 * @param[in] key Buffer for returned key. 00225 * @param[in] key_size Key buffer size. 00226 * 00227 * @returns MBED_SUCCESS Success. 00228 * MBED_ERROR_NOT_READY Not initialized. 00229 * MBED_ERROR_READ_FAILED Unable to read from block device. 00230 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00231 * MBED_ERROR_INVALID_SIZE Invalid size given in function arguments. 00232 * MBED_ERROR_INVALID_DATA_DETECTED Data is corrupt. 00233 * MBED_ERROR_ITEM_NOT_FOUND No more keys found. 00234 */ 00235 virtual int iterator_next(iterator_t it, char *key, size_t key_size); 00236 00237 /** 00238 * @brief Close iteration. 00239 * 00240 * @param[in] it Iterator handle. 00241 * 00242 * @returns MBED_SUCCESS Success. 00243 * MBED_ERROR_NOT_READY Not initialized. 00244 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00245 */ 00246 virtual int iterator_close(iterator_t it); 00247 00248 /** 00249 * @brief Set data in reserved area, which is a special location for special data, such as ROT. 00250 * The data written to reserved area can't be overwritten. 00251 * 00252 * @param[in] reserved_data Reserved data buffer. 00253 * @param[in] reserved_data_buf_size 00254 * Reserved data buffer size. 00255 * 00256 * @returns MBED_SUCCESS Success. 00257 * MBED_ERROR_NOT_READY Not initialized. 00258 * MBED_ERROR_READ_FAILED Unable to read from media. 00259 * MBED_ERROR_WRITE_FAILED Unable to write to media. 00260 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00261 * MBED_ERROR_INVALID_SIZE Invalid size given in function arguments. 00262 */ 00263 virtual int reserved_data_set(const void *reserved_data, size_t reserved_data_buf_size); 00264 00265 /** 00266 * @brief Get data from reserved area, which is a special location for special data, such as ROT. 00267 * 00268 * @param[in] reserved_data Reserved data buffer. 00269 * @param[in] reserved_data_buf_size 00270 * Reserved data buffer size. 00271 * @param[in] actual_data_size Return data size. 00272 * 00273 * @returns MBED_SUCCESS Success. 00274 * MBED_ERROR_NOT_READY Not initialized. 00275 * MBED_ERROR_READ_FAILED Unable to read from media. 00276 * MBED_ERROR_INVALID_ARGUMENT Invalid argument given in function arguments. 00277 * MBED_ERROR_INVALID_DATA_DETECTED Data is corrupt. 00278 * MBED_ERROR_ITEM_NOT_FOUND No reserved data was written. 00279 */ 00280 virtual int reserved_data_get(void *reserved_data, size_t reserved_data_buf_size, 00281 size_t *actual_data_size = 0); 00282 00283 #if !defined(DOXYGEN_ONLY) 00284 private: 00285 00286 typedef struct { 00287 uint32_t address; 00288 size_t size; 00289 } tdbstore_area_data_t; 00290 00291 static const int _num_areas = 2; 00292 static const int _max_open_iterators = 16; 00293 00294 PlatformMutex _mutex; 00295 PlatformMutex _inc_set_mutex; 00296 void *_ram_table; 00297 size_t _max_keys; 00298 size_t _num_keys; 00299 BlockDevice *_bd; 00300 BufferedBlockDevice *_buff_bd; 00301 uint32_t _free_space_offset; 00302 uint32_t _master_record_offset; 00303 uint32_t _master_record_size; 00304 bool _is_initialized; 00305 int _active_area; 00306 uint16_t _active_area_version; 00307 size_t _size; 00308 tdbstore_area_data_t _area_params[_num_areas]; 00309 uint32_t _prog_size; 00310 uint8_t *_work_buf; 00311 char *_key_buf; 00312 bool _variant_bd_erase_unit_size; 00313 void *_inc_set_handle; 00314 void *_iterator_table[_max_open_iterators]; 00315 00316 /** 00317 * @brief Read a block from an area. 00318 * 00319 * @param[in] area Area. 00320 * @param[in] offset Offset in area. 00321 * @param[in] size Number of bytes to read. 00322 * @param[in] buf Output buffer. 00323 * 00324 * @returns 0 for success, nonzero for failure. 00325 */ 00326 int read_area(uint8_t area, uint32_t offset, uint32_t size, void *buf); 00327 00328 /** 00329 * @brief Write a block to an area. 00330 * 00331 * @param[in] area Area. 00332 * @param[in] offset Offset in area. 00333 * @param[in] size Number of bytes to write. 00334 * @param[in] buf Input buffer. 00335 * 00336 * @returns 0 for success, non-zero for failure. 00337 */ 00338 int write_area(uint8_t area, uint32_t offset, uint32_t size, const void *buf); 00339 00340 /** 00341 * @brief Reset an area (erase its start). 00342 * This erases master record, but preserves the 00343 * reserved area data. 00344 * 00345 * @param[in] area Area. 00346 * 00347 * @returns 0 for success, nonzero for failure. 00348 */ 00349 int reset_area(uint8_t area); 00350 00351 /** 00352 * @brief Erase an erase unit. 00353 * 00354 * @param[in] area Area. 00355 * @param[in] offset Offset in area. 00356 * 00357 * @returns 0 for success, nonzero for failure. 00358 */ 00359 int erase_erase_unit(uint8_t area, uint32_t offset); 00360 00361 /** 00362 * @brief Calculate addresses and sizes of areas. 00363 */ 00364 void calc_area_params(); 00365 00366 /** 00367 * @brief Read a TDBStore record from a given location. 00368 * 00369 * @param[in] area Area. 00370 * @param[in] offset Offset of record in area. 00371 * @param[out] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00372 * @param[out] data_buf Data buffer. 00373 * @param[in] data_buf_size Data buffer size. 00374 * @param[out] actual_data_size Actual data size. 00375 * @param[in] data_offset Offset in data. 00376 * @param[in] copy_key Copy key to user buffer. 00377 * @param[in] copy_data Copy data to user buffer. 00378 * @param[in] check_expected_key Check whether key belongs to this record. 00379 * @param[in] calc_hash Calculate hash (on key). 00380 * @param[out] hash Calculated hash. 00381 * @param[out] flags Record flags. 00382 * @param[out] next_offset Offset of next record. 00383 * 00384 * @returns 0 for success, nonzero for failure. 00385 */ 00386 int read_record(uint8_t area, uint32_t offset, char *key, 00387 void *data_buf, uint32_t data_buf_size, 00388 uint32_t &actual_data_size, size_t data_offset, bool copy_key, 00389 bool copy_data, bool check_expected_key, bool calc_hash, 00390 uint32_t &hash, uint32_t &flags, uint32_t &next_offset); 00391 00392 /** 00393 * @brief Write a master record of a given area. 00394 * 00395 * @param[in] area Area. 00396 * @param[in] version Area version. 00397 * @param[out] next_offset Offset of next record. 00398 * 00399 * @returns 0 for success, nonzero for failure. 00400 */ 00401 int write_master_record(uint8_t area, uint16_t version, uint32_t &next_offset); 00402 00403 /** 00404 * @brief Copy a record from one area to the opposite one. 00405 * 00406 * @param[in] from_area Area to copy record from. 00407 * @param[in] from_offset Offset in source area. 00408 * @param[in] to_offset Offset in destination area. 00409 * @param[out] to_next_offset Offset of next record in destination area. 00410 * 00411 * @returns 0 for success, nonzero for failure. 00412 */ 00413 int copy_record(uint8_t from_area, uint32_t from_offset, uint32_t to_offset, 00414 uint32_t &to_next_offset); 00415 00416 /** 00417 * @brief Garbage collection (compact all records from active area to the standby one). 00418 * 00419 * @returns 0 for success, nonzero for failure. 00420 */ 00421 int garbage_collection(); 00422 00423 /** 00424 * @brief Return record size given key and data size. 00425 * 00426 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00427 * @param[in] data_size Data size. 00428 * 00429 * @returns record size. 00430 */ 00431 uint32_t record_size(const char *key, uint32_t data_size); 00432 00433 /** 00434 * @brief Find a record given key 00435 * 00436 * @param[in] area Area. 00437 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00438 * @param[out] offset Offset of record. 00439 * @param[out] ram_table_ind Index in RAM table (target one if not found). 00440 * @param[out] hash Calculated key hash. 00441 * 00442 * @returns 0 for success, nonzero for failure. 00443 */ 00444 int find_record(uint8_t area, const char *key, uint32_t &offset, 00445 uint32_t &ram_table_ind, uint32_t &hash); 00446 /** 00447 * @brief Actual logics of get API (also covers all other get APIs). 00448 * 00449 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00450 * @param[in] copy_data Copy data to user buffer. 00451 * @param[in] data_buf Buffer to store data on. 00452 * @param[in] data_buf_size Data buffer size (bytes). 00453 * @param[out] actual_data_size Actual data size (bytes). 00454 * @param[out] flags Flags. 00455 * 00456 * @returns 0 for success, nonzero for failure. 00457 */ 00458 int do_get(const char *key, bool copy_data, 00459 void *data_buf, uint32_t data_buf_size, uint32_t &actual_data_size, 00460 uint32_t &flags); 00461 00462 /** 00463 * @brief Actual logics of set API (covers also the remove API). 00464 * 00465 * @param[in] key Key - must not include '*' '/' '?' ':' ';' '\' '"' '|' ' ' '<' '>' '\'. 00466 * @param[in] data_buf Data buffer. 00467 * @param[in] data_buf_size Data buffer size (bytes). 00468 * @param[in] flags Flags. 00469 * 00470 * @returns 0 for success, nonzero for failure. 00471 */ 00472 int do_set(const char *key, const void *data_buf, uint32_t data_buf_size, uint32_t flags); 00473 00474 /** 00475 * @brief Build RAM table and update _free_space_offset (scanning all the records in the area). 00476 * 00477 * @returns 0 for success, nonzero for failure. 00478 */ 00479 int build_ram_table(); 00480 00481 /** 00482 * @brief Increment maximum number of keys and reallocate RAM table accordingly. 00483 * 00484 * @param[out] ram_table Updated RAM table. 00485 * 00486 * @returns 0 for success, nonzero for failure. 00487 */ 00488 int increment_max_keys(void **ram_table = 0); 00489 00490 /** 00491 * @brief Calculate offset from start of erase unit. 00492 * 00493 * @param[in] area Area. 00494 * @param[in] offset Offset in area. 00495 * @param[out] offset_from_start Offset from start of erase unit. 00496 * @param[out] dist_to_end Distance to end of erase unit. 00497 * 00498 * @returns offset in erase unit. 00499 */ 00500 void offset_in_erase_unit(uint8_t area, uint32_t offset, uint32_t &offset_from_start, 00501 uint32_t &dist_to_end); 00502 00503 /** 00504 * @brief Before writing a record, check whether you are crossing an erase unit. 00505 * If you do, check if it's erased, and erase it if not. 00506 * 00507 * @param[in] area Area. 00508 * @param[in] offset Offset in area. 00509 * @param[in] size Write size. 00510 * @param[in] force_check Force checking. 00511 * 00512 * @returns 0 for success, nonzero for failure. 00513 */ 00514 int check_erase_before_write(uint8_t area, uint32_t offset, uint32_t size, 00515 bool force_check = false); 00516 00517 /** 00518 * @brief Get data from reserved area - worker function. 00519 * This verifies that reserved data on both areas have 00520 * correct checksums. If given pointer is not NULL, also 00521 * write the reserved data to buffer. If checksums are not 00522 * valid, return error code, and don't write anything to any 00523 * pointers. 00524 * 00525 * @param[out] reserved_data Reserved data buffer (NULL to return nothing). 00526 * @param[in] reserved_data_buf_size 00527 * Reserved data buffer size. 00528 * @param[out] actual_data_size If not NULL, return actual data size. 00529 * @param[out] copy_trailer If not NULL, copy the trailer content to given buffer. 00530 * 00531 * @returns 0 on success or a negative error code on failure 00532 */ 00533 int do_reserved_data_get(void *reserved_data, size_t reserved_data_buf_size, 00534 size_t *actual_data_size = 0, void *copy_trailer = 0); 00535 00536 /** 00537 * @brief Update all iterators after adding or deleting of keys. 00538 * 00539 * @param[in] added True if added, false if deleted. 00540 * @param[in] ram_table_ind RAM table index. 00541 * 00542 * @returns none 00543 */ 00544 void update_all_iterators(bool added, uint32_t ram_table_ind); 00545 00546 #endif 00547 00548 }; 00549 /** @}*/ 00550 00551 } // namespace mbed 00552 00553 #endif
Generated on Tue Jul 12 2022 13:54:55 by
