Skip to main content

tinyboot_core/traits/
boot.rs

1use super::{BootMode, BootState};
2
3/// Trait for firmware transfer protocol.
4pub trait Transport: embedded_io::Read + embedded_io::Write {}
5
6/// Trait for reading and writing firmware to persistent storage.
7///
8/// Flash is memory-mapped, so [`as_slice`](Storage::as_slice) provides
9/// zero-copy read access to the app region.
10pub trait Storage:
11    embedded_storage::nor_flash::NorFlash + embedded_storage::nor_flash::ReadNorFlash
12{
13    /// Direct read access to the app region (zero-copy).
14    fn as_slice(&self) -> &[u8];
15
16    /// Unlock flash for erase/write. Called once before entering the protocol loop.
17    fn unlock(&mut self);
18}
19
20/// Trait for system boot control.
21pub trait BootCtl {
22    /// Returns true if the bootloader was explicitly requested (e.g. via boot mode register).
23    fn is_boot_requested(&self) -> bool;
24
25    /// Reset the system into the specified boot mode.
26    fn system_reset(&mut self, mode: BootMode) -> !;
27}
28
29/// Persistent boot metadata storage.
30pub trait BootMetaStore {
31    /// Error type for metadata operations.
32    type Error: core::fmt::Debug;
33
34    /// Current boot lifecycle state.
35    fn boot_state(&self) -> BootState;
36
37    /// Returns true if any trial boots remain.
38    fn has_trials(&self) -> bool;
39
40    /// Stored CRC16 of the application firmware.
41    fn app_checksum(&self) -> u16;
42
43    /// Stored application size in bytes.
44    fn app_size(&self) -> u32;
45
46    /// Step state down by one (1→0 bit clear).
47    fn advance(&mut self) -> Result<BootState, Self::Error>;
48
49    /// Consume one trial boot (clears one bit in the trials field).
50    fn consume_trial(&mut self) -> Result<(), Self::Error>;
51
52    /// Erase meta and rewrite with given checksum, state, and app_size.
53    /// Trials return to erased default (full).
54    fn refresh(
55        &mut self,
56        checksum: u16,
57        state: BootState,
58        app_size: u32,
59    ) -> Result<(), Self::Error>;
60}
61
62/// Concrete platform holding all boot-time peripherals.
63///
64/// Constructed by the board-specific crate and passed to [`Core::new`](crate::Core::new).
65pub struct Platform<T, S, B, C>
66where
67    T: Transport,
68    S: Storage,
69    B: BootMetaStore,
70    C: BootCtl,
71{
72    /// UART / RS-485 transport.
73    pub transport: T,
74    /// Flash storage for reading and writing firmware.
75    pub storage: S,
76    /// Persistent boot metadata (state, trials, checksum).
77    pub boot_meta: B,
78    /// Boot control (reset, boot mode selection).
79    pub ctl: C,
80}
81
82impl<T, S, B, C> Platform<T, S, B, C>
83where
84    T: Transport,
85    S: Storage,
86    B: BootMetaStore,
87    C: BootCtl,
88{
89    /// Assemble a platform from its components.
90    #[inline(always)]
91    pub fn new(transport: T, storage: S, boot_meta: B, ctl: C) -> Self {
92        Self {
93            transport,
94            storage,
95            boot_meta,
96            ctl,
97        }
98    }
99}