aboutsummaryrefslogtreecommitdiff
path: root/embassy-boot/boot/src/partition.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-04-03 11:49:44 +0000
committerGitHub <[email protected]>2023-04-03 11:49:44 +0000
commit0909a6cd3ff6fb953aa2d83fb5da37384ad7dae2 (patch)
treea040bd60916068140f86a773ff952a0d128c12ed /embassy-boot/boot/src/partition.rs
parent08f911d25e83266b03bd1ebd37eee50cf2c53dd4 (diff)
parentd9d6fd6d70f3f9971c6db65b6962199f9da7913c (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.rs134
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 @@
1use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
2use 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))]
4pub struct Partition { 7pub 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)]
107mod 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}