A persistent configuration management library for embedded Rust applications.
cfg-noodle
provides a type-safe, async-friendly way to manage configuration data in embedded systems with persistent flash storage. It uses an intrusive linked list architecture to efficiently manage multiple configuration items while minimizing memory overhead.
- Persistent Storage: Read and write configuration to flash memory with wear leveling
- Async/Await: Async API to handle flash access with minimal blocking
- Memory Efficient: Uses intrusive linked lists to minimize RAM usage
- Flexible Flash Support: The
NdlDataStorage
trait can be implemented for most flash chips - Worker Task Pattern: Background task handles all flash I/O operations (use our default or bring your own!)
In the demos
folder you can find an example for the nRF52840-DK that stores the blinking frequencies of the four
board LEDs on flash and loads them after reboot.
The library is built around a StorageList
consisting of StorageListNode
s, where
StorageList
is the central coordinator that manages all configuration itemsStorageListNode
is the individual configuration item that can be attached to a listStorageListNodeHandle
is a handle for reading and writing configuration data
and a background worker task that handles all flash I/O operations including:
- Loading configuration data from flash on startup
- Writing changed configuration data to flash
- Garbage collection to reclaim space from old data
- API Documentation - docs.rs API reference
- Safety Guide - Important safety considerations for contributors
- Data Portability Guide - Configuration node data evolution guide
- Demos - Complete working demo example
- Worker Task - Default worker task implementation that can serve as a template to build your own
The library supports different storage backends through the NdlDataStorage
trait:
- Sequential Storage: Built-in support for
sequential-storage
crate - Test Storage: In-memory storage for testing and development
This crate contains lots of unsafe
code for performance and memory efficiency.
All unsafe code follows strict safety rules documented in the Safety Guide.
The public API, however, is safe to use.
std
- Enable standard library support (for testing)defmt
- Enable defmt logging support (efficient logging on embedded)- Default: no features enabled (no_std embedded use)
The StorageList
has three functions that need to be executed by a worker task:
process_reads
: deserialize data from flash into the nodesprocess_writes
: serialize data from the nodes into flashprocess_garbage
: delete old data (but keep a few as a backup)
The worker task is separate to allow users to control exactly when read/write/garbage processing takes place, enabling control over flash durability consumption, power consumption, efficient batching, and other specific requirements.
However, cfg-noodle provides a basic default worker task implementation that is sufficient for many cases.
When attaching a StorageListNode
to a StorageList
, the following happens:
- User calls
attach
- Node is pushed to the intrusive linked list (if all safety checks pass and the key does not already exist)
- Worker task is notified about the node waiting to be hydrated
- Worker task calls
process_reads
to hydrate the node from flash data or initialize it with a default value otherwise - User obtains a
StorageListNodeHandle
that allows loading/writing the underlying value
When writing a value via the StorageListNodeHandle
, the following happens:
- User calls
write
- Value in the
StorageListNode
is replaced - Worker task is notified about the pending write to flash
- Worker task calls
process_writes
to write the entire linked list to flash
After writing to flash (or at other regular intervals) old data has to be deleted from flash. When the worker task calls process_garbage
this is what happens:
- Check whether GC is needed (if not, just return)
- Iterate over the existing elements in flash
- Invalidate (i.e. mark as "to be deleted") all elements except for the ones belonging to the current and latest three writes of the list.
General design notes, vocabulary and data representation in flash can be found in in DESIGN.md
We welcome contributions! Please see our Contributing Guide for details.