Change scratch to use a bank defined in config

This commit is contained in:
Wouter Geraedts 2022-07-12 10:35:49 +02:00
parent 40f93525b7
commit a301aaa9ea
8 changed files with 34 additions and 11 deletions

View file

@ -113,6 +113,7 @@ impl<CONTEXT: Context, const INTERNAL_PAGE_SIZE: usize> MoonbootBoot<CONTEXT, IN
);
let exchange_result = self.exchange.exchange::<INTERNAL_PAGE_SIZE>(
&self.config,
&mut self.storage,
&mut self.state,
progress,
@ -157,6 +158,7 @@ impl<CONTEXT: Context, const INTERNAL_PAGE_SIZE: usize> MoonbootBoot<CONTEXT, IN
// Try to exchange the firmware images
let exchange_result = self.exchange.exchange::<INTERNAL_PAGE_SIZE>(
&self.config,
&mut self.storage,
&mut self.state,
ExchangeProgress {

View file

@ -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<STORAGE: Storage, STATE: State> {
fn exchange<const INTERNAL_PAGE_SIZE: usize>(
&mut self,
config: &Config,
storage: &mut STORAGE,
state: &mut STATE,
progress: ExchangeProgress,

View file

@ -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<const INTERNAL_PAGE_SIZE: usize>(
&mut self,
_config: &Config,
storage: &mut STORAGE,
state: &mut STATE,
progress: ExchangeProgress,

View file

@ -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<Address>],
}
pub struct Scratch;
pub enum ExchangeError<STORAGE, STATE> {
Storage(STORAGE),
State(STATE),
ScratchInsufficient,
}
impl<STORAGE, STATE> Debug for ExchangeError<STORAGE, STATE>
@ -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<STORAGE, STATE> for Scratch<'a>
impl<STORAGE: Storage, STATE: State> Exchange<STORAGE, STATE> for Scratch
where
STORAGE::Error: Debug,
STATE::Error: Debug,
@ -40,6 +41,7 @@ where
fn exchange<const INTERNAL_PAGE_SIZE: usize>(
&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 ({})",

View file

@ -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

View file

@ -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!
}
}

View file

@ -15,9 +15,13 @@ pub struct MoonbootManager<CONTEXT: Context, const INTERNAL_PAGE_SIZE: usize> {
processor: CONTEXT::Processor,
}
#[cfg_attr(feature = "use-defmt", derive(Format))]
#[derive(Debug)]
pub struct InitError;
pub enum MarkError<E> {
#[cfg_attr(feature = "use-defmt", derive(Format))]
#[derive(Debug)]
pub enum MarkError<E: core::fmt::Debug> {
UpdateQueuedButNotInstalled,
State(E),
}

View file

@ -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<MoonbootState, Self::Error>;