diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-04-04 21:30:49 +0200 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-04-04 21:30:49 +0200 |
| commit | 53efb029009e3cb92bb19c8ac8f521407aa4d1e2 (patch) | |
| tree | b78038b9b4d38e927692743199100a0034c0da33 | |
| parent | 6c93309df490020f0ae4a515bf404dfd251b9b69 (diff) | |
Allow different erase sizes for active and dfu
| -rw-r--r-- | embassy-boot/boot/src/boot_loader.rs | 6 | ||||
| -rw-r--r-- | embassy-boot/boot/src/large_erase.rs | 70 | ||||
| -rw-r--r-- | embassy-boot/boot/src/lib.rs | 12 |
3 files changed, 9 insertions, 79 deletions
diff --git a/embassy-boot/boot/src/boot_loader.rs b/embassy-boot/boot/src/boot_loader.rs index 37fff621a..25f81009e 100644 --- a/embassy-boot/boot/src/boot_loader.rs +++ b/embassy-boot/boot/src/boot_loader.rs | |||
| @@ -56,9 +56,9 @@ trait FlashConfigEx { | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | impl<T: FlashConfig> FlashConfigEx for T { | 58 | impl<T: FlashConfig> FlashConfigEx for T { |
| 59 | /// Get the page size which is the "unit of operation" within the bootloader. | ||
| 59 | fn page_size() -> usize { | 60 | fn page_size() -> usize { |
| 60 | assert_eq!(T::ACTIVE::ERASE_SIZE, T::DFU::ERASE_SIZE); | 61 | core::cmp::max(T::ACTIVE::ERASE_SIZE, T::DFU::ERASE_SIZE) |
| 61 | T::ACTIVE::ERASE_SIZE | ||
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| @@ -182,6 +182,8 @@ impl BootLoader { | |||
| 182 | assert_eq!(0, P::page_size() % aligned_buf.len()); | 182 | assert_eq!(0, P::page_size() % aligned_buf.len()); |
| 183 | assert_eq!(0, P::page_size() % P::ACTIVE::WRITE_SIZE); | 183 | assert_eq!(0, P::page_size() % P::ACTIVE::WRITE_SIZE); |
| 184 | assert_eq!(0, P::page_size() % P::DFU::WRITE_SIZE); | 184 | assert_eq!(0, P::page_size() % P::DFU::WRITE_SIZE); |
| 185 | assert_eq!(0, P::page_size() % P::ACTIVE::ERASE_SIZE); | ||
| 186 | assert_eq!(0, P::page_size() % P::DFU::ERASE_SIZE); | ||
| 185 | assert!(aligned_buf.len() >= P::STATE::WRITE_SIZE); | 187 | assert!(aligned_buf.len() >= P::STATE::WRITE_SIZE); |
| 186 | assert_partitions(self.active, self.dfu, self.state, P::page_size(), P::STATE::WRITE_SIZE); | 188 | assert_partitions(self.active, self.dfu, self.state, P::page_size(), P::STATE::WRITE_SIZE); |
| 187 | 189 | ||
diff --git a/embassy-boot/boot/src/large_erase.rs b/embassy-boot/boot/src/large_erase.rs deleted file mode 100644 index b999a046f..000000000 --- a/embassy-boot/boot/src/large_erase.rs +++ /dev/null | |||
| @@ -1,70 +0,0 @@ | |||
| 1 | #![allow(unused)] | ||
| 2 | |||
| 3 | use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; | ||
| 4 | use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash}; | ||
| 5 | |||
| 6 | pub struct LargeErase<F, const ERASE_SIZE: usize>(pub F); | ||
| 7 | |||
| 8 | impl<F, const ERASE_SIZE: usize> LargeErase<F, ERASE_SIZE> { | ||
| 9 | pub const fn new(flash: F) -> Self { | ||
| 10 | Self(flash) | ||
| 11 | } | ||
| 12 | } | ||
| 13 | |||
| 14 | impl<F: ErrorType, const ERASE_SIZE: usize> ErrorType for LargeErase<F, ERASE_SIZE> { | ||
| 15 | type Error = F::Error; | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<F: NorFlash, const ERASE_SIZE: usize> NorFlash for LargeErase<F, ERASE_SIZE> { | ||
| 19 | const WRITE_SIZE: usize = F::ERASE_SIZE; | ||
| 20 | const ERASE_SIZE: usize = ERASE_SIZE; | ||
| 21 | |||
| 22 | fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { | ||
| 23 | assert!(ERASE_SIZE >= F::ERASE_SIZE); | ||
| 24 | assert_eq!(0, ERASE_SIZE % F::ERASE_SIZE); | ||
| 25 | self.0.erase(from, to) | ||
| 26 | } | ||
| 27 | |||
| 28 | fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { | ||
| 29 | self.0.write(offset, bytes) | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | impl<F: ReadNorFlash, const ERASE_SIZE: usize> ReadNorFlash for LargeErase<F, ERASE_SIZE> { | ||
| 34 | const READ_SIZE: usize = F::READ_SIZE; | ||
| 35 | |||
| 36 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { | ||
| 37 | self.0.read(offset, bytes) | ||
| 38 | } | ||
| 39 | |||
| 40 | fn capacity(&self) -> usize { | ||
| 41 | self.0.capacity() | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | impl<F: AsyncNorFlash, const ERASE_SIZE: usize> AsyncNorFlash for LargeErase<F, ERASE_SIZE> { | ||
| 46 | const WRITE_SIZE: usize = F::ERASE_SIZE; | ||
| 47 | const ERASE_SIZE: usize = ERASE_SIZE; | ||
| 48 | |||
| 49 | async fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { | ||
| 50 | assert!(ERASE_SIZE >= F::ERASE_SIZE); | ||
| 51 | assert_eq!(0, ERASE_SIZE % F::ERASE_SIZE); | ||
| 52 | self.0.erase(from, to).await | ||
| 53 | } | ||
| 54 | |||
| 55 | async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { | ||
| 56 | self.0.write(offset, bytes).await | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | impl<F: AsyncReadNorFlash, const ERASE_SIZE: usize> AsyncReadNorFlash for LargeErase<F, ERASE_SIZE> { | ||
| 61 | const READ_SIZE: usize = F::READ_SIZE; | ||
| 62 | |||
| 63 | async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { | ||
| 64 | self.0.read(offset, bytes).await | ||
| 65 | } | ||
| 66 | |||
| 67 | fn capacity(&self) -> usize { | ||
| 68 | self.0.capacity() | ||
| 69 | } | ||
| 70 | } | ||
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs index cc812d797..3109f2b47 100644 --- a/embassy-boot/boot/src/lib.rs +++ b/embassy-boot/boot/src/lib.rs | |||
| @@ -7,7 +7,6 @@ mod fmt; | |||
| 7 | 7 | ||
| 8 | mod boot_loader; | 8 | mod boot_loader; |
| 9 | mod firmware_updater; | 9 | mod firmware_updater; |
| 10 | mod large_erase; | ||
| 11 | mod mem_flash; | 10 | mod mem_flash; |
| 12 | mod partition; | 11 | mod partition; |
| 13 | 12 | ||
| @@ -49,7 +48,6 @@ mod tests { | |||
| 49 | use futures::executor::block_on; | 48 | use futures::executor::block_on; |
| 50 | 49 | ||
| 51 | use super::*; | 50 | use super::*; |
| 52 | use crate::large_erase::LargeErase; | ||
| 53 | use crate::mem_flash::MemFlash; | 51 | use crate::mem_flash::MemFlash; |
| 54 | 52 | ||
| 55 | /* | 53 | /* |
| @@ -156,7 +154,7 @@ mod tests { | |||
| 156 | const DFU: Partition = Partition::new(0, 16384); | 154 | const DFU: Partition = Partition::new(0, 16384); |
| 157 | 155 | ||
| 158 | let mut active = MemFlash::<16384, 4096, 8>::random(); | 156 | let mut active = MemFlash::<16384, 4096, 8>::random(); |
| 159 | let mut dfu = LargeErase::<_, 4096>::new(MemFlash::<16384, 2048, 8>::random()); | 157 | let mut dfu = MemFlash::<16384, 2048, 8>::random(); |
| 160 | let mut state = MemFlash::<4096, 128, 4>::random(); | 158 | let mut state = MemFlash::<4096, 128, 4>::random(); |
| 161 | let mut aligned = [0; 4]; | 159 | let mut aligned = [0; 4]; |
| 162 | 160 | ||
| @@ -188,7 +186,7 @@ mod tests { | |||
| 188 | 186 | ||
| 189 | // First DFU page is untouched | 187 | // First DFU page is untouched |
| 190 | for i in DFU.from + 4096..DFU.to { | 188 | for i in DFU.from + 4096..DFU.to { |
| 191 | assert_eq!(dfu.0.mem[i], original[i - DFU.from - 4096], "Index {}", i); | 189 | assert_eq!(dfu.mem[i], original[i - DFU.from - 4096], "Index {}", i); |
| 192 | } | 190 | } |
| 193 | } | 191 | } |
| 194 | 192 | ||
| @@ -200,7 +198,7 @@ mod tests { | |||
| 200 | const DFU: Partition = Partition::new(0, 16384); | 198 | const DFU: Partition = Partition::new(0, 16384); |
| 201 | 199 | ||
| 202 | let mut aligned = [0; 4]; | 200 | let mut aligned = [0; 4]; |
| 203 | let mut active = LargeErase::<_, 4096>::new(MemFlash::<16384, 2048, 4>::random()); | 201 | let mut active = MemFlash::<16384, 2048, 4>::random(); |
| 204 | let mut dfu = MemFlash::<16384, 4096, 8>::random(); | 202 | let mut dfu = MemFlash::<16384, 4096, 8>::random(); |
| 205 | let mut state = MemFlash::<4096, 128, 4>::random(); | 203 | let mut state = MemFlash::<4096, 128, 4>::random(); |
| 206 | 204 | ||
| @@ -208,7 +206,7 @@ mod tests { | |||
| 208 | let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()]; | 206 | let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()]; |
| 209 | 207 | ||
| 210 | for i in ACTIVE.from..ACTIVE.to { | 208 | for i in ACTIVE.from..ACTIVE.to { |
| 211 | active.0.mem[i] = original[i - ACTIVE.from]; | 209 | active.mem[i] = original[i - ACTIVE.from]; |
| 212 | } | 210 | } |
| 213 | 211 | ||
| 214 | let mut updater = FirmwareUpdater::new(DFU, STATE); | 212 | let mut updater = FirmwareUpdater::new(DFU, STATE); |
| @@ -229,7 +227,7 @@ mod tests { | |||
| 229 | ); | 227 | ); |
| 230 | 228 | ||
| 231 | for i in ACTIVE.from..ACTIVE.to { | 229 | for i in ACTIVE.from..ACTIVE.to { |
| 232 | assert_eq!(active.0.mem[i], update[i - ACTIVE.from], "Index {}", i); | 230 | assert_eq!(active.mem[i], update[i - ACTIVE.from], "Index {}", i); |
| 233 | } | 231 | } |
| 234 | 232 | ||
| 235 | // First DFU page is untouched | 233 | // First DFU page is untouched |
