Mistake on this page?
Report an issue in GitHub or email us

KVStore

Tip: This API replaces the deprecated NVStore API.

KVStore class hierarchy

The KVStore API is a common get/set API implemented by several classes. It allows flexibility in the configuration of a storage solution that you can build by allocating several combinations of objects. For example, SecureStore can hold a TDBStore or a FileSystemStore, both implementing the KVStore API, without any change in functionality.

Developers should use the static global KVStore API when possible, to use the flexibility of KVStore configuration.

It is also possible to instantiate single objects of the classes detailed below and use the KVStore class API directly. The KVStore API presents additional functionality not present in the global API, such as incremental set (set_start, set_add_data and set_finalize) and incremental get (parameter offset in function get). You must use these APIs with caution because two calls to set_start result in the second call to set_start being held pending on a mutex until set_finalize is called.

Classes implementing KVStore API:

  • Tiny Database Storage (TDBStore): A lightweight module that stores data on a flash storage. It is part of the KVStore class family, so it supports the get/set interface. It is designed to optimize performance (speed of access), reduce wearing of the flash and minimize storage overhead. It is also resilient to power failures.

    • Requirements and assumptions: TDBStore assumes that the underlying block device is fully dedicated for it (starting offset 0). If you want to dedicate only a part of the device to TDBStore, then use a sliced block device, typically with SlicingBlockDevice. This feature requires a flash based block device, such as FlashIAPBlockDevice or SpifBlockDevice. It can work on top of block devices that don't need erasing before writes, such as HeapBlockDevice or SDBlockDevice, but requires a flash simulator layer for this purpose, like the one offered by FlashSimBlockDevice.
  • FileSystemStore: A lightweight implementation of the KVStore interface over file systems.

    • Requirements and assumptions: FileSystemStore assumes the underlying file system qualities for resilience and file validation. If the underlying file system has no protection against power failures, then neither does FileSystemStore. When initializing this class, it is assumed that the underlying FileSystem is initialized and mounted.
  • SecureStore: A KVStore-based storage solution that provides security features on the stored data, such as encryption, authentication, rollback protection and write once, over an underlying KVStore class. It references an additional KVStore class for storing the rollback protection keys.

    • Requirements and assumptions: SecureStore assumes that the underlying KVStore instances are instantiated and initialized.

KVStore class reference

Data Structures
struct  info
 Holds key information. More...
Public Types
typedef struct mbed::KVStore::info info_t
 Holds key information. More...
Public Member Functions
virtual int init ()=0
 Initialize KVStore. More...
virtual int deinit ()=0
 Deinitialize KVStore. More...
virtual int reset ()=0
 Reset KVStore contents (clear all keys) More...
virtual int set (const char *key, const void *buffer, size_t size, uint32_t create_flags)=0
 Set one KVStore item, given key and value. More...
virtual int get (const char *key, void *buffer, size_t buffer_size, size_t *actual_size=NULL, size_t offset=0)=0
 Get one KVStore item, given key. More...
virtual int get_info (const char *key, info_t *info=NULL)=0
 Get information of a given key. More...
virtual int remove (const char *key)=0
 Remove a KVStore item, given key. More...
virtual int set_start (set_handle_t *handle, const char *key, size_t final_data_size, uint32_t create_flags)=0
 Start an incremental KVStore set sequence. More...
virtual int set_add_data (set_handle_t handle, const void *value_data, size_t data_size)=0
 Add data to incremental KVStore set sequence. More...
virtual int set_finalize (set_handle_t handle)=0
 Finalize an incremental KVStore set sequence. More...
virtual int iterator_open (iterator_t *it, const char *prefix=NULL)=0
 Start an iteration over KVStore keys. More...
virtual int iterator_next (iterator_t it, char *key, size_t key_size)=0
 Get next key in iteration. More...
virtual int iterator_close (iterator_t it)=0
 Close iteration. More...
bool is_valid_key (const char *key) const
 Convenience function for checking key validity. More...

KVStore example

/* Copyright (c) 2018 Arm Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "mbed.h"
#include <stdio.h>
#include <string.h>
#include "KVStore.h"
#include "kvstore_global_api.h"

using namespace mbed;

#define EXAMPLE_KV_VALUE_LENGTH 64
#define EXAMPLE_KV_KEY_LENGTH 32
#define err_code(res) MBED_GET_ERROR_CODE(res)

void kv_store_global_api_example();

int main()
{
    /* KV Store Static API Example */
    kv_store_global_api_example();
}

