Add a ConfigSection
A persistent configuration section is owned by the feature crate that interprets it (for example rohi-net owns
WifiConfig), never by rohi-config. The stored bytes are a persistent ABI; read it
before choosing names and field numbers.
-
Define the type in the feature crate with bounded fields (
heapless, fixed arrays) and explicit CBOR layout:use minicbor::{CborLen, Decode, Encode}; use rohi_config::ConfigSection; #[derive(Clone, PartialEq, Eq, Encode, Decode, CborLen, ConfigSection)] #[cbor(array)] // explicit representation: part of the ABI #[config(version = 1)] // required pub struct UplinkConfig { #[n(0)] pub endpoint: Endpoint, #[n(1)] pub interval_s: u32, }- The section ID is the FNV-1a hash of the struct name. Renaming the type orphans the stored data; pick the
name once, or pin the ID with
#[config(id = 0x..., version = N)]. - Field numbers (
#[n(..)]) are the schema: only append, never reuse or renumber. - Secrets: do not derive
Debug; implement it by hand with redaction (seeWifiPassword).
- The section ID is the FNV-1a hash of the struct name. Renaming the type orphans the stored data; pick the
name once, or pin the ID with
-
Pin the encoding with a golden test (
assert_eq!on the exact bytes,T::IDandT::VERSION); seecbor_encoding_is_stableforWifiConfig. Also test the round trip and the maximum-size value againstMAX_SECTION_PAYLOAD. -
Validate in the type (
validate()), at the boundary that accepts new values and again in the consumer. -
Use it from the firmware through
ConfigHandle::{get, set, remove}; the configuration task is the only owner of the store. If the runtime must react to a change (as Wi-Fi does), publish the new value as desired state from the owner task right after the commit, with no.awaitin between (Durable mutation). -
Versioning: changing the layout later means bumping
versionand, if old data must stay readable, adding adecode_versionedhook (rohi_config::decode_exactdecodes older layouts strictly). -
Docs: add the section to the persistent ABI examples if it introduces a new rule, and note it in Configuration store.
A destructive “erase all” is deliberately not part of ConfigHandle; per-section removal must never touch sections of
other features (a future identity).