aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-04-03 15:33:20 +0200
committerRasmus Melchior Jacobsen <[email protected]>2023-04-03 15:33:20 +0200
commit7c11d85e1ea0d01e5e1b4d6564d258663d66509b (patch)
tree861eef5f9485c7fe2c775a2a28d9366d5efb5928
parent0909a6cd3ff6fb953aa2d83fb5da37384ad7dae2 (diff)
Move MemFlash to separate module and add verify_erased_before_write verification
-rw-r--r--embassy-boot/boot/src/lib.rs155
-rw-r--r--embassy-boot/boot/src/mem_flash.rs213
-rw-r--r--embassy-boot/boot/src/partition.rs18
3 files changed, 244 insertions, 142 deletions
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs
index 4c28d7aa4..a5795781f 100644
--- a/embassy-boot/boot/src/lib.rs
+++ b/embassy-boot/boot/src/lib.rs
@@ -8,6 +8,7 @@ mod fmt;
8mod boot_loader; 8mod boot_loader;
9mod firmware_updater; 9mod firmware_updater;
10mod firmware_writer; 10mod firmware_writer;
11mod mem_flash;
11mod partition; 12mod partition;
12 13
13pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig}; 14pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig};
@@ -46,13 +47,10 @@ impl<const N: usize> AsMut<[u8]> for AlignedBuffer<N> {
46 47
47#[cfg(test)] 48#[cfg(test)]
48mod tests { 49mod tests {
49 use core::convert::Infallible;
50
51 use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
52 use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
53 use futures::executor::block_on; 50 use futures::executor::block_on;
54 51
55 use super::*; 52 use super::*;
53 use crate::mem_flash::MemFlash;
56 54
57 /* 55 /*
58 #[test] 56 #[test]
@@ -75,8 +73,8 @@ mod tests {
75 const ACTIVE: Partition = Partition::new(4096, 61440); 73 const ACTIVE: Partition = Partition::new(4096, 61440);
76 const DFU: Partition = Partition::new(61440, 122880); 74 const DFU: Partition = Partition::new(61440, 122880);
77 75
78 let mut flash = MemFlash::<131072, 4096, 4>([0xff; 131072]); 76 let mut flash = MemFlash::<131072, 4096, 4>::default();
79 flash.0[0..4].copy_from_slice(&[BOOT_MAGIC; 4]); 77 flash.mem[0..4].copy_from_slice(&[BOOT_MAGIC; 4]);
80 let mut flash = SingleFlashConfig::new(&mut flash); 78 let mut flash = SingleFlashConfig::new(&mut flash);
81 79
82 let mut bootloader: BootLoader = BootLoader::new(ACTIVE, DFU, STATE); 80 let mut bootloader: BootLoader = BootLoader::new(ACTIVE, DFU, STATE);
@@ -95,14 +93,14 @@ mod tests {
95 const STATE: Partition = Partition::new(0, 4096); 93 const STATE: Partition = Partition::new(0, 4096);
96 const ACTIVE: Partition = Partition::new(4096, 61440); 94 const ACTIVE: Partition = Partition::new(4096, 61440);
97 const DFU: Partition = Partition::new(61440, 122880); 95 const DFU: Partition = Partition::new(61440, 122880);
98 let mut flash = MemFlash::<131072, 4096, 4>([0xff; 131072]); 96 let mut flash = MemFlash::<131072, 4096, 4>::random().with_limited_erase_before_write_verification(4..);
99 97
100 let original: [u8; ACTIVE.len()] = [rand::random::<u8>(); ACTIVE.len()]; 98 let original: [u8; ACTIVE.len()] = [rand::random::<u8>(); ACTIVE.len()];
101 let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()]; 99 let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()];
102 let mut aligned = [0; 4]; 100 let mut aligned = [0; 4];
103 101
104 for i in ACTIVE.from..ACTIVE.to { 102 for i in ACTIVE.from..ACTIVE.to {
105 flash.0[i] = original[i - ACTIVE.from]; 103 flash.mem[i] = original[i - ACTIVE.from];
106 } 104 }
107 105
108 let mut bootloader: BootLoader = BootLoader::new(ACTIVE, DFU, STATE); 106 let mut bootloader: BootLoader = BootLoader::new(ACTIVE, DFU, STATE);
@@ -124,12 +122,12 @@ mod tests {
124 ); 122 );
125 123
126 for i in ACTIVE.from..ACTIVE.to { 124 for i in ACTIVE.from..ACTIVE.to {
127 assert_eq!(flash.0[i], update[i - ACTIVE.from], "Index {}", i); 125 assert_eq!(flash.mem[i], update[i - ACTIVE.from], "Index {}", i);
128 } 126 }
129 127
130 // First DFU page is untouched 128 // First DFU page is untouched
131 for i in DFU.from + 4096..DFU.to { 129 for i in DFU.from + 4096..DFU.to {
132 assert_eq!(flash.0[i], original[i - DFU.from - 4096], "Index {}", i); 130 assert_eq!(flash.mem[i], original[i - DFU.from - 4096], "Index {}", i);
133 } 131 }
134 132
135 // Running again should cause a revert 133 // Running again should cause a revert
@@ -141,12 +139,12 @@ mod tests {
141 ); 139 );
142 140
143 for i in ACTIVE.from..ACTIVE.to { 141 for i in ACTIVE.from..ACTIVE.to {
144 assert_eq!(flash.0[i], original[i - ACTIVE.from], "Index {}", i); 142 assert_eq!(flash.mem[i], original[i - ACTIVE.from], "Index {}", i);
145 } 143 }
146 144
147 // Last page is untouched 145 // Last page is untouched
148 for i in DFU.from..DFU.to - 4096 { 146 for i in DFU.from..DFU.to - 4096 {
149 assert_eq!(flash.0[i], update[i - DFU.from], "Index {}", i); 147 assert_eq!(flash.mem[i], update[i - DFU.from], "Index {}", i);
150 } 148 }
151 149
152 // Mark as booted 150 // Mark as booted
@@ -166,16 +164,16 @@ mod tests {
166 const ACTIVE: Partition = Partition::new(4096, 16384); 164 const ACTIVE: Partition = Partition::new(4096, 16384);
167 const DFU: Partition = Partition::new(0, 16384); 165 const DFU: Partition = Partition::new(0, 16384);
168 166
169 let mut active = MemFlash::<16384, 4096, 8>([0xff; 16384]); 167 let mut active = MemFlash::<16384, 4096, 8>::random();
170 let mut dfu = MemFlash::<16384, 2048, 8>([0xff; 16384]); 168 let mut dfu = MemFlash::<16384, 2048, 8>::random();
171 let mut state = MemFlash::<4096, 128, 4>([0xff; 4096]); 169 let mut state = MemFlash::<4096, 128, 4>::random().with_limited_erase_before_write_verification(2048 + 4..);
172 let mut aligned = [0; 4]; 170 let mut aligned = [0; 4];
173 171
174 let original: [u8; ACTIVE.len()] = [rand::random::<u8>(); ACTIVE.len()]; 172 let original: [u8; ACTIVE.len()] = [rand::random::<u8>(); ACTIVE.len()];
175 let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()]; 173 let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()];
176 174
177 for i in ACTIVE.from..ACTIVE.to { 175 for i in ACTIVE.from..ACTIVE.to {
178 active.0[i] = original[i - ACTIVE.from]; 176 active.mem[i] = original[i - ACTIVE.from];
179 } 177 }
180 178
181 let mut updater = FirmwareUpdater::new(DFU, STATE); 179 let mut updater = FirmwareUpdater::new(DFU, STATE);
@@ -203,12 +201,12 @@ mod tests {
203 ); 201 );
204 202
205 for i in ACTIVE.from..ACTIVE.to { 203 for i in ACTIVE.from..ACTIVE.to {
206 assert_eq!(active.0[i], update[i - ACTIVE.from], "Index {}", i); 204 assert_eq!(active.mem[i], update[i - ACTIVE.from], "Index {}", i);
207 } 205 }
208 206
209 // First DFU page is untouched 207 // First DFU page is untouched
210 for i in DFU.from + 4096..DFU.to { 208 for i in DFU.from + 4096..DFU.to {
211 assert_eq!(dfu.0[i], original[i - DFU.from - 4096], "Index {}", i); 209 assert_eq!(dfu.mem[i], original[i - DFU.from - 4096], "Index {}", i);
212 } 210 }
213 } 211 }
214 212
@@ -220,15 +218,15 @@ mod tests {
220 const DFU: Partition = Partition::new(0, 16384); 218 const DFU: Partition = Partition::new(0, 16384);
221 219
222 let mut aligned = [0; 4]; 220 let mut aligned = [0; 4];
223 let mut active = MemFlash::<16384, 2048, 4>([0xff; 16384]); 221 let mut active = MemFlash::<16384, 2048, 4>::random();
224 let mut dfu = MemFlash::<16384, 4096, 8>([0xff; 16384]); 222 let mut dfu = MemFlash::<16384, 4096, 8>::random();
225 let mut state = MemFlash::<4096, 128, 4>([0xff; 4096]); 223 let mut state = MemFlash::<4096, 128, 4>::random().with_limited_erase_before_write_verification(2048 + 4..);
226 224
227 let original: [u8; ACTIVE.len()] = [rand::random::<u8>(); ACTIVE.len()]; 225 let original: [u8; ACTIVE.len()] = [rand::random::<u8>(); ACTIVE.len()];
228 let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()]; 226 let update: [u8; DFU.len()] = [rand::random::<u8>(); DFU.len()];
229 227
230 for i in ACTIVE.from..ACTIVE.to { 228 for i in ACTIVE.from..ACTIVE.to {
231 active.0[i] = original[i - ACTIVE.from]; 229 active.mem[i] = original[i - ACTIVE.from];
232 } 230 }
233 231
234 let mut updater = FirmwareUpdater::new(DFU, STATE); 232 let mut updater = FirmwareUpdater::new(DFU, STATE);
@@ -255,12 +253,12 @@ mod tests {
255 ); 253 );
256 254
257 for i in ACTIVE.from..ACTIVE.to { 255 for i in ACTIVE.from..ACTIVE.to {
258 assert_eq!(active.0[i], update[i - ACTIVE.from], "Index {}", i); 256 assert_eq!(active.mem[i], update[i - ACTIVE.from], "Index {}", i);
259 } 257 }
260 258
261 // First DFU page is untouched 259 // First DFU page is untouched
262 for i in DFU.from + 4096..DFU.to { 260 for i in DFU.from + 4096..DFU.to {
263 assert_eq!(dfu.0[i], original[i - DFU.from - 4096], "Index {}", i); 261 assert_eq!(dfu.mem[i], original[i - DFU.from - 4096], "Index {}", i);
264 } 262 }
265 } 263 }
266 264
@@ -313,113 +311,4 @@ mod tests {
313 )) 311 ))
314 .is_ok()); 312 .is_ok());
315 } 313 }
316
317 pub struct MemFlash<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize>(pub [u8; SIZE]);
318
319 impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> NorFlash
320 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
321 {
322 const WRITE_SIZE: usize = WRITE_SIZE;
323 const ERASE_SIZE: usize = ERASE_SIZE;
324 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
325 let from = from as usize;
326 let to = to as usize;
327 assert!(from % ERASE_SIZE == 0);
328 assert!(to % ERASE_SIZE == 0, "To: {}, erase size: {}", to, ERASE_SIZE);
329 for i in from..to {
330 self.0[i] = 0xFF;
331 }
332 Ok(())
333 }
334
335 fn write(&mut self, offset: u32, data: &[u8]) -> Result<(), Self::Error> {
336 assert!(data.len() % WRITE_SIZE == 0);
337 assert!(offset as usize % WRITE_SIZE == 0);
338 assert!(offset as usize + data.len() <= SIZE);
339
340 self.0[offset as usize..offset as usize + data.len()].copy_from_slice(data);
341
342 Ok(())
343 }
344 }
345
346 impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> ErrorType
347 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
348 {
349 type Error = Infallible;
350 }
351
352 impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> ReadNorFlash
353 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
354 {
355 const READ_SIZE: usize = 1;
356
357 fn read(&mut self, offset: u32, buf: &mut [u8]) -> Result<(), Self::Error> {
358 let len = buf.len();
359 buf[..].copy_from_slice(&self.0[offset as usize..offset as usize + len]);
360 Ok(())
361 }
362
363 fn capacity(&self) -> usize {
364 SIZE
365 }
366 }
367
368 impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> super::Flash
369 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
370 {
371 const BLOCK_SIZE: usize = ERASE_SIZE;
372 const ERASE_VALUE: u8 = 0xFF;
373 }
374
375 impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncReadNorFlash
376 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
377 {
378 const READ_SIZE: usize = 1;
379
380 async fn read(&mut self, offset: u32, buf: &mut [u8]) -> Result<(), Self::Error> {
381 let len = buf.len();
382 buf[..].copy_from_slice(&self.0[offset as usize..offset as usize + len]);
383 Ok(())
384 }
385
386 fn capacity(&self) -> usize {
387 SIZE
388 }
389 }
390
391 impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncNorFlash
392 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
393 {
394 const WRITE_SIZE: usize = WRITE_SIZE;
395 const ERASE_SIZE: usize = ERASE_SIZE;
396
397 async fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
398 let from = from as usize;
399 let to = to as usize;
400 assert!(from % ERASE_SIZE == 0);
401 assert!(to % ERASE_SIZE == 0);
402 for i in from..to {
403 self.0[i] = 0xFF;
404 }
405 Ok(())
406 }
407
408 async fn write(&mut self, offset: u32, data: &[u8]) -> Result<(), Self::Error> {
409 info!("Writing {} bytes to 0x{:x}", data.len(), offset);
410 assert!(data.len() % WRITE_SIZE == 0);
411 assert!(offset as usize % WRITE_SIZE == 0);
412 assert!(
413 offset as usize + data.len() <= SIZE,
414 "OFFSET: {}, LEN: {}, FLASH SIZE: {}",
415 offset,
416 data.len(),
417 SIZE
418 );
419
420 self.0[offset as usize..offset as usize + data.len()].copy_from_slice(data);
421
422 Ok(())
423 }
424 }
425} 314}
diff --git a/embassy-boot/boot/src/mem_flash.rs b/embassy-boot/boot/src/mem_flash.rs
new file mode 100644
index 000000000..e87ccd37a
--- /dev/null
+++ b/embassy-boot/boot/src/mem_flash.rs
@@ -0,0 +1,213 @@
1#![allow(unused)]
2
3use core::ops::{Bound, Range, RangeBounds};
4
5use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
6use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash};
7
8use crate::Flash;
9
10pub struct MemFlash<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> {
11 pub mem: [u8; SIZE],
12 pub allow_same_write: bool,
13 pub verify_erased_before_write: Range<usize>,
14 pub pending_write_successes: Option<usize>,
15}
16
17#[derive(Debug)]
18pub struct MemFlashError;
19
20impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE> {
21 pub const fn new(fill: u8) -> Self {
22 Self {
23 mem: [fill; SIZE],
24 allow_same_write: false,
25 verify_erased_before_write: 0..SIZE,
26 pending_write_successes: None,
27 }
28 }
29
30 #[cfg(test)]
31 pub fn random() -> Self {
32 let mut mem = [0; SIZE];
33 for byte in mem.iter_mut() {
34 *byte = rand::random::<u8>();
35 }
36 Self {
37 mem,
38 allow_same_write: false,
39 verify_erased_before_write: 0..SIZE,
40 pending_write_successes: None,
41 }
42 }
43
44 #[must_use]
45 pub fn allow_same_write(self, allow: bool) -> Self {
46 Self {
47 allow_same_write: allow,
48 ..self
49 }
50 }
51
52 #[must_use]
53 pub fn with_limited_erase_before_write_verification<R: RangeBounds<usize>>(self, verified_range: R) -> Self {
54 let start = match verified_range.start_bound() {
55 Bound::Included(start) => *start,
56 Bound::Excluded(start) => *start + 1,
57 Bound::Unbounded => 0,
58 };
59 let end = match verified_range.end_bound() {
60 Bound::Included(end) => *end - 1,
61 Bound::Excluded(end) => *end,
62 Bound::Unbounded => self.mem.len(),
63 };
64 Self {
65 verify_erased_before_write: start..end,
66 ..self
67 }
68 }
69}
70
71impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> Default
72 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
73{
74 fn default() -> Self {
75 Self::new(0xFF)
76 }
77}
78
79impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> Flash
80 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
81{
82 const BLOCK_SIZE: usize = ERASE_SIZE;
83 const ERASE_VALUE: u8 = 0xFF;
84}
85
86impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> ErrorType
87 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
88{
89 type Error = MemFlashError;
90}
91
92impl NorFlashError for MemFlashError {
93 fn kind(&self) -> NorFlashErrorKind {
94 NorFlashErrorKind::Other
95 }
96}
97
98impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> ReadNorFlash
99 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
100{
101 const READ_SIZE: usize = 1;
102
103 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
104 let len = bytes.len();
105 bytes.copy_from_slice(&self.mem[offset as usize..offset as usize + len]);
106 Ok(())
107 }
108
109 fn capacity(&self) -> usize {
110 SIZE
111 }
112}
113
114impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> NorFlash
115 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
116{
117 const WRITE_SIZE: usize = WRITE_SIZE;
118 const ERASE_SIZE: usize = ERASE_SIZE;
119
120 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
121 let from = from as usize;
122 let to = to as usize;
123 assert!(from % ERASE_SIZE == 0);
124 assert!(to % ERASE_SIZE == 0, "To: {}, erase size: {}", to, ERASE_SIZE);
125 for i in from..to {
126 self.mem[i] = 0xFF;
127 }
128 Ok(())
129 }
130
131 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
132 let offset = offset as usize;
133 assert!(bytes.len() % WRITE_SIZE == 0);
134 assert!(offset % WRITE_SIZE == 0);
135 assert!(offset + bytes.len() <= SIZE);
136
137 if let Some(pending_successes) = self.pending_write_successes {
138 if pending_successes > 0 {
139 self.pending_write_successes = Some(pending_successes - 1);
140 } else {
141 return Err(MemFlashError);
142 }
143 }
144
145 for ((offset, mem_byte), new_byte) in self
146 .mem
147 .iter_mut()
148 .enumerate()
149 .skip(offset)
150 .take(bytes.len())
151 .zip(bytes)
152 {
153 if self.allow_same_write && mem_byte == new_byte {
154 // Write does not change the flash memory which is allowed
155 } else {
156 if self.verify_erased_before_write.contains(&offset) {
157 assert_eq!(0xFF, *mem_byte, "Offset {} is not erased", offset);
158 }
159 *mem_byte &= *new_byte;
160 }
161 }
162
163 Ok(())
164 }
165}
166
167impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncReadNorFlash
168 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
169{
170 const READ_SIZE: usize = 1;
171
172 async fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
173 <Self as ReadNorFlash>::read(self, offset, bytes)
174 }
175
176 fn capacity(&self) -> usize {
177 <Self as ReadNorFlash>::capacity(self)
178 }
179}
180
181impl<const SIZE: usize, const ERASE_SIZE: usize, const WRITE_SIZE: usize> AsyncNorFlash
182 for MemFlash<SIZE, ERASE_SIZE, WRITE_SIZE>
183{
184 const WRITE_SIZE: usize = WRITE_SIZE;
185 const ERASE_SIZE: usize = ERASE_SIZE;
186
187 async fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
188 <Self as NorFlash>::erase(self, from, to)
189 }
190
191 async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
192 <Self as NorFlash>::write(self, offset, bytes)
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use core::ops::Range;
199
200 use embedded_storage::nor_flash::NorFlash;
201
202 use super::MemFlash;
203
204 #[test]
205 fn writes_only_flip_bits_from_1_to_0() {
206 let mut flash = MemFlash::<16, 16, 1>::default().with_limited_erase_before_write_verification(0..0);
207
208 flash.write(0, &[0x55]).unwrap();
209 flash.write(0, &[0xAA]).unwrap();
210
211 assert_eq!(0x00, flash.mem[0]);
212 }
213}
diff --git a/embassy-boot/boot/src/partition.rs b/embassy-boot/boot/src/partition.rs
index 3ccd4dd76..1157e8cd8 100644
--- a/embassy-boot/boot/src/partition.rs
+++ b/embassy-boot/boot/src/partition.rs
@@ -105,45 +105,45 @@ impl Partition {
105 105
106#[cfg(test)] 106#[cfg(test)]
107mod tests { 107mod tests {
108 use crate::tests::MemFlash; 108 use crate::mem_flash::MemFlash;
109 use crate::Partition; 109 use crate::Partition;
110 110
111 #[test] 111 #[test]
112 fn can_erase() { 112 fn can_erase() {
113 let mut flash = MemFlash::<1024, 64, 4>([0x00; 1024]); 113 let mut flash = MemFlash::<1024, 64, 4>::new(0x00);
114 let partition = Partition::new(256, 512); 114 let partition = Partition::new(256, 512);
115 115
116 partition.erase_blocking(&mut flash, 64, 192).unwrap(); 116 partition.erase_blocking(&mut flash, 64, 192).unwrap();
117 117
118 for (index, byte) in flash.0.iter().copied().enumerate().take(256 + 64) { 118 for (index, byte) in flash.mem.iter().copied().enumerate().take(256 + 64) {
119 assert_eq!(0x00, byte, "Index {}", index); 119 assert_eq!(0x00, byte, "Index {}", index);
120 } 120 }
121 121
122 for (index, byte) in flash.0.iter().copied().enumerate().skip(256 + 64).take(128) { 122 for (index, byte) in flash.mem.iter().copied().enumerate().skip(256 + 64).take(128) {
123 assert_eq!(0xFF, byte, "Index {}", index); 123 assert_eq!(0xFF, byte, "Index {}", index);
124 } 124 }
125 125
126 for (index, byte) in flash.0.iter().copied().enumerate().skip(256 + 64 + 128) { 126 for (index, byte) in flash.mem.iter().copied().enumerate().skip(256 + 64 + 128) {
127 assert_eq!(0x00, byte, "Index {}", index); 127 assert_eq!(0x00, byte, "Index {}", index);
128 } 128 }
129 } 129 }
130 130
131 #[test] 131 #[test]
132 fn can_wipe() { 132 fn can_wipe() {
133 let mut flash = MemFlash::<1024, 64, 4>([0x00; 1024]); 133 let mut flash = MemFlash::<1024, 64, 4>::new(0x00);
134 let partition = Partition::new(256, 512); 134 let partition = Partition::new(256, 512);
135 135
136 partition.wipe_blocking(&mut flash).unwrap(); 136 partition.wipe_blocking(&mut flash).unwrap();
137 137
138 for (index, byte) in flash.0.iter().copied().enumerate().take(256) { 138 for (index, byte) in flash.mem.iter().copied().enumerate().take(256) {
139 assert_eq!(0x00, byte, "Index {}", index); 139 assert_eq!(0x00, byte, "Index {}", index);
140 } 140 }
141 141
142 for (index, byte) in flash.0.iter().copied().enumerate().skip(256).take(256) { 142 for (index, byte) in flash.mem.iter().copied().enumerate().skip(256).take(256) {
143 assert_eq!(0xFF, byte, "Index {}", index); 143 assert_eq!(0xFF, byte, "Index {}", index);
144 } 144 }
145 145
146 for (index, byte) in flash.0.iter().copied().enumerate().skip(512) { 146 for (index, byte) in flash.mem.iter().copied().enumerate().skip(512) {
147 assert_eq!(0x00, byte, "Index {}", index); 147 assert_eq!(0x00, byte, "Index {}", index);
148 } 148 }
149 } 149 }