mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6388 from davidsaada/david_nvstore_set_alloc_key
NVStore: key management enhancementspull/6442/head
commit
6dc0c9d6c3
|
@ -22,6 +22,7 @@ Each item is kept in an entry containing a header and data, where the header hol
|
|||
- get: Get the value of an item, given key.
|
||||
- set: Set the value of an item, given key and value.
|
||||
- set_once: Like set, but allows only a one time setting of this item (and disables deleting of this item).
|
||||
- set_alloc_key: Like set, but allocates a free key (from the non predefined keys).
|
||||
- remove: Remove an item, given key.
|
||||
- get_item_size: Get the item value size (in bytes).
|
||||
- set_max_keys: Set maximal value of unique keys. Overriding the default of NVSTORE_MAX_KEYS. This affects RAM consumption,
|
||||
|
|
|
@ -70,6 +70,7 @@ static void nvstore_basic_functionality_test()
|
|||
|
||||
uint16_t actual_len_bytes = 0;
|
||||
NVStore &nvstore = NVStore::get_instance();
|
||||
uint16_t key;
|
||||
|
||||
uint8_t *nvstore_testing_buf_set = new uint8_t[basic_func_max_data_size];
|
||||
uint8_t *nvstore_testing_buf_get = new uint8_t[basic_func_max_data_size];
|
||||
|
@ -127,6 +128,10 @@ static void nvstore_basic_functionality_test()
|
|||
result = nvstore.set(19, 10, &(nvstore_testing_buf_set[3]));
|
||||
TEST_ASSERT_EQUAL(NVSTORE_ALREADY_EXISTS, result);
|
||||
|
||||
result = nvstore.set_alloc_key(key, 17, &(nvstore_testing_buf_set[3]));
|
||||
TEST_ASSERT_EQUAL(NVSTORE_NUM_PREDEFINED_KEYS, key);
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
|
||||
// Make sure set items are also gotten OK after reset
|
||||
result = nvstore.deinit();
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
|
@ -153,6 +158,11 @@ static void nvstore_basic_functionality_test()
|
|||
TEST_ASSERT_EQUAL(64, actual_len_bytes);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(nvstore_testing_buf_set, nvstore_testing_buf_get, 64);
|
||||
|
||||
result = nvstore.get(NVSTORE_NUM_PREDEFINED_KEYS, 64, nvstore_testing_buf_get, actual_len_bytes);
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
TEST_ASSERT_EQUAL(17, actual_len_bytes);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(&nvstore_testing_buf_set[3], nvstore_testing_buf_get, 17);
|
||||
|
||||
result = nvstore.get(10, 65, nvstore_testing_buf_get, actual_len_bytes);
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
TEST_ASSERT_EQUAL(64, actual_len_bytes);
|
||||
|
|
|
@ -134,6 +134,7 @@ NVStore::NVStore() : _init_done(0), _init_attempts(0), _active_area(0), _max_key
|
|||
_active_area_version(0), _free_space_offset(0), _size(0), _mutex(0), _offset_by_key(0), _flash(0),
|
||||
_min_prog_size(0), _page_buf(0)
|
||||
{
|
||||
memcpy(_flash_area_params, 0, sizeof(_flash_area_params));
|
||||
}
|
||||
|
||||
NVStore::~NVStore()
|
||||
|
@ -589,6 +590,10 @@ int NVStore::do_get(uint16_t key, uint16_t buf_size, void *buf, uint16_t &actual
|
|||
|
||||
if (!buf) {
|
||||
buf_size = 0;
|
||||
// This is only required in order to satisfy static code analysis tools, fearing
|
||||
// that a null buff is dereferenced inside read_record function. However, this won't happen
|
||||
// when buf_size is 0, so just have buf point to a dummy location.
|
||||
buf = &flags;
|
||||
}
|
||||
|
||||
_mutex->lock();
|
||||
|
@ -623,7 +628,7 @@ int NVStore::get_item_size(uint16_t key, uint16_t &actual_size)
|
|||
return do_get(key, 0, NULL, actual_size, 1);
|
||||
}
|
||||
|
||||
int NVStore::do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t flags)
|
||||
int NVStore::do_set(uint16_t &key, uint16_t buf_size, const void *buf, uint16_t flags)
|
||||
{
|
||||
int ret = NVSTORE_SUCCESS;
|
||||
uint32_t record_offset, record_size, new_free_space;
|
||||
|
@ -636,7 +641,11 @@ int NVStore::do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t f
|
|||
}
|
||||
}
|
||||
|
||||
if (key >= _max_keys) {
|
||||
if ((key != no_key) && (key >= _max_keys)) {
|
||||
return NVSTORE_BAD_VALUE;
|
||||
}
|
||||
|
||||
if ((key == no_key) && (flags & delete_item_flag)) {
|
||||
return NVSTORE_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
@ -648,7 +657,7 @@ int NVStore::do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t f
|
|||
return NVSTORE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (_offset_by_key[key] & offs_by_key_set_once_mask) {
|
||||
if ((key != no_key) && (_offset_by_key[key] & offs_by_key_set_once_mask)) {
|
||||
return NVSTORE_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
|
@ -656,6 +665,17 @@ int NVStore::do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t f
|
|||
|
||||
_mutex->lock();
|
||||
|
||||
if (key == no_key) {
|
||||
for (key = NVSTORE_NUM_PREDEFINED_KEYS; key < _max_keys; key++) {
|
||||
if (!_offset_by_key[key]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key == _max_keys) {
|
||||
return NVSTORE_NO_FREE_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
new_free_space = core_util_atomic_incr_u32(&_free_space_offset, record_size);
|
||||
record_offset = new_free_space - record_size;
|
||||
|
||||
|
@ -696,6 +716,12 @@ int NVStore::set_once(uint16_t key, uint16_t buf_size, const void *buf)
|
|||
return do_set(key, buf_size, buf, set_once_flag);
|
||||
}
|
||||
|
||||
int NVStore::set_alloc_key(uint16_t &key, uint16_t buf_size, const void *buf)
|
||||
{
|
||||
key = no_key;
|
||||
return do_set(key, buf_size, buf, 0);
|
||||
}
|
||||
|
||||
int NVStore::remove(uint16_t key)
|
||||
{
|
||||
return do_set(key, 0, NULL, delete_item_flag);
|
||||
|
|
|
@ -41,10 +41,20 @@ typedef enum {
|
|||
NVSTORE_FLASH_AREA_TOO_SMALL = -7,
|
||||
NVSTORE_OS_ERROR = -8,
|
||||
NVSTORE_ALREADY_EXISTS = -9,
|
||||
NVSTORE_NO_FREE_KEY = -10,
|
||||
} nvstore_status_e;
|
||||
|
||||
typedef enum {
|
||||
NVSTORE_FIRST_PREDEFINED_KEY = 0,
|
||||
|
||||
// All predefined keys used for internal features should be defined here
|
||||
|
||||
NVSTORE_LAST_PREDEFINED_KEY = 15,
|
||||
NVSTORE_NUM_PREDEFINED_KEYS
|
||||
} nvstore_predefined_keys_e;
|
||||
|
||||
#ifndef NVSTORE_MAX_KEYS
|
||||
#define NVSTORE_MAX_KEYS 16
|
||||
#define NVSTORE_MAX_KEYS ((uint16_t)NVSTORE_NUM_PREDEFINED_KEYS)
|
||||
#endif
|
||||
|
||||
// defines 2 areas - active and nonactive, not configurable
|
||||
|
@ -148,6 +158,24 @@ public:
|
|||
*/
|
||||
int set(uint16_t key, uint16_t buf_size, const void *buf);
|
||||
|
||||
/**
|
||||
* @brief Programs one item of data on Flash, allocating a key.
|
||||
*
|
||||
* @param[out] key Returned key of stored item.
|
||||
* @param[in] buf_size Item size in bytes.
|
||||
* @param[in] buf Buffer containing data.
|
||||
*
|
||||
* @returns NVSTORE_SUCCESS Value was successfully written on Flash.
|
||||
* NVSTORE_WRITE_ERROR Physical error writing data.
|
||||
* NVSTORE_BAD_VALUE Bad value in any of the parameters.
|
||||
* NVSTORE_FLASH_AREA_TOO_SMALL
|
||||
* Not enough space in Flash area.
|
||||
* NVSTORE_ALREADY_EXISTS Item set with write once API already exists.
|
||||
* NVSTORE_NO_FREE_KEY Couldn't allocate a key for this call.
|
||||
*
|
||||
*/
|
||||
int set_alloc_key(uint16_t &key, uint16_t buf_size, const void *buf);
|
||||
|
||||
/**
|
||||
* @brief Programs one item of data on Flash, given key, allowing no consequent sets to this key.
|
||||
*
|
||||
|
@ -394,14 +422,14 @@ private:
|
|||
/**
|
||||
* @brief Actual logics of set API (covers also set_once and remove APIs).
|
||||
*
|
||||
* @param[in] key key.
|
||||
* @param[out] key key (both input and output).
|
||||
* @param[in] buf_size Buffer size (bytes).
|
||||
* @param[in] buf Input Buffer.
|
||||
* @param[in] flags Record flags.
|
||||
*
|
||||
* @returns 0 for success, nonzero for failure.
|
||||
*/
|
||||
int do_set(uint16_t key, uint16_t buf_size, const void *buf, uint16_t flags);
|
||||
int do_set(uint16_t &key, uint16_t buf_size, const void *buf, uint16_t flags);
|
||||
|
||||
};
|
||||
/** @}*/
|
||||
|
|
Loading…
Reference in New Issue