#![no_std]
use embedded_shadow::prelude::*;
pub fn main() {
let storage = ShadowStorageBuilder::new()
.total_size::<1024>() .block_size::<64>() .block_count::<16>() .default_access() .no_persist() .build();
let host_shadow = storage.host_shadow();
let kernel_shadow = storage.kernel_shadow();
host_shadow.with_view(|view| {
let config_data = [0xDE, 0xAD, 0xBE, 0xEF];
view.write_range(0x100, &config_data).unwrap();
let control_data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
view.write_range(0x200, &control_data).unwrap();
});
kernel_shadow.with_view(|view| {
assert!(view.is_dirty(0x100, 4).unwrap(), "Config should be dirty");
assert!(view.is_dirty(0x200, 8).unwrap(), "Control should be dirty");
let mut buffer = [0u8; 8];
view.read_range(0x200, &mut buffer).unwrap();
assert_eq!(buffer, [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
let mut blocks_processed = 0;
view.for_each_dirty_block(|addr, data| {
blocks_processed += 1;
match addr {
0x80 => {
assert_eq!(data.len(), 64);
}
0x200 => {
assert_eq!(data.len(), 64);
}
_ => {}
}
Ok(())
})
.unwrap();
assert_eq!(blocks_processed, 2, "Should process 2 dirty blocks");
view.clear_dirty();
assert!(!view.any_dirty());
assert!(!view.is_dirty(0x100, 4).unwrap());
});
unsafe {
host_shadow.with_view_unchecked(|view| {
view.write_range(0x300, &[0xFF; 16]).unwrap();
});
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_basic_example() {
super::main();
}
}