Allow different erase sizes for active and dfu

This commit is contained in:
Rasmus Melchior Jacobsen 2023-04-04 21:30:49 +02:00
parent 6c93309df4
commit 53efb02900
3 changed files with 9 additions and 79 deletions

View file

@ -56,9 +56,9 @@ trait FlashConfigEx {
}
impl<T: FlashConfig> FlashConfigEx for T {
/// Get the page size which is the "unit of operation" within the bootloader.
fn page_size() -> usize {
assert_eq!(T::ACTIVE::ERASE_SIZE, T::DFU::ERASE_SIZE);
T::ACTIVE::ERASE_SIZE
core::cmp::max(T::ACTIVE::ERASE_SIZE, T::DFU::ERASE_SIZE)
}
}
@ -182,6 +182,8 @@ impl BootLoader {
assert_eq!(0, P::page_size() % aligned_buf.len());
assert_eq!(0, P::page_size() % P::ACTIVE::WRITE_SIZE);
assert_eq!(0, P::page_size() % P::DFU::WRITE_SIZE);
assert_eq!(0, P::page_size() % P::ACTIVE::ERASE_SIZE);
assert_eq!(0, P::page_size() % P::DFU::ERASE_SIZE);
assert!(aligned_buf.len() >= P::STATE::WRITE_SIZE);
assert_partitions(self.active, self.dfu, self.state, P::page_size(), P::STATE::WRITE_SIZE);

View file

@ -1,70 +0,0 @@
#![allow(unused)]
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
pub struct LargeErase<F, const ERASE_SIZE: usize>(pub F);
impl<F, const ERASE_SIZE: usize> LargeErase<F, ERASE_SIZE> {
pub const fn new(flash: F) -> Self {
Self(flash)
}
}
impl<F: ErrorType, const ERASE_SIZE: usize> ErrorType for LargeErase<F, ERASE_SIZE> {
type Error = F::Error;
}
impl<F: NorFlash, const ERASE_SIZE: usize> NorFlash for LargeErase<F, ERASE_SIZE> {
const WRITE_SIZE: usize = F::ERASE_SIZE;
const ERASE_SIZE: usize = ERASE_SIZE;
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
assert!(ERASE_SIZE >= F::ERASE_SIZE);
assert_eq!(0, ERASE_SIZE % F::ERASE_SIZE);
self.0.erase(from, to)
}
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
self.0.write(offset, bytes)
}
}
impl<F: ReadNorFlash, const ERASE_SIZE: usize> ReadNorFlash for LargeErase<F, ERASE_SIZE> {
const READ_SIZE: usize = F::READ_SIZE;
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
self.0.read(offset, bytes)
}
fn capacity(&self) -> usize {
self.0.capacity()
}
}
impl<F: AsyncNorFlash, const ERASE_SIZE: usize> AsyncNorFlash for LargeErase<F, ERASE_SIZE> {
const WRITE_SIZE: usize = F::ERASE_SIZE;
const ERASE_SIZE: usize = ERASE_SIZE;
async fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
assert!(ERASE_SIZE >= F::ERASE_SIZE);
assert_eq!(0, ERASE_SIZE % F::ERASE_SIZE);
self.0.erase(from, to).await
}
async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
self.0.write(offset, bytes).await
}
}
impl<F: AsyncReadNorFlash, const ERASE_SIZE: usize> AsyncReadNorFlash for LargeErase<F, ERASE_SIZE> {
const READ_SIZE: usize = F::READ_SIZE;
async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
self.0.read(offset, bytes).await
}
fn capacity(&self) -> usize {
self.0.capacity()
}
}

View file

@ -7,7 +7,6 @@ mod fmt;
mod boot_loader;
mod firmware_updater;
mod large_erase;
mod mem_flash;
mod partition;
@ -49,7 +48,6 @@ mod tests {
use futures::executor::block_on;
use super::*;
use crate::large_erase::LargeErase;
use crate::mem_flash::MemFlash;
/*
@ -156,7 +154,7 @@ mod tests {
const DFU: Partition = Partition::new(0, 16384);
let mut active = MemFlash::<16384, 4096, 8>::random();
let mut dfu = LargeErase::<_, 4096>::new(MemFlash::<16384, 2048, 8>::random());
let mut dfu = MemFlash::<16384, 2048, 8>::random();
let mut state = MemFlash::<4096, 128, 4>::random();
let mut aligned = [0; 4];
@ -188,7 +186,7 @@ mod tests {
// First DFU page is untouched
for i in DFU.from + 4096..DFU.to {
assert_eq!(dfu.0.mem[i], original[i - DFU.from - 4096], "Index {}", i);
assert_eq!(dfu.mem[i], original[i - DFU.from - 4096], "Index {}", i);
}
}
@ -200,7 +198,7 @@ mod tests {
const DFU: Partition = Partition::new(0, 16384);
let mut aligned = [0; 4];
let mut active = LargeErase::<_, 4096>::new(MemFlash::<16384, 2048, 4>::random());
let mut active = MemFlash::<16384, 2048, 4>::random();
let mut dfu = MemFlash::<16384, 4096, 8>::random();
let mut state = MemFlash::<4096, 128, 4>::random();
@ -208,7 +206,7 @@ mod tests {
let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()];
for i in ACTIVE.from..ACTIVE.to {
active.0.mem[i] = original[i - ACTIVE.from];
active.mem[i] = original[i - ACTIVE.from];
}
let mut updater = FirmwareUpdater::new(DFU, STATE);
@ -229,7 +227,7 @@ mod tests {
);
for i in ACTIVE.from..ACTIVE.to {
assert_eq!(active.0.mem[i], update[i - ACTIVE.from], "Index {}", i);
assert_eq!(active.mem[i], update[i - ACTIVE.from], "Index {}", i);
}
// First DFU page is untouched