use super::{BootMode, BootState};
pub trait Transport: embedded_io::Read + embedded_io::Write {}
pub trait Storage:
embedded_storage::nor_flash::NorFlash + embedded_storage::nor_flash::ReadNorFlash
{
fn as_slice(&self) -> &[u8];
fn unlock(&mut self);
}
pub trait BootCtl {
fn is_boot_requested(&self) -> bool;
fn system_reset(&mut self, mode: BootMode) -> !;
}
pub trait BootMetaStore {
type Error: core::fmt::Debug;
fn boot_state(&self) -> BootState;
fn has_trials(&self) -> bool;
fn app_checksum(&self) -> u16;
fn app_size(&self) -> u32;
fn advance(&mut self) -> Result<BootState, Self::Error>;
fn consume_trial(&mut self) -> Result<(), Self::Error>;
fn refresh(
&mut self,
checksum: u16,
state: BootState,
app_size: u32,
) -> Result<(), Self::Error>;
}
pub struct Platform<T, S, B, C>
where
T: Transport,
S: Storage,
B: BootMetaStore,
C: BootCtl,
{
pub transport: T,
pub storage: S,
pub boot_meta: B,
pub ctl: C,
}
impl<T, S, B, C> Platform<T, S, B, C>
where
T: Transport,
S: Storage,
B: BootMetaStore,
C: BootCtl,
{
#[inline(always)]
pub fn new(transport: T, storage: S, boot_meta: B, ctl: C) -> Self {
Self {
transport,
storage,
boot_meta,
ctl,
}
}
}