embedded-shadow
A no_std, no-alloc shadow register table for embedded systems with dirty tracking and transactional writes.
Features
- Zero allocation - All storage is statically allocated via const generics
- Dirty tracking - Efficiently track which blocks have been modified
- Dual views - Separate Host (application) and Kernel (hardware) access patterns
- Access policies - Control read/write permissions for different memory regions
- Persistence policies - Define what and when data should be persisted
- Staging support - Preview and commit/rollback transactional writes
- Critical-section support - Thread-safe access when needed
Architecture
The shadow registry uses a one-way dirty tracking model:
┌──────────────────┐ ┌──────────────────────────┐
│ Host (App) │ │ Kernel (HW) │
│ │ │ │
│ write_range() │────────▶│ for_each_dirty_block() │
│ (marks dirty) │ dirty │ (reads dirty) │
│ │ bits │ │
│ │◀────────│ clear_dirty() │
│ │ reset │ write_range() │
│ │ │ (no dirty mark) │
└──────────────────┘ └──────────────────────────┘
- Host writes mark blocks as dirty and may trigger persistence
- Kernel reads dirty state to sync changes to hardware
- Kernel writes update the shadow (e.g., after reading from hardware) without marking dirty
- Kernel clears dirty bits after syncing
This design enables efficient one-way synchronization from application to hardware.
Quick Start
use *;
// Create storage: 1KB total, 64-byte blocks, 16 blocks
let storage = new
.
.
.
.default_access
.no_persist
.build;
// Load factory defaults at boot (doesn't mark dirty)
storage.load_defaults.unwrap;
// host_shadow() and kernel_shadow() return short-lived references,
// typically constructed each iteration and passed via context, e.g.:
// fn update(ctx: &mut HostContext) { ctx.shadow.with_view(|view| { ... }); }
// fn run_once(ctx: &mut KernelContext) { ctx.shadow.with_view_unchecked(|view| { ... }); }
// Host side (main loop): use with_view for critical section safety
storage.host_shadow.with_view;
// Kernel side (ISR): use with_view_unchecked since ISR already has exclusive access
unsafe
Examples
See the examples directory for detailed usage:
basic.rs- Core concepts and dirty trackingstaging.rs- Transactional writes with preview/commit/rollbackaccess_policy.rs- Memory protection and access controlpersist.rs- Flash persistence patternscomplex.rs- Real-world motor controller simulation
Critical Section
This crate requires a critical-section implementation for your platform. Most embedded HALs provide this. For testing, add:
[]
= { = "1.2", = ["std"] }
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.