diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2023-04-03 11:49:44 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-04-03 11:49:44 +0000 |
| commit | 0909a6cd3ff6fb953aa2d83fb5da37384ad7dae2 (patch) | |
| tree | a040bd60916068140f86a773ff952a0d128c12ed /embassy-boot/boot/src/partition.rs | |
| parent | 08f911d25e83266b03bd1ebd37eee50cf2c53dd4 (diff) | |
| parent | d9d6fd6d70f3f9971c6db65b6962199f9da7913c (diff) | |
Merge #1312
1312: Let bootloader partition have read/write/erase operations r=Dirbaio a=rmja
This change should not have any breaking changes.
Co-authored-by: Rasmus Melchior Jacobsen <[email protected]>
Diffstat (limited to 'embassy-boot/boot/src/partition.rs')
| -rw-r--r-- | embassy-boot/boot/src/partition.rs | 134 |
1 files changed, 131 insertions, 3 deletions
diff --git a/embassy-boot/boot/src/partition.rs b/embassy-boot/boot/src/partition.rs index 46f80a23c..3ccd4dd76 100644 --- a/embassy-boot/boot/src/partition.rs +++ b/embassy-boot/boot/src/partition.rs | |||
| @@ -1,10 +1,13 @@ | |||
| 1 | use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; | ||
| 2 | use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash}; | ||
| 3 | |||
| 1 | /// A region in flash used by the bootloader. | 4 | /// A region in flash used by the bootloader. |
| 2 | #[derive(Copy, Clone, Debug)] | 5 | #[derive(Copy, Clone, Debug)] |
| 3 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 6 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 4 | pub struct Partition { | 7 | pub struct Partition { |
| 5 | /// Start of the flash region. | 8 | /// The offset into the flash where the partition starts. |
| 6 | pub from: usize, | 9 | pub from: usize, |
| 7 | /// End of the flash region. | 10 | /// The offset into the flash where the partition ends. |
| 8 | pub to: usize, | 11 | pub to: usize, |
| 9 | } | 12 | } |
| 10 | 13 | ||
| @@ -14,9 +17,134 @@ impl Partition { | |||
| 14 | Self { from, to } | 17 | Self { from, to } |
| 15 | } | 18 | } |
| 16 | 19 | ||
| 17 | /// Return the length of the partition | 20 | /// Return the size of the partition |
| 18 | #[allow(clippy::len_without_is_empty)] | 21 | #[allow(clippy::len_without_is_empty)] |
| 19 | pub const fn len(&self) -> usize { | 22 | pub const fn len(&self) -> usize { |
| 20 | self.to - self.from | 23 | self.to - self.from |
| 21 | } | 24 | } |
| 25 | |||
| 26 | /// Read from the partition on the provided flash | ||
| 27 | pub(crate) async fn read<F: AsyncReadNorFlash>( | ||
| 28 | &self, | ||
| 29 | flash: &mut F, | ||
| 30 | offset: u32, | ||
| 31 | bytes: &mut [u8], | ||
| 32 | ) -> Result<(), F::Error> { | ||
| 33 | let offset = self.from as u32 + offset; | ||
| 34 | flash.read(offset, bytes).await | ||
| 35 | } | ||
| 36 | |||
| 37 | /// Write to the partition on the provided flash | ||
| 38 | pub(crate) async fn write<F: AsyncNorFlash>( | ||
| 39 | &self, | ||
| 40 | flash: &mut F, | ||
| 41 | offset: u32, | ||
| 42 | bytes: &[u8], | ||
| 43 | ) -> Result<(), F::Error> { | ||
| 44 | let offset = self.from as u32 + offset; | ||
| 45 | flash.write(offset, bytes).await?; | ||
| 46 | trace!("Wrote from 0x{:x} len {}", offset, bytes.len()); | ||
| 47 | Ok(()) | ||
| 48 | } | ||
| 49 | |||
| 50 | /// Erase part of the partition on the provided flash | ||
| 51 | pub(crate) async fn erase<F: AsyncNorFlash>(&self, flash: &mut F, from: u32, to: u32) -> Result<(), F::Error> { | ||
| 52 | let from = self.from as u32 + from; | ||
| 53 | let to = self.from as u32 + to; | ||
| 54 | flash.erase(from, to).await?; | ||
| 55 | trace!("Erased from 0x{:x} to 0x{:x}", from, to); | ||
| 56 | Ok(()) | ||
| 57 | } | ||
| 58 | |||
| 59 | /// Erase the entire partition | ||
| 60 | pub(crate) async fn wipe<F: AsyncNorFlash>(&self, flash: &mut F) -> Result<(), F::Error> { | ||
| 61 | let from = self.from as u32; | ||
| 62 | let to = self.to as u32; | ||
| 63 | flash.erase(from, to).await?; | ||
| 64 | trace!("Wiped from 0x{:x} to 0x{:x}", from, to); | ||
| 65 | Ok(()) | ||
| 66 | } | ||
| 67 | |||
| 68 | /// Read from the partition on the provided flash | ||
| 69 | pub(crate) fn read_blocking<F: ReadNorFlash>( | ||
| 70 | &self, | ||
| 71 | flash: &mut F, | ||
| 72 | offset: u32, | ||
| 73 | bytes: &mut [u8], | ||
| 74 | ) -> Result<(), F::Error> { | ||
| 75 | let offset = self.from as u32 + offset; | ||
| 76 | flash.read(offset, bytes) | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Write to the partition on the provided flash | ||
| 80 | pub(crate) fn write_blocking<F: NorFlash>(&self, flash: &mut F, offset: u32, bytes: &[u8]) -> Result<(), F::Error> { | ||
| 81 | let offset = self.from as u32 + offset; | ||
| 82 | flash.write(offset, bytes)?; | ||
| 83 | trace!("Wrote from 0x{:x} len {}", offset, bytes.len()); | ||
| 84 | Ok(()) | ||
| 85 | } | ||
| 86 | |||
| 87 | /// Erase part of the partition on the provided flash | ||
| 88 | pub(crate) fn erase_blocking<F: NorFlash>(&self, flash: &mut F, from: u32, to: u32) -> Result<(), F::Error> { | ||
| 89 | let from = self.from as u32 + from; | ||
| 90 | let to = self.from as u32 + to; | ||
| 91 | flash.erase(from, to)?; | ||
| 92 | trace!("Erased from 0x{:x} to 0x{:x}", from, to); | ||
| 93 | Ok(()) | ||
| 94 | } | ||
| 95 | |||
| 96 | /// Erase the entire partition | ||
| 97 | pub(crate) fn wipe_blocking<F: NorFlash>(&self, flash: &mut F) -> Result<(), F::Error> { | ||
| 98 | let from = self.from as u32; | ||
| 99 | let to = self.to as u32; | ||
| 100 | flash.erase(from, to)?; | ||
| 101 | trace!("Wiped from 0x{:x} to 0x{:x}", from, to); | ||
| 102 | Ok(()) | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | #[cfg(test)] | ||
| 107 | mod tests { | ||
| 108 | use crate::tests::MemFlash; | ||
| 109 | use crate::Partition; | ||
| 110 | |||
| 111 | #[test] | ||
| 112 | fn can_erase() { | ||
| 113 | let mut flash = MemFlash::<1024, 64, 4>([0x00; 1024]); | ||
| 114 | let partition = Partition::new(256, 512); | ||
| 115 | |||
| 116 | partition.erase_blocking(&mut flash, 64, 192).unwrap(); | ||
| 117 | |||
| 118 | for (index, byte) in flash.0.iter().copied().enumerate().take(256 + 64) { | ||
| 119 | assert_eq!(0x00, byte, "Index {}", index); | ||
| 120 | } | ||
| 121 | |||
| 122 | for (index, byte) in flash.0.iter().copied().enumerate().skip(256 + 64).take(128) { | ||
| 123 | assert_eq!(0xFF, byte, "Index {}", index); | ||
| 124 | } | ||
| 125 | |||
| 126 | for (index, byte) in flash.0.iter().copied().enumerate().skip(256 + 64 + 128) { | ||
| 127 | assert_eq!(0x00, byte, "Index {}", index); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 131 | #[test] | ||
| 132 | fn can_wipe() { | ||
| 133 | let mut flash = MemFlash::<1024, 64, 4>([0x00; 1024]); | ||
| 134 | let partition = Partition::new(256, 512); | ||
| 135 | |||
| 136 | partition.wipe_blocking(&mut flash).unwrap(); | ||
| 137 | |||
| 138 | for (index, byte) in flash.0.iter().copied().enumerate().take(256) { | ||
| 139 | assert_eq!(0x00, byte, "Index {}", index); | ||
| 140 | } | ||
| 141 | |||
| 142 | for (index, byte) in flash.0.iter().copied().enumerate().skip(256).take(256) { | ||
| 143 | assert_eq!(0xFF, byte, "Index {}", index); | ||
| 144 | } | ||
| 145 | |||
| 146 | for (index, byte) in flash.0.iter().copied().enumerate().skip(512) { | ||
| 147 | assert_eq!(0x00, byte, "Index {}", index); | ||
| 148 | } | ||
| 149 | } | ||
| 22 | } | 150 | } |