void kv_store_global_api_example()
{
    char kv_value_in[EXAMPLE_KV_VALUE_LENGTH] = {"kvstore_dummy_value_hello_world"};
    char kv_key_in[EXAMPLE_KV_KEY_LENGTH] = {"/kv/dummy_key1"};
    char kv_key_out[EXAMPLE_KV_KEY_LENGTH] = {0};
    size_t actual_size = 0;

    /* key information container */
    kv_info_t info;

    /* kv store iterator */
    kv_iterator_t kvstore_it;

    int i_ind = 0;

    printf("--- Mbed OS KVStore static API example ---\n");

    int res = MBED_ERROR_NOT_READY;

    /* Start By Resetting the KV Storage */
    printf("kv_reset\n");
    res = kv_reset("/kv/");
    printf("kv_reset -> %d\n", err_code(res));

    /* Set First 'Dummy' Key/Value pair with unprotected clear value data */
    printf("kv_set first dummy key\n");
    res = kv_set(kv_key_in, kv_value_in, strlen(kv_value_in), 0);
    printf("kv_set -> %d\n", err_code(res));

    /* Read the KV Pair you've just set */
    /* Start by getting key's information */
    printf("kv_get_info of first key\n");
    res = kv_get_info(kv_key_in, &info);
    printf("kv_get_info -> %d\n", err_code(res));
    printf("kv_get_info key: %s\n", kv_key_in);
    printf("kv_get_info info - size: %u, flags: %lu\n", info.size, info.flags);

    /* Now that you know the data value size of this key,
     * allocate a buffer with matching size and get the value data */
    printf("kv_get first key\n");
    char *kv_first_value_out = new char[info.size + 1];
    memset(kv_first_value_out, 0, info.size + 1);
    res = kv_get(kv_key_in, kv_first_value_out, info.size, &actual_size);
    printf("kv_get -> %d\n", err_code(res));
    printf("kv_get key: %s\n", kv_key_in);
    printf("kv_get value: %s\n", kv_first_value_out);
    delete[] kv_first_value_out;

    /* Lets set some more 'Dummy' and 'Real' KV pairs */
    /* Set 'Dummy' Key2 */
    printf("kv_set second dummy key \n");
    res = kv_set("/kv/dummy_key2", "dummy_value2", strlen("dummy_value2"), 0);
    printf("kv_set -> %d\n", err_code(res));

    /* Set an authenticated-encrypted 'Dummy' key with Replay protection */
    printf("kv_set third key with Confidentiality and Replay Protection flags\n");
    res = kv_set("/kv/dummy_auth_enc_key", "auth_enc_value", strlen("auth_enc_value"),
                 KV_REQUIRE_CONFIDENTIALITY_FLAG | KV_REQUIRE_REPLAY_PROTECTION_FLAG);
    printf("kv_set -> %d\n", err_code(res));

    /* Set 2 non-dummy 'Real' KV pairs */
    /* Set 'Real' Key 1 */
    printf("kv_set Set 'Real' Key 1\n");
    res = kv_set("/kv/real_key1", "real_value1", strlen("real_value1"), 0);
    printf("kv_set -> %d\n", err_code(res));
    /* Set 'Real' Write-Once Key2 for a key that you do not want to be removed */
    printf("kv_set Set 'Real' Key 2 with flag write-once\n");
    res = kv_set("/kv/real_wo_key", "real_wo_value", strlen("real_wo_value"), KV_WRITE_ONCE_FLAG);
    printf("kv_set -> %d\n", err_code(res));

    /* Now lets remove all of the 'Dummy' Keys and remain with the 'Real' ones */
    printf("Removing 'Dummy' Keys\n");
    /* Iterate and remove Keys that start with prefix 'dummy' */
    res = kv_iterator_open(&kvstore_it, "dummy");
    memset(kv_key_out, 0, EXAMPLE_KV_KEY_LENGTH);
    while (kv_iterator_next(kvstore_it, kv_key_out, EXAMPLE_KV_KEY_LENGTH) != MBED_ERROR_ITEM_NOT_FOUND) {
        i_ind++;
        printf("%d) Removing %s\n", i_ind, kv_key_out);
        kv_remove(kv_key_out);
        memset(kv_key_out, 0, EXAMPLE_KV_KEY_LENGTH);
    }
    res = kv_iterator_close(kvstore_it);
    printf("Remaining with 'Real' Keys:\n");
    /* Iterate on all remaining Keys */
    res = kv_iterator_open(&kvstore_it, NULL);
    memset(kv_key_out, 0, EXAMPLE_KV_KEY_LENGTH);
    i_ind = 0;
    while (kv_iterator_next(kvstore_it, kv_key_out, EXAMPLE_KV_KEY_LENGTH) != MBED_ERROR_ITEM_NOT_FOUND) {
        i_ind++;
        printf("%d) %s\n", i_ind, kv_key_out);
        memset(kv_key_out, 0, EXAMPLE_KV_KEY_LENGTH);
    }
    res = kv_iterator_close(kvstore_it);

    /* Try to remove write-once Key - should fail */
    printf("kv_remove write-once file - should fail!\n");
    res = kv_remove("/kv/real_wo_key");
    printf("kv_remove -> %d\n", err_code(res));

    /* Finally, reset will format kvstore and remove All Keys (including write-once keys) */
    printf("kv_reset format kvstore (including write-once)\n");
    res = kv_reset("/kv/");
    printf("kv_reset -> %d\n", err_code(res));

    return;
}

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.