diff options
| -rw-r--r-- | embassy-boot/boot/src/firmware_updater.rs | 25 | ||||
| -rw-r--r-- | embassy-boot/boot/src/firmware_writer.rs | 55 | ||||
| -rw-r--r-- | embassy-boot/boot/src/lib.rs | 8 |
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 @@ | |||
| 1 | use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind}; | 1 | use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind}; |
| 2 | use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash; | 2 | use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash; |
| 3 | 3 | ||
| 4 | use crate::{FirmwareWriter, Partition, State, BOOT_MAGIC, SWAP_MAGIC}; | 4 | use 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 @@ | |||
| 1 | use embedded_storage::nor_flash::NorFlash; | ||
| 2 | use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash; | ||
| 3 | |||
| 4 | use crate::Partition; | ||
| 5 | |||
| 6 | /// FirmwareWriter allows writing blocks to an already erased flash. | ||
| 7 | pub struct FirmwareWriter(pub(crate) Partition); | ||
| 8 | |||
| 9 | impl 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 | ||
| 8 | mod boot_loader; | 8 | mod boot_loader; |
| 9 | mod firmware_updater; | 9 | mod firmware_updater; |
| 10 | mod firmware_writer; | ||
| 11 | mod partition; | 10 | mod partition; |
| 12 | 11 | ||
| 13 | pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig}; | 12 | pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig}; |
| 14 | pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError}; | 13 | pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError}; |
| 15 | pub use firmware_writer::FirmwareWriter; | ||
| 16 | pub use partition::Partition; | 14 | pub use partition::Partition; |
| 17 | 15 | ||
| 18 | pub(crate) const BOOT_MAGIC: u8 = 0xD0; | 16 | pub(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(); |
