tasks: simulation: split out flash storage api bits into separate mod
This commit is contained in:
@@ -9,6 +9,9 @@ pub mod idle;
|
||||
pub mod logging;
|
||||
pub mod graphics;
|
||||
|
||||
#[cfg(feature="simulation")]
|
||||
pub mod storage;
|
||||
|
||||
#[cfg(feature="simulation")]
|
||||
pub mod simdata;
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ impl RmpData for StreamHeader {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_rmp<Writer: RmpWrite>(&self, writer: &mut Writer) -> Result<(), ValueWriteError<Writer::Error>> {
|
||||
fn write_rmp<Writer: RmpWrite>(&self, _writer: &mut Writer) -> Result<(), ValueWriteError<Writer::Error>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
122
src/storage.rs
Normal file
122
src/storage.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use core::{cell::RefCell, fmt::Formatter};
|
||||
|
||||
use alloc::rc::Rc;
|
||||
use embedded_storage::{ReadStorage, Storage};
|
||||
use log::*;
|
||||
use rmp::decode::{RmpRead, RmpReadErr};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SharedFlash<S> {
|
||||
storage: Rc<RefCell<S>>
|
||||
}
|
||||
|
||||
impl<S> Clone for SharedFlash<S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
storage: Rc::clone(&self.storage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> SharedFlash<S> {
|
||||
pub fn new(storage: S) -> Self {
|
||||
Self {
|
||||
storage: Rc::new(RefCell::new(storage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Storage> Storage for SharedFlash<S> {
|
||||
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||
self.storage.borrow_mut().write(offset, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ReadStorage> ReadStorage for SharedFlash<S> {
|
||||
type Error = S::Error;
|
||||
|
||||
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.storage.borrow_mut().read(offset, bytes)
|
||||
}
|
||||
|
||||
fn capacity(&self) -> usize {
|
||||
self.storage.borrow().capacity()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RangeReadError<E> {
|
||||
OutOfData,
|
||||
Storage(E)
|
||||
}
|
||||
impl<E: core::fmt::Debug + 'static> RmpReadErr for RangeReadError<E> {}
|
||||
|
||||
impl<E> core::fmt::Display for RangeReadError<E> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||
f.write_str("RmpErr")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RangeReader<S> {
|
||||
storage: S,
|
||||
start: usize,
|
||||
end: usize,
|
||||
offset: usize
|
||||
}
|
||||
|
||||
impl<S: ReadStorage> RangeReader<S> {
|
||||
pub const fn new(storage: S, start: usize, end: usize) -> Self {
|
||||
assert!(start <= end);
|
||||
// TODO: Should add bounds checking since we will know the size of the chunk already
|
||||
Self {
|
||||
storage,
|
||||
start,
|
||||
end,
|
||||
offset: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn seek(&mut self, offset: usize) -> Result<(), RangeReadError<S::Error>> {
|
||||
self.offset += offset;
|
||||
if self.offset > self.end {
|
||||
Err(RangeReadError::OutOfData)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subset(&self, size: usize) -> Result<Self, RangeReadError<S::Error>> where S: Clone + core::fmt::Debug {
|
||||
trace!("subset {:#02x}:{:#02x} -> {:#02x}:{:#02x}", self.start, self.end, self.start + self.offset, self.start + self.offset + size);
|
||||
if self.start + self.offset + size > self.end {
|
||||
Err(RangeReadError::OutOfData)
|
||||
} else {
|
||||
Ok(Self {
|
||||
storage: self.storage.clone(),
|
||||
start: self.offset + self.start,
|
||||
end: self.start + self.offset + size,
|
||||
offset: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ReadStorage> RmpRead for RangeReader<S> where S::Error: core::fmt::Debug + 'static {
|
||||
type Error = RangeReadError<S::Error>;
|
||||
|
||||
fn read_exact_buf(&mut self, buf: &mut [u8]) -> Result<(), RangeReadError<S::Error>> {
|
||||
let pos = self.start + self.offset;
|
||||
if pos > self.end {
|
||||
Err(RangeReadError::OutOfData)
|
||||
} else {
|
||||
assert!(pos + buf.len() <= self.end);
|
||||
match self.storage.read(pos as u32, buf) {
|
||||
Ok(_) => {
|
||||
self.offset += buf.len();
|
||||
Ok(())
|
||||
},
|
||||
Err(err) => Err(RangeReadError::Storage(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +1,13 @@
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::Formatter;
|
||||
|
||||
use alloc::rc::Rc;
|
||||
use embassy_sync::channel::DynamicSender;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_storage::{ReadStorage, Storage};
|
||||
use embedded_storage::ReadStorage;
|
||||
use esp_bootloader_esp_idf::partitions::PartitionTable;
|
||||
use esp_storage::FlashStorage;
|
||||
use nalgebra::{Vector2, Vector3};
|
||||
use log::*;
|
||||
use rmp::decode::{RmpRead, RmpReadErr, ValueReadError};
|
||||
use rmp::decode::ValueReadError;
|
||||
|
||||
use crate::{Breaker, events::{Measurement, SensorSource, SensorState}, simdata::{AnnotationReading, EventRecord, EventStreamHeader, GPSReading, IMUReading, RmpData, SimDataError, StreamEvent, StreamHeader, StreamIndex, StreamType}};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SharedFlash<S> {
|
||||
storage: Rc<RefCell<S>>
|
||||
}
|
||||
|
||||
impl<S> Clone for SharedFlash<S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
storage: Rc::clone(&self.storage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> SharedFlash<S> {
|
||||
pub fn new(storage: S) -> Self {
|
||||
Self {
|
||||
storage: Rc::new(RefCell::new(storage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Storage> Storage for SharedFlash<S> {
|
||||
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||
self.storage.borrow_mut().write(offset, bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ReadStorage> ReadStorage for SharedFlash<S> {
|
||||
type Error = S::Error;
|
||||
|
||||
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.storage.borrow_mut().read(offset, bytes)
|
||||
}
|
||||
|
||||
fn capacity(&self) -> usize {
|
||||
self.storage.borrow().capacity()
|
||||
}
|
||||
}
|
||||
use crate::{Breaker, events::{Measurement, SensorSource, SensorState}, simdata::{AnnotationReading, EventRecord, EventStreamHeader, GPSReading, IMUReading, RmpData, SimDataError, StreamEvent, StreamHeader, StreamIndex, StreamType}, storage::{RangeReadError, RangeReader, SharedFlash}};
|
||||
|
||||
pub struct SimDataTable<S> {
|
||||
reader: RangeReader<S>,
|
||||
@@ -129,70 +86,6 @@ impl<S: ReadStorage + Clone + core::fmt::Debug> Iterator for SimDataTable<S> whe
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RangeReader<S> {
|
||||
storage: S,
|
||||
start: usize,
|
||||
end: usize,
|
||||
offset: usize
|
||||
}
|
||||
|
||||
impl<S: ReadStorage> RangeReader<S> {
|
||||
pub const fn new(storage: S, start: usize, end: usize) -> Self {
|
||||
assert!(start <= end);
|
||||
// TODO: Should add bounds checking since we will know the size of the chunk already
|
||||
Self {
|
||||
storage,
|
||||
start,
|
||||
end,
|
||||
offset: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn seek(&mut self, offset: usize) -> Result<(), RangeReadError<S::Error>> {
|
||||
self.offset += offset;
|
||||
if self.offset > self.end {
|
||||
Err(RangeReadError::OutOfData)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subset(&self, size: usize) -> Result<Self, SimDataError<S::Error>> where S: Clone + core::fmt::Debug {
|
||||
trace!("subset {:#02x}:{:#02x} -> {:#02x}:{:#02x}", self.start, self.end, self.start + self.offset, self.start + self.offset + size);
|
||||
if self.start + self.offset + size > self.end {
|
||||
Err(SimDataError::EndOfStream)
|
||||
} else {
|
||||
Ok(Self {
|
||||
storage: self.storage.clone(),
|
||||
start: self.offset + self.start,
|
||||
end: self.start + self.offset + size,
|
||||
offset: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ReadStorage> RmpRead for RangeReader<S> where S::Error: core::fmt::Debug + 'static {
|
||||
type Error = RangeReadError<S::Error>;
|
||||
|
||||
fn read_exact_buf(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
|
||||
let pos = self.start + self.offset;
|
||||
if pos > self.end {
|
||||
Err(RangeReadError::OutOfData)
|
||||
} else {
|
||||
assert!(pos + buf.len() <= self.end);
|
||||
match self.storage.read(pos as u32, buf) {
|
||||
Ok(_) => {
|
||||
self.offset += buf.len();
|
||||
Ok(())
|
||||
},
|
||||
Err(err) => Err(RangeReadError::Storage(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SimDataReader<S> {
|
||||
reader: RangeReader<S>,
|
||||
srcid: SensorSource,
|
||||
@@ -265,19 +158,6 @@ impl<S: ReadStorage> SimDataReader<S> where S::Error: core::fmt::Debug + 'static
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RangeReadError<E> {
|
||||
OutOfData,
|
||||
Storage(E)
|
||||
}
|
||||
impl<E: core::fmt::Debug + 'static> RmpReadErr for RangeReadError<E> {}
|
||||
|
||||
impl<E> core::fmt::Display for RangeReadError<E> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||
f.write_str("RmpErr")
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task(pool_size = 3)]
|
||||
pub async fn simulation_task(mut reader: SimDataReader<SharedFlash<FlashStorage>>, events: DynamicSender<'static, Measurement>) {
|
||||
warn!("Starting simulation for {:?}", reader.srcid());
|
||||
|
||||
Reference in New Issue
Block a user