Expand description
Chip-agnostic implementation of the umsh-hal storage traits on top
of sequential-storage.
This is the storage engine every UMSH board shares. It is generic over
the async flash driver (F: MultiwriteNorFlash) and the sharing mutex
(M: RawMutex); chip BSPs supply concrete backings and alias the
types.
The same map serves every trait. Logical separation is by ASCII key prefix decided at the call site:
| Prefix | Trait | Payload |
|---|---|---|
id.sk | (direct) | local Ed25519 secret scalar (32 B) |
peers | PeerStore | packed pubkey index (32 B × N) |
peer:<pk> | PeerStore | alias len (1 B) + alias (≤16 B) |
ch:<id> | KeyValueStore | channel name + key + flags |
mac.tx:<pk> | CounterStore | TX reservation boundary (u32 LE) |
mac.rx:<pk> | CounterStore | RX replay-window boundary (u32 LE) |
§CPU stall warning
Page erases block the executor for a long time on every backend we
use — the nRF52840 NVMC halts the CPU for ~85 ms, and the ESP32
suspends the flash cache for the duration of the write. No amount of
async scheduling can preempt either. Callers MUST batch writes; the
MAC’s TX-side COUNTER_PERSIST_BLOCK_SIZE = 128 and the RX-side
mirror keep this manageable for counters, and peer-record writes
should be debounced at the application layer.
§Sharing model
FlashStore owns the flash + map behind an async mutex.
KeyValueView, CounterView, PeerView, and ChannelView
are zero-cost view types that each hold a &'static FlashStore. They
exist as separate types because the umsh-hal traits both define
load and store methods — implementing both on a single type would
force every caller to disambiguate via UFCS. Keep them split.
Structs§
- Channel
View - View implementing [
umsh_hal::ChannelStore] on top of a sharedFlashStore. - Counter
View - View implementing [
umsh_hal::CounterStore] on top of a sharedFlashStore. Counters are stored as little-endian u32 values keyed by the caller-supplied context bytes (the MAC layer is expected to prefix them withmac.tx:/mac.rx:). - Flash
Store - Owns the flash driver and the
sequential-storagemap. - KeyValue
View - View implementing [
umsh_hal::KeyValueStore] on top of a sharedFlashStore. The view itself is essentially a thin pointer; the real storage lives in the staticFlashStore. - Peer
View - View implementing [
umsh_hal::PeerStore] on top of a sharedFlashStore. Follows the same view-type pattern asKeyValueViewandCounterView.
Enums§
- Error
- Errors surfaced by this module, generic over the flash driver’s own error type.
Constants§
- ALIAS_
HEADER_ LEN - Fixed-size alias header prepended to every peer record.
- MAX_
ALIAS_ LEN - Maximum alias length in bytes (UTF-8).
- MAX_
CHANNELS - Maximum number of channels tracked in the channel index.
- MAX_
CHANNEL_ NAME_ LEN - Maximum channel name length in bytes (UTF-8). Matches CliSession’s alias cap.
- MAX_
KEY_ LEN - Maximum stored key length. Covers an 8-byte ASCII prefix plus a 32-byte Ed25519 pubkey with headroom for shorter prefixes / new namespaces.
- MAX_
PEERS - Maximum number of peers tracked in the peer index. 8 × 32 = 256 bytes, comfortably under the 512-byte scratch limit.
- MAX_
PEER_ RECORD_ LEN - Maximum total peer record size.
- SCRATCH_
LEN - Per-call scratch buffer size used for sequential-storage’s serialise / deserialise workspace. Must hold the largest (serialised key + value) pair the store ever sees. 512 B comfortably covers a 64 B key plus a ~256 B peer record.