|
Astarte device API for Zephyr 0.9.0
Astarte device SDK for Zephyr RTOS
|
This library provides a namespaced, persistent key-value storage solution specifically designed for Zephyr RTOS. It leverages the Zephyr Memory Storage (ZMS) subsystem as its underlying non-volatile backend.
The library abstracts standard key-value pairs by mapping them to discrete 32-bit ZMS IDs. The ID space is segmented to reserve specific addresses for metadata, system states, and actual user data.
| ZMS reserved IDs | Value | Purpose |
|---|---|---|
ASTARTE_KEY_VALUE_ENTRY_MIN_USABLE_ID | UINT16_MAX + 1 | The minimum allowable ID for standard key-value payloads. |
ASTARTE_KEY_VALUE_ENTRY_MAX_USABLE_ID | UINT32_MAX - 4 | The maximum allowable ID for standard key-value payloads. |
ASTARTE_KEY_VALUE_ENTRY_INTENT_ID | UINT32_MAX - 3 | Stores the Write-Ahead Log (WAL) intent block. |
ASTARTE_KEY_VALUE_ENTRY_HEAD_AND_TAIL_ID | UINT32_MAX - 2 | Stores the global linked list's head and tail pointers. |
ASTARTE_KEY_VALUE_ENTRY_VERSION_ID | UINT32_MAX - 1 | Stores the formatting version to detect breaking changes during initialization. |
ASTARTE_KEY_VALUE_ENTRY_NULL_ID | UINT32_MAX | Represents a null/invalid pointer in the linked list. |
To locate or allocate ZMS IDs for a given namespace and key, the library utilizes a custom hashing implementation.
sys_hash32 function.0x9e3779b9U).When a key-value pair is committed to ZMS, it is serialized into a single contiguous block. The entry is divided into a fixed-size header and a dynamically sized data section.
| Field name | Size | Description |
|---|---|---|
namespace_len | 2 | Length of the namespace string. |
key_len | 2 | Length of the key string. |
next_id | 4 | ZMS ID of the next entry in the linked list. |
prev_id | 4 | ZMS ID of the previous entry in the linked list. |
| Namespace string | Variable | The literal namespace characters, excluding a null terminator. |
| Key string | Variable | The literal key characters, excluding a null terminator. |
| Value data | Variable | The binary payload for the key-value pair. |
Because ZMS does not natively provide a way to iterate through keys sorted by a namespace, the library maintains a global doubly-linked list of all stored entries.
ASTARTE_KEY_VALUE_ENTRY_HEAD_AND_TAIL_ID record.next_id and points the new node back via prev_id.A critical architectural feature of this library is its resilience to sudden power losses during multi-step ZMS operations. This is achieved using an Intent Block, acting as a Write-Ahead Log (WAL).
Before the library makes physical mutations to the linked list or hash map, it registers its intention at ASTARTE_KEY_VALUE_ENTRY_INTENT_ID. The intent states include:
ASTARTE_KEY_VALUE_ENTRY_INTENT_NONE: The system is stable; no pending operations.ASTARTE_KEY_VALUE_ENTRY_INTENT_INSERTING: Tracks dangling pointers during a 3-step node insertion.ASTARTE_KEY_VALUE_ENTRY_INTENT_UPDATING: Tracks a localized payload swap.ASTARTE_KEY_VALUE_ENTRY_INTENT_DELETING: Tracks unlinking a node from the global list.ASTARTE_KEY_VALUE_ENTRY_INTENT_SHIFTING: Tracks the hash map repair process following a deletion.When astarte_key_value_open mounts the ZMS partition, it immediately triggers astarte_key_value_entry_intent_resolve.
next_id of the previous tail node.prev_id and next_id neighbors before physically deleting the target payload.To ensure the linear probing sequence remains unbroken after an entry is removed, the library executes a "shift back" routine.