aboutsummaryrefslogtreecommitdiff
path: root/embassy-boot
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-04-04 07:58:16 +0200
committerRasmus Melchior Jacobsen <[email protected]>2023-04-04 07:58:16 +0200
commitc94f1e14507a8f58d110d9470f8399f5dfed18de (patch)
tree8106897befb158167e7ebb9c838e82d9987d1726 /embassy-boot
parent8aaffe82e71dfb2b3845c95bbf59ef4a34c7096c (diff)
parent36ad82a52b540eec5e94052b08de8e8e6308f2ce (diff)
Merge remote-tracking branch 'upstream/master' into incremental-hash
Diffstat (limited to 'embassy-boot')
-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 90157036a..22e3e6b00 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)]
@@ -253,7 +253,6 @@ impl FirmwareUpdater {
253 offset: usize, 253 offset: usize,
254 data: &[u8], 254 data: &[u8],
255 dfu_flash: &mut F, 255 dfu_flash: &mut F,
256 block_size: usize,
257 ) -> Result<(), FirmwareUpdaterError> { 256 ) -> Result<(), FirmwareUpdaterError> {
258 assert!(data.len() >= F::ERASE_SIZE); 257 assert!(data.len() >= F::ERASE_SIZE);
259 258
@@ -261,25 +260,23 @@ impl FirmwareUpdater {
261 .erase(dfu_flash, offset as u32, (offset + data.len()) as u32) 260 .erase(dfu_flash, offset as u32, (offset + data.len()) as u32)
262 .await?; 261 .await?;
263 262
264 FirmwareWriter(self.dfu) 263 self.dfu.write(dfu_flash, offset as u32, data).await?;
265 .write_block(offset, data, dfu_flash, block_size)
266 .await?;
267 264
268 Ok(()) 265 Ok(())
269 } 266 }
270 267
271 /// Prepare for an incoming DFU update by erasing the entire DFU area and 268 /// Prepare for an incoming DFU update by erasing the entire DFU area and
272 /// returning a `FirmwareWriter`. 269 /// returning its `Partition`.
273 /// 270 ///
274 /// Using this instead of `write_firmware` allows for an optimized API in 271 /// Using this instead of `write_firmware` allows for an optimized API in
275 /// exchange for added complexity. 272 /// exchange for added complexity.
276 pub async fn prepare_update<F: AsyncNorFlash>( 273 pub async fn prepare_update<F: AsyncNorFlash>(
277 &mut self, 274 &mut self,
278 dfu_flash: &mut F, 275 dfu_flash: &mut F,
279 ) -> Result<FirmwareWriter, FirmwareUpdaterError> { 276 ) -> Result<Partition, FirmwareUpdaterError> {
280 self.dfu.wipe(dfu_flash).await?; 277 self.dfu.wipe(dfu_flash).await?;
281 278
282 Ok(FirmwareWriter(self.dfu)) 279 Ok(self.dfu)
283 } 280 }
284 281
285 // 282 //
@@ -460,29 +457,25 @@ impl FirmwareUpdater {
460 offset: usize, 457 offset: usize,
461 data: &[u8], 458 data: &[u8],
462 dfu_flash: &mut F, 459 dfu_flash: &mut F,
463 block_size: usize,
464 ) -> Result<(), FirmwareUpdaterError> { 460 ) -> Result<(), FirmwareUpdaterError> {
465 assert!(data.len() >= F::ERASE_SIZE); 461 assert!(data.len() >= F::ERASE_SIZE);
466 462
467 self.dfu 463 self.dfu
468 .erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?; 464 .erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?;
469 465
470 FirmwareWriter(self.dfu).write_block_blocking(offset, data, dfu_flash, block_size)?; 466 self.dfu.write_blocking(dfu_flash, offset as u32, data)?;
471 467
472 Ok(()) 468 Ok(())
473 } 469 }
474 470
475 /// Prepare for an incoming DFU update by erasing the entire DFU area and 471 /// Prepare for an incoming DFU update by erasing the entire DFU area and
476 /// returning a `FirmwareWriter`. 472 /// returning its `Partition`.
477 /// 473 ///
478 /// Using this instead of `write_firmware_blocking` allows for an optimized 474 /// Using this instead of `write_firmware_blocking` allows for an optimized
479 /// API in exchange for added complexity. 475 /// API in exchange for added complexity.
480 pub fn prepare_update_blocking<F: NorFlash>( 476 pub fn prepare_update_blocking<F: NorFlash>(&mut self, flash: &mut F) -> Result<Partition, FirmwareUpdaterError> {
481 &mut self,
482 flash: &mut F,
483 ) -> Result<FirmwareWriter, FirmwareUpdaterError> {
484 self.dfu.wipe_blocking(flash)?; 477 self.dfu.wipe_blocking(flash)?;
485 478
486 Ok(FirmwareWriter(self.dfu)) 479 Ok(self.dfu)
487 } 480 }
488} 481}
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 6d0e2d8c2..6888a8055 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();