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 | ||||
| -rw-r--r-- | rust-toolchain.toml | 2 | ||||
| -rw-r--r-- | tests/nrf/src/bin/timer.rs | 25 |
5 files changed, 38 insertions, 77 deletions
diff --git a/embassy-boot/boot/src/firmware_updater.rs b/embassy-boot/boot/src/firmware_updater.rs index fe3c0452f..2b5cc72fa 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)] |
| @@ -256,7 +256,6 @@ impl FirmwareUpdater { | |||
| 256 | offset: usize, | 256 | offset: usize, |
| 257 | data: &[u8], | 257 | data: &[u8], |
| 258 | dfu_flash: &mut F, | 258 | dfu_flash: &mut F, |
| 259 | block_size: usize, | ||
| 260 | ) -> Result<(), FirmwareUpdaterError> { | 259 | ) -> Result<(), FirmwareUpdaterError> { |
| 261 | assert!(data.len() >= F::ERASE_SIZE); | 260 | assert!(data.len() >= F::ERASE_SIZE); |
| 262 | 261 | ||
| @@ -264,25 +263,23 @@ impl FirmwareUpdater { | |||
| 264 | .erase(dfu_flash, offset as u32, (offset + data.len()) as u32) | 263 | .erase(dfu_flash, offset as u32, (offset + data.len()) as u32) |
| 265 | .await?; | 264 | .await?; |
| 266 | 265 | ||
| 267 | FirmwareWriter(self.dfu) | 266 | self.dfu.write(dfu_flash, offset as u32, data).await?; |
| 268 | .write_block(offset, data, dfu_flash, block_size) | ||
| 269 | .await?; | ||
| 270 | 267 | ||
| 271 | Ok(()) | 268 | Ok(()) |
| 272 | } | 269 | } |
| 273 | 270 | ||
| 274 | /// Prepare for an incoming DFU update by erasing the entire DFU area and | 271 | /// Prepare for an incoming DFU update by erasing the entire DFU area and |
| 275 | /// returning a `FirmwareWriter`. | 272 | /// returning its `Partition`. |
| 276 | /// | 273 | /// |
| 277 | /// Using this instead of `write_firmware` allows for an optimized API in | 274 | /// Using this instead of `write_firmware` allows for an optimized API in |
| 278 | /// exchange for added complexity. | 275 | /// exchange for added complexity. |
| 279 | pub async fn prepare_update<F: AsyncNorFlash>( | 276 | pub async fn prepare_update<F: AsyncNorFlash>( |
| 280 | &mut self, | 277 | &mut self, |
| 281 | dfu_flash: &mut F, | 278 | dfu_flash: &mut F, |
| 282 | ) -> Result<FirmwareWriter, FirmwareUpdaterError> { | 279 | ) -> Result<Partition, FirmwareUpdaterError> { |
| 283 | self.dfu.wipe(dfu_flash).await?; | 280 | self.dfu.wipe(dfu_flash).await?; |
| 284 | 281 | ||
| 285 | Ok(FirmwareWriter(self.dfu)) | 282 | Ok(self.dfu) |
| 286 | } | 283 | } |
| 287 | 284 | ||
| 288 | // | 285 | // |
| @@ -469,29 +466,25 @@ impl FirmwareUpdater { | |||
| 469 | offset: usize, | 466 | offset: usize, |
| 470 | data: &[u8], | 467 | data: &[u8], |
| 471 | dfu_flash: &mut F, | 468 | dfu_flash: &mut F, |
| 472 | block_size: usize, | ||
| 473 | ) -> Result<(), FirmwareUpdaterError> { | 469 | ) -> Result<(), FirmwareUpdaterError> { |
| 474 | assert!(data.len() >= F::ERASE_SIZE); | 470 | assert!(data.len() >= F::ERASE_SIZE); |
| 475 | 471 | ||
| 476 | self.dfu | 472 | self.dfu |
| 477 | .erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?; | 473 | .erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?; |
| 478 | 474 | ||
| 479 | FirmwareWriter(self.dfu).write_block_blocking(offset, data, dfu_flash, block_size)?; | 475 | self.dfu.write_blocking(dfu_flash, offset as u32, data)?; |
| 480 | 476 | ||
| 481 | Ok(()) | 477 | Ok(()) |
| 482 | } | 478 | } |
| 483 | 479 | ||
| 484 | /// Prepare for an incoming DFU update by erasing the entire DFU area and | 480 | /// Prepare for an incoming DFU update by erasing the entire DFU area and |
| 485 | /// returning a `FirmwareWriter`. | 481 | /// returning its `Partition`. |
| 486 | /// | 482 | /// |
| 487 | /// Using this instead of `write_firmware_blocking` allows for an optimized | 483 | /// Using this instead of `write_firmware_blocking` allows for an optimized |
| 488 | /// API in exchange for added complexity. | 484 | /// API in exchange for added complexity. |
| 489 | pub fn prepare_update_blocking<F: NorFlash>( | 485 | pub fn prepare_update_blocking<F: NorFlash>(&mut self, flash: &mut F) -> Result<Partition, FirmwareUpdaterError> { |
| 490 | &mut self, | ||
| 491 | flash: &mut F, | ||
| 492 | ) -> Result<FirmwareWriter, FirmwareUpdaterError> { | ||
| 493 | self.dfu.wipe_blocking(flash)?; | 486 | self.dfu.wipe_blocking(flash)?; |
| 494 | 487 | ||
| 495 | Ok(FirmwareWriter(self.dfu)) | 488 | Ok(self.dfu) |
| 496 | } | 489 | } |
| 497 | } | 490 | } |
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 597ce3fa3..cb12f9dc7 100644 --- a/embassy-boot/boot/src/lib.rs +++ b/embassy-boot/boot/src/lib.rs | |||
| @@ -7,13 +7,11 @@ 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 mem_flash; | 10 | mod mem_flash; |
| 12 | mod partition; | 11 | mod partition; |
| 13 | 12 | ||
| 14 | pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig}; | 13 | pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig}; |
| 15 | pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError}; | 14 | pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError}; |
| 16 | pub use firmware_writer::FirmwareWriter; | ||
| 17 | pub use partition::Partition; | 15 | pub use partition::Partition; |
| 18 | 16 | ||
| 19 | pub(crate) const BOOT_MAGIC: u8 = 0xD0; | 17 | pub(crate) const BOOT_MAGIC: u8 = 0xD0; |
| @@ -107,7 +105,7 @@ mod tests { | |||
| 107 | let mut updater = FirmwareUpdater::new(DFU, STATE); | 105 | let mut updater = FirmwareUpdater::new(DFU, STATE); |
| 108 | let mut offset = 0; | 106 | let mut offset = 0; |
| 109 | for chunk in update.chunks(4096) { | 107 | for chunk in update.chunks(4096) { |
| 110 | block_on(updater.write_firmware(offset, chunk, &mut flash, 4096)).unwrap(); | 108 | block_on(updater.write_firmware(offset, chunk, &mut flash)).unwrap(); |
| 111 | offset += chunk.len(); | 109 | offset += chunk.len(); |
| 112 | } | 110 | } |
| 113 | block_on(updater.mark_updated(&mut flash, &mut aligned)).unwrap(); | 111 | block_on(updater.mark_updated(&mut flash, &mut aligned)).unwrap(); |
| @@ -180,7 +178,7 @@ mod tests { | |||
| 180 | 178 | ||
| 181 | let mut offset = 0; | 179 | let mut offset = 0; |
| 182 | for chunk in update.chunks(2048) { | 180 | for chunk in update.chunks(2048) { |
| 183 | block_on(updater.write_firmware(offset, chunk, &mut dfu, chunk.len())).unwrap(); | 181 | block_on(updater.write_firmware(offset, chunk, &mut dfu)).unwrap(); |
| 184 | offset += chunk.len(); | 182 | offset += chunk.len(); |
| 185 | } | 183 | } |
| 186 | block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap(); | 184 | block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap(); |
| @@ -233,7 +231,7 @@ mod tests { | |||
| 233 | 231 | ||
| 234 | let mut offset = 0; | 232 | let mut offset = 0; |
| 235 | for chunk in update.chunks(4096) { | 233 | for chunk in update.chunks(4096) { |
| 236 | block_on(updater.write_firmware(offset, chunk, &mut dfu, chunk.len())).unwrap(); | 234 | block_on(updater.write_firmware(offset, chunk, &mut dfu)).unwrap(); |
| 237 | offset += chunk.len(); | 235 | offset += chunk.len(); |
| 238 | } | 236 | } |
| 239 | block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap(); | 237 | block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap(); |
diff --git a/rust-toolchain.toml b/rust-toolchain.toml index da75fa53a..22abacdea 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # Before upgrading check that everything is available on all tier1 targets here: | 1 | # Before upgrading check that everything is available on all tier1 targets here: |
| 2 | # https://rust-lang.github.io/rustup-components-history | 2 | # https://rust-lang.github.io/rustup-components-history |
| 3 | [toolchain] | 3 | [toolchain] |
| 4 | channel = "nightly-2023-02-07" | 4 | channel = "nightly-2023-04-02" |
| 5 | components = [ "rust-src", "rustfmt", "llvm-tools-preview" ] | 5 | components = [ "rust-src", "rustfmt", "llvm-tools-preview" ] |
| 6 | targets = [ | 6 | targets = [ |
| 7 | "thumbv7em-none-eabi", | 7 | "thumbv7em-none-eabi", |
diff --git a/tests/nrf/src/bin/timer.rs b/tests/nrf/src/bin/timer.rs new file mode 100644 index 000000000..9b9b5fb28 --- /dev/null +++ b/tests/nrf/src/bin/timer.rs | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::{assert, info}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_time::{Duration, Instant, Timer}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let _p = embassy_nrf::init(Default::default()); | ||
| 13 | info!("Hello World!"); | ||
| 14 | |||
| 15 | let start = Instant::now(); | ||
| 16 | Timer::after(Duration::from_millis(100)).await; | ||
| 17 | let end = Instant::now(); | ||
| 18 | let ms = (end - start).as_millis(); | ||
| 19 | info!("slept for {} ms", ms); | ||
| 20 | assert!(ms >= 99); | ||
| 21 | assert!(ms < 110); | ||
| 22 | |||
| 23 | info!("Test OK"); | ||
| 24 | cortex_m::asm::bkpt(); | ||
| 25 | } | ||
