aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();