diff --git a/src/boot/mod.rs b/src/boot/mod.rs index 7d09796..927716b 100644 --- a/src/boot/mod.rs +++ b/src/boot/mod.rs @@ -113,6 +113,7 @@ impl MoonbootBoot( + &self.config, &mut self.storage, &mut self.state, progress, @@ -157,6 +158,7 @@ impl MoonbootBoot( + &self.config, &mut self.storage, &mut self.state, ExchangeProgress { diff --git a/src/exchange/mod.rs b/src/exchange/mod.rs index 6f7592e..416e1e1 100644 --- a/src/exchange/mod.rs +++ b/src/exchange/mod.rs @@ -2,7 +2,10 @@ pub mod ram; pub mod scratch; -use crate::state::{ExchangeProgress, State}; +use crate::{ + hardware::Config, + state::{ExchangeProgress, State}, +}; use embedded_storage::Storage; /// Abstraction for the exchange operation of the current state. @@ -11,6 +14,7 @@ pub trait Exchange { fn exchange( &mut self, + config: &Config, storage: &mut STORAGE, state: &mut STATE, progress: ExchangeProgress, diff --git a/src/exchange/ram.rs b/src/exchange/ram.rs index 9be9f9a..984ad3f 100644 --- a/src/exchange/ram.rs +++ b/src/exchange/ram.rs @@ -2,6 +2,7 @@ use embedded_storage::Storage; use crate::{ exchange::Exchange, + hardware::Config, log, state::{ExchangeProgress, State, Update}, Address, @@ -36,6 +37,7 @@ where fn exchange( &mut self, + _config: &Config, storage: &mut STORAGE, state: &mut STATE, progress: ExchangeProgress, diff --git a/src/exchange/scratch.rs b/src/exchange/scratch.rs index 67e4e4b..2d1f908 100644 --- a/src/exchange/scratch.rs +++ b/src/exchange/scratch.rs @@ -1,21 +1,21 @@ -use core::{fmt::Debug, ops::Range}; +use core::fmt::Debug; use embedded_storage::Storage; use crate::{ exchange::Exchange, + hardware::Config, log, state::{ExchangeProgress, ExchangeStep, State, Update}, Address, }; -pub struct Scratch<'a> { - pub pages: &'a [Range
], -} +pub struct Scratch; pub enum ExchangeError { Storage(STORAGE), State(STATE), + ScratchInsufficient, } impl Debug for ExchangeError @@ -27,11 +27,12 @@ where match self { Self::Storage(arg0) => f.debug_tuple("Storage").field(arg0).finish(), Self::State(arg0) => f.debug_tuple("State").field(arg0).finish(), + Self::ScratchInsufficient => f.write_str("ScratchInsufficient"), } } } -impl<'a, STORAGE: Storage, STATE: State> Exchange for Scratch<'a> +impl Exchange for Scratch where STORAGE::Error: Debug, STATE::Error: Debug, @@ -40,6 +41,7 @@ where fn exchange( &mut self, + config: &Config, storage: &mut STORAGE, state: &mut STATE, progress: ExchangeProgress, @@ -56,6 +58,10 @@ where assert_ne!(a.size, 0); assert_ne!(b.size, 0); + if config.scratch_bank.size < INTERNAL_PAGE_SIZE as u32 { + return Err(ExchangeError::ScratchInsufficient); + } + let size = a.size; // Both are equal let full_pages = size / INTERNAL_PAGE_SIZE as Address; @@ -74,6 +80,8 @@ where let a_location = a.location; let b_location = b.location; + let scratch_bank_pages = config.scratch_bank.size / INTERNAL_PAGE_SIZE as u32; + let mut first = true; for page_index in page_index..full_pages { let offset = page_index * INTERNAL_PAGE_SIZE as u32; @@ -81,8 +89,9 @@ where let a_location = a_location + offset; let b_location = b_location + offset; - let scratch_index = page_index as usize % self.pages.len(); - let scratch_location = self.pages[scratch_index].start; + let scratch_index = page_index % scratch_bank_pages; + let scratch_offset = scratch_index * INTERNAL_PAGE_SIZE as u32; + let scratch_location = config.scratch_bank.location + scratch_offset; log::trace!( "Exchange: Page {}, from a ({}) to b ({}) using scratch ({})", diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index bdef5ce..3b9cfdf 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -47,6 +47,8 @@ pub struct Config { pub update_bank: Bank, /// bank the bootloader is contained in, switching between banks pub bootloader_bank: Bank, + /// bank the pages are temporarily stored when using the `Scratch` exchange method + pub scratch_bank: Bank, // Initial Image is stored to this bank after first update, restore on failure // pub golden_bank: Bank, /// section of RAM of this device diff --git a/src/hardware/processor.rs b/src/hardware/processor.rs index 33be20a..dcd54f3 100644 --- a/src/hardware/processor.rs +++ b/src/hardware/processor.rs @@ -35,7 +35,7 @@ pub mod cortex_m { } } - fn setup(&mut self, config: &crate::hardware::Config) { + fn setup(&mut self, _config: &crate::hardware::Config) { // Nothing to do! } } diff --git a/src/manager/mod.rs b/src/manager/mod.rs index 4f4498d..9f41206 100644 --- a/src/manager/mod.rs +++ b/src/manager/mod.rs @@ -15,9 +15,13 @@ pub struct MoonbootManager { processor: CONTEXT::Processor, } +#[cfg_attr(feature = "use-defmt", derive(Format))] +#[derive(Debug)] pub struct InitError; -pub enum MarkError { +#[cfg_attr(feature = "use-defmt", derive(Format))] +#[derive(Debug)] +pub enum MarkError { UpdateQueuedButNotInstalled, State(E), } diff --git a/src/state/mod.rs b/src/state/mod.rs index 18501c6..24d6bfb 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -116,7 +116,7 @@ pub struct MoonbootState { /// RAM. As long as you don't want to perform update download, power cycle the device, and then /// apply the update, storing it in volatile memory is fine. pub trait State { - type Error; + type Error: Debug; /// Read the shared state fn read(&mut self) -> Result;