This library provides a convenient way to store information as key-value pairs in non-volatile storage.
Getting Started
This section provides steps for getting started with this library by using the block storage interface.block-storage
- Include the kv-store library header in the application.
- Initialize the underlying storage. This could be done using either the HAL NVM or Serial Memory depending on the storage
- Example initialization for hal API 3.0 nvm driver
mtb_hal_nvm_t nvm_obj;
mtb_hal_nvm_region_info_t block_info;
cy_rslt_t result = mtb_hal_nvm_setup(&nvm_obj, NULL);
CY_ASSERT(result == CY_RSLT_SUCCESS);
mtb_hal_nvm_info_t nvm_info;
mtb_hal_nvm_get_info(&nvm_obj, &nvm_info);
block_info = nvm_info.regions[nvm_info.region_count - 1];
- Example initialization for serial memory driver
mtb_serial_memory_t serial_memory_obj;
cy_stc_smif_context_t context;
cy_rslt_t result = mtb_serial_memory_setup(
&serial_memory_obj, MTB_SERIAL_MEMORY_CHIP_SELECT_0,
&base_address, &sm_clock, &context, &smif_block_obj);
- Example initialization for hal API 2.0 nvm driver
cyhal_nvm_t nvm_obj;
cyhal_nvm_region_info_t block_info;
cy_rslt_t result = cyhal_nvm_init(&nvm_obj);
CY_ASSERT(result == CY_RSLT_SUCCESS);
cyhal_nvm_info_t nvm_info;
cyhal_nvm_get_info(&nvm_obj, &nvm_info);
block_info = nvm_info.regions[nvm_info.region_count - 1];
- Create the block storage interface using the HAL NVM or the serial memory.If neither the HAL NVM nor serial memory driver is being used to communicate with the storage device, the application must provide a custom implementation of the block device interface.
- Example implementation using block storage HAL 3.0 NVM interface
mtb_block_storage_t nvm_bsd;
mtb_block_storage_create_hal_nvm(&nvm_bsd, &nvm_obj);
- Example implementation using block storage serial-memory interface
mtb_block_storage_t serial_memory_bsd;
mtb_block_storage_create_serial_memory(&serial_memory_bsd, &serial_memory_obj);
CY_ASSERT(result == CY_RSLT_SUCCESS);
- Example implementation using block storage HAL Classic NVM interface
mtb_block_storage_t nvm_bsd;
mtb_block_storage_nvm_create(&nvm_bsd);
- Initialize the kv-store library.
- Set the start address and length.
- If using the hal-nvm driver, for this example the address space provided starts 16 pages from the end of the nvm. Note that if the device does not have a working flash (i.e. using main flash) care must be taken to ensure that the space allocated below is not used by anything else (for eg. Application image).
uint32_t length = 16U * block_info.block_size;
uint32_t start_addr = block_info.start_address + block_info.size - length;
- If using the serial-memory library, for this example we define the space provided to the kv-store library to be the size of 2 sectors.
uint32_t start_addr = 0;
uint32_t sector_size = serial_memory_bsd.get_erase_size(serial_memory_bsd.context, start_addr);
uint32_t length = sector_size * 2;
- Call mtb_kvstore_init by passing the start address, length, block device and the optional memory allocate and free function pointers
mtb_kvstore_t obj;
CY_ASSERT(result == CY_RSLT_SUCCESS);
cy_rslt_t mtb_kvstore_init(mtb_kvstore_t *obj, uint32_t start_addr, uint32_t length, const mtb_block_storage_t *bsd, mtb_kvstore_allocate_memory_t alloc_memory, mtb_kvstore_free_memory_t free_memory)
Initialize an instance of the kv-store library.
Definition: mtb_kvstore.c:1568
- The library should now be ready to perform operations.
- Write operation.
uint8_t data[10];
CY_ASSERT(result == CY_RSLT_SUCCESS);
cy_rslt_t mtb_kvstore_write(mtb_kvstore_t *obj, const char *key, const uint8_t *data, uint32_t size)
Store a key value pair.
Definition: mtb_kvstore.c:1659
- Read operation.
uint8_t read_data[10];
uint32_t data_size = sizeof(read_data);
CY_ASSERT(result == CY_RSLT_SUCCESS);
cy_rslt_t mtb_kvstore_read(mtb_kvstore_t *obj, const char *key, uint8_t *data, uint32_t *size)
Read data associated with a key.
Definition: mtb_kvstore.c:1741
- Delete operation.
CY_ASSERT(result == CY_RSLT_SUCCESS);
cy_rslt_t mtb_kvstore_delete(mtb_kvstore_t *obj, const char *key)
Delete a key value pair.
Definition: mtb_kvstore.c:1866
|
#define | MTB_KVSTORE_MAX_KEY_SIZE (64U) |
| Maximum key size permitted.
|
|
#define | MTB_KVSTORE_ENSURE_MAX (0xFFFFFFFFu) |
| When passed as an argument to mtb_kvstore_ensure_capacity, indicates that cleanup tasks should always be performed regardless of the amount of space which is currently free, to ensure the maximum possible amount of free space is available.
|
|
#define | MTB_KVSTORE_BAD_PARAM_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 0) |
| An invalid parameter value is passed in.
|
|
#define | MTB_KVSTORE_ALIGNMENT_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 1) |
| The storage area passed in is not aligned to erase sector boundary. More...
|
|
#define | MTB_KVSTORE_MEM_ALLOC_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 2) |
| Memory allocation failed. More...
|
|
#define | MTB_KVSTORE_INVALID_DATA_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 3) |
| Invalid data was detected. More...
|
|
#define | MTB_KVSTORE_ERASED_DATA_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 4) |
| Erased data was detected. More...
|
|
#define | MTB_KVSTORE_ITEM_NOT_FOUND_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 5) |
| Item was not found in the storage.
|
|
#define | MTB_KVSTORE_STORAGE_FULL_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 6) |
| The storage is full.
|
|
#define | MTB_KVSTORE_BUFFER_TOO_SMALL CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 7) |
| Buffer provided is too small for value found.
|
|
|
typedef cy_rslt_t(* | mtb_kvstore_bd_read) (void *context, uint32_t addr, uint32_t length, uint8_t *buf) |
| Function prototype for reading data from the block device. More...
|
|
typedef cy_rslt_t(* | mtb_kvstore_bd_program) (void *context, uint32_t addr, uint32_t length, const uint8_t *buf) |
| Function prototype for writing data to the block device. More...
|
|
typedef cy_rslt_t(* | mtb_kvstore_bd_erase) (void *context, uint32_t addr, uint32_t length) |
| Function prototype for read from the block device. More...
|
|
typedef uint32_t(* | mtb_kvstore_bd_read_size) (void *context, uint32_t addr) |
| Function prototype to get the read size of the block device for a specific address. More...
|
|
typedef uint32_t(* | mtb_kvstore_bd_program_size) (void *context, uint32_t addr) |
| Function prototype to get the program size of the block device for a specific address. More...
|
|
typedef uint32_t(* | mtb_kvstore_bd_erase_size) (void *context, uint32_t addr) |
| Function prototype to get the erase size of the block device for a specific address. More...
|
|
typedef void *(* | mtb_kvstore_allocate_memory_t) (size_t size) |
| Function prototype for allocating memory to be used for kv-store internal operations. More...
|
|
typedef void(* | mtb_kvstore_free_memory_t) (void *ptr) |
| Function prototype for freeing memory. More...
|
|
|
cy_rslt_t | mtb_kvstore_init (mtb_kvstore_t *obj, uint32_t start_addr, uint32_t length, const mtb_block_storage_t *bsd, mtb_kvstore_allocate_memory_t alloc_memory, mtb_kvstore_free_memory_t free_memory) |
| Initialize an instance of the kv-store library. More...
|
|
cy_rslt_t | mtb_kvstore_write (mtb_kvstore_t *obj, const char *key, const uint8_t *data, uint32_t size) |
| Store a key value pair. More...
|
|
cy_rslt_t | mtb_kvstore_read (mtb_kvstore_t *obj, const char *key, uint8_t *data, uint32_t *size) |
| Read data associated with a key. More...
|
|
cy_rslt_t | mtb_kvstore_read_partial (mtb_kvstore_t *obj, const char *key, uint8_t *data, uint32_t *size, const uint32_t offset_bytes) |
| Read data associated with a key. More...
|
|
cy_rslt_t | mtb_kvstore_key_exists (mtb_kvstore_t *obj, const char *key) |
| Check if a key is stored in memory. More...
|
|
cy_rslt_t | mtb_kvstore_value_size (mtb_kvstore_t *obj, const char *key, uint32_t *size) |
| Get the size in bytes of data in memory corresponding to a given key. More...
|
|
cy_rslt_t | mtb_kvstore_delete (mtb_kvstore_t *obj, const char *key) |
| Delete a key value pair. More...
|
|
uint32_t | mtb_kvstore_size (mtb_kvstore_t *obj) |
| Query the size consumed in the kv-store storage. More...
|
|
uint32_t | mtb_kvstore_remaining_size (mtb_kvstore_t *obj) |
| Query the free space available in the kv-store storage. More...
|
|
cy_rslt_t | mtb_kvstore_ensure_capacity (mtb_kvstore_t *obj, uint32_t size) |
| Tries to make the specified amount of space available for immediate use. More...
|
|
cy_rslt_t | mtb_kvstore_reset (mtb_kvstore_t *obj) |
| Reset kv-store storage. More...
|
|
void | mtb_kvstore_deinit (mtb_kvstore_t *obj) |
| Delete kv-store instance. More...
|
|
◆ MTB_KVSTORE_ALIGNMENT_ERROR
#define MTB_KVSTORE_ALIGNMENT_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 1) |
The storage area passed in is not aligned to erase sector boundary.
See notes in mtb_kvstore_init for more information on constraints.
◆ MTB_KVSTORE_MEM_ALLOC_ERROR
#define MTB_KVSTORE_MEM_ALLOC_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 2) |
Memory allocation failed.
There is not enough space available on the heap.
◆ MTB_KVSTORE_INVALID_DATA_ERROR
#define MTB_KVSTORE_INVALID_DATA_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 3) |
Invalid data was detected.
The record may be corrupted.
◆ MTB_KVSTORE_ERASED_DATA_ERROR
#define MTB_KVSTORE_ERASED_DATA_ERROR CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MIDDLEWARE_KVSTORE, 4) |
Erased data was detected.
The record may be corrupted
◆ mtb_kvstore_bd_read
typedef cy_rslt_t(* mtb_kvstore_bd_read) (void *context, uint32_t addr, uint32_t length, uint8_t *buf) |
Function prototype for reading data from the block device.
- Parameters
-
[in] | context | Context object that is passed into mtb_kvstore_init |
[in] | addr | Address to read the data from the block device. This address is passed in as start_addr + offset. |
[in] | length | Length of the data that needs to be read. |
[out] | buf | Buffer to read the data. |
- Returns
- Result of the read operation.
◆ mtb_kvstore_bd_program
typedef cy_rslt_t(* mtb_kvstore_bd_program) (void *context, uint32_t addr, uint32_t length, const uint8_t *buf) |
Function prototype for writing data to the block device.
- Parameters
-
[in] | context | Context object that is passed into mtb_kvstore_init |
[in] | addr | Address to program the data into the block device. This address is passed in as start_addr + offset. |
[in] | length | Length of the data that needs to be written |
[out] | buf | Data that needs to be written |
- Returns
- Result of the program operation.
◆ mtb_kvstore_bd_erase
typedef cy_rslt_t(* mtb_kvstore_bd_erase) (void *context, uint32_t addr, uint32_t length) |
Function prototype for read from the block device.
- Parameters
-
[in] | context | Context object that is passed into mtb_kvstore_init |
[in] | addr | Address to read the data from the device. This address is passed in as start_addr + offset. |
[in] | length | Length of the data that needs to be erased. |
- Returns
- Result of the erase operation.
◆ mtb_kvstore_bd_read_size
typedef uint32_t(* mtb_kvstore_bd_read_size) (void *context, uint32_t addr) |
Function prototype to get the read size of the block device for a specific address.
- Parameters
-
[in] | context | Context object that is passed into mtb_kvstore_init |
[in] | addr | Address for which the read size is queried. This address is passed in as start_addr + offset. |
- Returns
- Read size of the memory device.
◆ mtb_kvstore_bd_program_size
typedef uint32_t(* mtb_kvstore_bd_program_size) (void *context, uint32_t addr) |
Function prototype to get the program size of the block device for a specific address.
- Parameters
-
[in] | context | Context object that is passed into mtb_kvstore_init |
[in] | addr | Address for which the program size is queried. This address is passed in as start_addr + offset. |
- Returns
- Program size of the memory device.
◆ mtb_kvstore_bd_erase_size
typedef uint32_t(* mtb_kvstore_bd_erase_size) (void *context, uint32_t addr) |
Function prototype to get the erase size of the block device for a specific address.
- Parameters
-
[in] | context | Context object that is passed into mtb_kvstore_init |
[in] | addr | Address for which the erase size is queried. This address is passed in a start_addr + offset. |
- Returns
- Erase size of the memory device.
◆ mtb_kvstore_allocate_memory_t
typedef void *(* mtb_kvstore_allocate_memory_t) (size_t size) |
Function prototype for allocating memory to be used for kv-store internal operations.
- Parameters
-
[in] | size | Size in bytes of the memory to be allocated |
- Returns
- Pointer to the allocated memory in case the memory allocation is success or NULL in case of failure.
◆ mtb_kvstore_free_memory_t
typedef void(* mtb_kvstore_free_memory_t) (void *ptr) |
Function prototype for freeing memory.
- Parameters
-
[in] | ptr | Pointer to the memory block to be freed |
- Returns
- None.
◆ mtb_kvstore_init()
Initialize an instance of the kv-store library.
- Parameters
-
[out] | obj | Pointer to a kv-store object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | start_addr | Start address for the memory. All addresses when performing memory operations will be offset from this address. See notes for constraints. |
[in] | length | Total space available in bytes. See notes for constraints. |
[in] | bsd | Block storage device interface for the underlying memory to be used. |
[in] | alloc_memory | Optional parameter that could be used to allocate the requested memory size. Application could set up this function pointer if they desire to allocate the memory from specific memory region. If not null, KV Store uses the specified function for allocating the memory needed for internal operations. When specified as NULL, KV Store uses the malloc function to allocate the memory |
[in] | free_memory | Optional parameter that could be used to free the memory block allocated using the 'alloc_memory' function.If not null, KV Store uses the specified function for freeing the memory. When specified as NULL, KV Store uses the free function to free the memory |
Address space considerations
- Note
- The start_addr and start_addr + length must be aligned to the erase sector boundary.
-
An even number of erase sectors must be provided as storage. (2 * N * erase sector size) where N is the number of sectors.
-
The implementation assumes that the value of the storage in the erased state is either 0x00 or 0xFF.
-
The space provided to the library provided must have the uniform characteristics (erase, program and read size). A space spanning regions with different characteristics in a hybrid sector device is not supported and if provided may lead to undefined behavior.
-
If the application desires to use specific memory region for KV Store internal operation, it should set up both the alloc_memory and free_memory functions.
RTOS considerations
- Note
- In a RTOS environment the library must be initialized after the RTOS kernel has started.
- Returns
- Result of the initialization operation.
◆ mtb_kvstore_write()
cy_rslt_t mtb_kvstore_write |
( |
mtb_kvstore_t * |
obj, |
|
|
const char * |
key, |
|
|
const uint8_t * |
data, |
|
|
uint32_t |
size |
|
) |
| |
Store a key value pair.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
[in] | key | Lookup key for the data. |
[in] | data | Pointer to the start of the data to be stored. |
[in] | size | Total size of the data in bytes. |
- Returns
- Result of the write operation.
◆ mtb_kvstore_read()
cy_rslt_t mtb_kvstore_read |
( |
mtb_kvstore_t * |
obj, |
|
|
const char * |
key, |
|
|
uint8_t * |
data, |
|
|
uint32_t * |
size |
|
) |
| |
Read data associated with a key.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
[in] | key | Lookup key for the data. |
[out] | data | Pointer to the start of the buffer for the data to be read into. |
[in,out] | size | [in] Total size of the data in bytes. [out] Actual size of the data in storage. If a data buffer is provided then the size cannot be NULL or 0. |
- Note
- It is valid to set both
data
and size
to NULL to check if the key exists in the storage.
- Returns
- Result of the read operation.
◆ mtb_kvstore_read_partial()
cy_rslt_t mtb_kvstore_read_partial |
( |
mtb_kvstore_t * |
obj, |
|
|
const char * |
key, |
|
|
uint8_t * |
data, |
|
|
uint32_t * |
size, |
|
|
const uint32_t |
offset_bytes |
|
) |
| |
Read data associated with a key.
If buffer is too small, will partially read and fill buffer. No corruption checking is performed.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
[in] | key | Lookup key for the data. |
[out] | data | Pointer to the start of the buffer for the data to be read into. |
[in,out] | size | [in] Total size of the data in bytes. [out] Number of bytes read into buffer. If a data buffer is provided then the size cannot be NULL or 0. |
[in] | offset_bytes | Number of bytes to skip at the start the value read into data |
- Returns
- Result of the read operation.
◆ mtb_kvstore_key_exists()
cy_rslt_t mtb_kvstore_key_exists |
( |
mtb_kvstore_t * |
obj, |
|
|
const char * |
key |
|
) |
| |
Check if a key is stored in memory.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
[in] | key | Lookup key |
- Returns
- Result of the key_exists operation
◆ mtb_kvstore_value_size()
cy_rslt_t mtb_kvstore_value_size |
( |
mtb_kvstore_t * |
obj, |
|
|
const char * |
key, |
|
|
uint32_t * |
size |
|
) |
| |
Get the size in bytes of data in memory corresponding to a given key.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
[in] | key | Lookup key for the data |
[out] | size | Size of data in bytes |
- Returns
- Result of the value size operation
◆ mtb_kvstore_delete()
cy_rslt_t mtb_kvstore_delete |
( |
mtb_kvstore_t * |
obj, |
|
|
const char * |
key |
|
) |
| |
Delete a key value pair.
- Note
- This function will return CY_RSLT_SUCCESS if the key cannot be found in the storage.
- Parameters
-
[in] | obj | Pointer to a kv-store object. |
[in] | key | Lookup key to delete key value pair. |
- Returns
- Result of the delete operation.
◆ mtb_kvstore_size()
uint32_t mtb_kvstore_size |
( |
mtb_kvstore_t * |
obj | ) |
|
Query the size consumed in the kv-store storage.
- Parameters
-
[in] | obj | Pointer to a kv-store object. |
- Returns
- Size of storage consumed in bytes.
◆ mtb_kvstore_remaining_size()
uint32_t mtb_kvstore_remaining_size |
( |
mtb_kvstore_t * |
obj | ) |
|
Query the free space available in the kv-store storage.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
- Returns
- Size of storage free in bytes.
◆ mtb_kvstore_ensure_capacity()
cy_rslt_t mtb_kvstore_ensure_capacity |
( |
mtb_kvstore_t * |
obj, |
|
|
uint32_t |
size |
|
) |
| |
Tries to make the specified amount of space available for immediate use.
If necessary, internal cleanup operations will be executed to make additional space available, so this is a potentially long-running operation.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
[in] | size | Amount of space to ensure is available, in bytes. To always perform cleanup operations regardless of the amount of space currently free, use MTB_KVSTORE_ENSURE_MAX. |
- Returns
- Result of the operation. If
size
is not MTB_KVSTORE_ENSURE_MAX and it is not possible to make the requested amount of space available, returns MTB_KVSTORE_STORAGE_FULL_ERROR.
◆ mtb_kvstore_reset()
cy_rslt_t mtb_kvstore_reset |
( |
mtb_kvstore_t * |
obj | ) |
|
Reset kv-store storage.
This function erases all the data in the storage.
- Parameters
-
[in] | obj | Pointer to a kv-store object |
- Returns
- Result of the reset operation
◆ mtb_kvstore_deinit()
void mtb_kvstore_deinit |
( |
mtb_kvstore_t * |
obj | ) |
|
Delete kv-store instance.
This function frees any program memory allocated by the library.
- Parameters
-
[in] | obj | Pointer to a kv-store object |