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}