aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-04-04 00:33:23 +0000
committerGitHub <[email protected]>2023-04-04 00:33:23 +0000
commit36ad82a52b540eec5e94052b08de8e8e6308f2ce (patch)
treedf3523a56e274b540f15203bb32a2748918431eb
parent117fca84ea6eaa29bd28fe02b5b537e5a925c05f (diff)
parentb1e2195b49129bcccf42121a6f39248bab9e341f (diff)
Merge #1322
1322: Remove FirmwareWriter r=Dirbaio a=rmja FirmwareWriter currently has a "max-write-size" parameter, but this is a limitation that should be handled by chunking inside the NorFlash driver, and not "up here" in user code. In case that the driver (e.g. qspi driver) is unaware of any max-write limitations, one could simply add an intermediate NorFlash adapter providing the chunk'ing capability. Co-authored-by: Rasmus Melchior Jacobsen <[email protected]>
-rw-r--r--embassy-boot/boot/src/firmware_updater.rs25
-rw-r--r--embassy-boot/boot/src/firmware_writer.rs55
-rw-r--r--embassy-boot/boot/src/lib.rs8
3 files changed, 12 insertions, 76 deletions
diff --git a/embassy-boot/boot/src/firmware_updater.rs b/embassy-boot/boot/src/firmware_updater.rs
index af1ba114a..dd22b2fa7 100644
--- a/embassy-boot/boot/src/firmware_updater.rs
+++ b/embassy-boot/boot/src/firmware_updater.rs
@@ -1,7 +1,7 @@
1use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind}; 1use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind};
2use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash; 2use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
3 3
4use crate::{FirmwareWriter, Partition, State, BOOT_MAGIC, SWAP_MAGIC}; 4use crate::{Partition, State, BOOT_MAGIC, SWAP_MAGIC};
5 5
6/// Errors returned by FirmwareUpdater 6/// Errors returned by FirmwareUpdater
7#[derive(Debug)] 7#[derive(Debug)]
@@ -243,7 +243,6 @@ impl FirmwareUpdater {
243 offset: usize, 243 offset: usize,
244 data: &[u8], 244 data: &[u8],
245 dfu_flash: &mut F, 245 dfu_flash: &mut F,
246 block_size: usize,
247 ) -> Result<(), FirmwareUpdaterError> { 246 ) -> Result<(), FirmwareUpdaterError> {
248 assert!(data.len() >= F::ERASE_SIZE); 247 assert!(data.len() >= F::ERASE_SIZE);
249 248
@@ -251,25 +250,23 @@ impl FirmwareUpdater {
251 .erase(dfu_flash, offset as u32, (offset + data.len()) as u32) 250 .erase(dfu_flash, offset as u32, (offset + data.len()) as u32)
252 .await?; 251 .await?;
253 252
254 FirmwareWriter(self.dfu) 253 self.dfu.write(dfu_flash, offset as u32, data).await?;
255 .write_block(offset, data, dfu_flash, block_size)
256 .await?;
257 254
258 Ok(()) 255 Ok(())
259 } 256 }
260 257
261 /// Prepare for an incoming DFU update by erasing the entire DFU area and 258 /// Prepare for an incoming DFU update by erasing the entire DFU area and
262 /// returning a `FirmwareWriter`. 259 /// returning its `Partition`.
263 /// 260 ///
264 /// Using this instead of `write_firmware` allows for an optimized API in 261 /// Using this instead of `write_firmware` allows for an optimized API in
265 /// exchange for added complexity. 262 /// exchange for added complexity.
266 pub async fn prepare_update<F: AsyncNorFlash>( 263 pub async fn prepare_update<F: AsyncNorFlash>(
267 &mut self, 264 &mut self,
268 dfu_flash: &mut F, 265 dfu_flash: &mut F,
269 ) -> Result<FirmwareWriter, FirmwareUpdaterError> { 266 ) -> Result<Partition, FirmwareUpdaterError> {
270 self.dfu.wipe(dfu_flash).await?; 267 self.dfu.wipe(dfu_flash).await?;
271 268
272 Ok(FirmwareWriter(self.dfu)) 269 Ok(self.dfu)
273 } 270 }
274 271
275 // 272 //
@@ -443,29 +440,25 @@ impl FirmwareUpdater {
443 offset: usize, 440 offset: usize,
444 data: &[u8], 441 data: &[u8],
445 dfu_flash: &mut F, 442 dfu_flash: &mut F,
446 block_size: usize,
447 ) -> Result<(), FirmwareUpdaterError> { 443 ) -> Result<(), FirmwareUpdaterError> {
448 assert!(data.len() >= F::ERASE_SIZE); 444 assert!(data.len() >= F::ERASE_SIZE);
449 445
450 self.dfu 446 self.dfu
451 .erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?; 447 .erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?;
452 448
453 FirmwareWriter(self.dfu).write_block_blocking(offset, data, dfu_flash, block_size)?; 449 self.dfu.write_blocking(dfu_flash, offset as u32, data)?;
454 450
455 Ok(()) 451 Ok(())
456 } 452 }
457 453
458 /// Prepare for an incoming DFU update by erasing the entire DFU area and 454 /// Prepare for an incoming DFU update by erasing the entire DFU area and
459 /// returning a `FirmwareWriter`. 455 /// returning its `Partition`.
460 /// 456 ///
461 /// Using this instead of `write_firmware_blocking` allows for an optimized 457 /// Using this instead of `write_firmware_blocking` allows for an optimized
462 /// API in exchange for added complexity. 458 /// API in exchange for added complexity.
463 pub fn prepare_update_blocking<F: NorFlash>( 459 pub fn prepare_update_blocking<F: NorFlash>(&mut self, flash: &mut F) -> Result<Partition, FirmwareUpdaterError> {
464 &mut self,
465 flash: &mut F,
466 ) -> Result<FirmwareWriter, FirmwareUpdaterError> {
467 self.dfu.wipe_blocking(flash)?; 460 self.dfu.wipe_blocking(flash)?;
468 461
469 Ok(FirmwareWriter(self.dfu)) 462 Ok(self.dfu)
470 } 463 }
471} 464}
diff --git a/embassy-boot/boot/src/firmware_writer.rs b/embassy-boot/boot/src/firmware_writer.rs
deleted file mode 100644
index 46079e731..000000000
--- a/embassy-boot/boot/src/firmware_writer.rs
+++ /dev/null
@@ -1,55 +0,0 @@
1use embedded_storage::nor_flash::NorFlash;
2use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
3
4use crate::Partition;
5
6/// FirmwareWriter allows writing blocks to an already erased flash.
7pub struct FirmwareWriter(pub(crate) Partition);
8
9impl FirmwareWriter {
10 /// Write data to a flash page.
11 ///
12 /// The buffer must follow alignment requirements of the target flash and a multiple of page size big.
13 ///
14 /// # Safety
15 ///
16 /// Failing to meet alignment and size requirements may result in a panic.
17 pub async fn write_block<F: AsyncNorFlash>(
18 &mut self,
19 offset: usize,
20 data: &[u8],
21 flash: &mut F,
22 block_size: usize,
23 ) -> Result<(), F::Error> {
24 let mut offset = offset as u32;
25 for chunk in data.chunks(block_size) {
26 self.0.write(flash, offset, chunk).await?;
27 offset += chunk.len() as u32;
28 }
29
30 Ok(())
31 }
32
33 /// Write data to a flash page.
34 ///
35 /// The buffer must follow alignment requirements of the target flash and a multiple of page size big.
36 ///
37 /// # Safety
38 ///
39 /// Failing to meet alignment and size requirements may result in a panic.
40 pub fn write_block_blocking<F: NorFlash>(
41 &mut self,
42 offset: usize,
43 data: &[u8],
44 flash: &mut F,
45 block_size: usize,
46 ) -> Result<(), F::Error> {
47 let mut offset = offset as u32;
48 for chunk in data.chunks(block_size) {
49 self.0.write_blocking(flash, offset, chunk)?;
50 offset += chunk.len() as u32;
51 }
52
53 Ok(())
54 }
55}
diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs
index 4c28d7aa4..428e7ca2b 100644
--- a/embassy-boot/boot/src/lib.rs
+++ b/embassy-boot/boot/src/lib.rs
@@ -7,12 +7,10 @@ mod fmt;
7 7
8mod boot_loader; 8mod boot_loader;
9mod firmware_updater; 9mod firmware_updater;
10mod firmware_writer;
11mod partition; 10mod partition;
12 11
13pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig}; 12pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig};
14pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError}; 13pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError};
15pub use firmware_writer::FirmwareWriter;
16pub use partition::Partition; 14pub use partition::Partition;
17 15
18pub(crate) const BOOT_MAGIC: u8 = 0xD0; 16pub(crate) const BOOT_MAGIC: u8 = 0xD0;
@@ -109,7 +107,7 @@ mod tests {
109 let mut updater = FirmwareUpdater::new(DFU, STATE); 107 let mut updater = FirmwareUpdater::new(DFU, STATE);
110 let mut offset = 0; 108 let mut offset = 0;
111 for chunk in update.chunks(4096) { 109 for chunk in update.chunks(4096) {
112 block_on(updater.write_firmware(offset, chunk, &mut flash, 4096)).unwrap(); 110 block_on(updater.write_firmware(offset, chunk, &mut flash)).unwrap();
113 offset += chunk.len(); 111 offset += chunk.len();
114 } 112 }
115 block_on(updater.mark_updated(&mut flash, &mut aligned)).unwrap(); 113 block_on(updater.mark_updated(&mut flash, &mut aligned)).unwrap();
@@ -182,7 +180,7 @@ mod tests {
182 180
183 let mut offset = 0; 181 let mut offset = 0;
184 for chunk in update.chunks(2048) { 182 for chunk in update.chunks(2048) {
185 block_on(updater.write_firmware(offset, chunk, &mut dfu, chunk.len())).unwrap(); 183 block_on(updater.write_firmware(offset, chunk, &mut dfu)).unwrap();
186 offset += chunk.len(); 184 offset += chunk.len();
187 } 185 }
188 block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap(); 186 block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap();
@@ -235,7 +233,7 @@ mod tests {
235 233
236 let mut offset = 0; 234 let mut offset = 0;
237 for chunk in update.chunks(4096) { 235 for chunk in update.chunks(4096) {
238 block_on(updater.write_firmware(offset, chunk, &mut dfu, chunk.len())).unwrap(); 236 block_on(updater.write_firmware(offset, chunk, &mut dfu)).unwrap();
239 offset += chunk.len(); 237 offset += chunk.len();
240 } 238 }
241 block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap(); 239 block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap();