mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 00:02:28 +00:00
Merge remote-tracking branch 'upstream/master' into avoid-write-before-erase
This commit is contained in:
commit
c38eb9660b
@ -1,7 +1,7 @@
|
||||
use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind};
|
||||
use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
|
||||
|
||||
use crate::{FirmwareWriter, Partition, State, BOOT_MAGIC, SWAP_MAGIC};
|
||||
use crate::{Partition, State, BOOT_MAGIC, SWAP_MAGIC};
|
||||
|
||||
/// Errors returned by FirmwareUpdater
|
||||
#[derive(Debug)]
|
||||
@ -256,7 +256,6 @@ impl FirmwareUpdater {
|
||||
offset: usize,
|
||||
data: &[u8],
|
||||
dfu_flash: &mut F,
|
||||
block_size: usize,
|
||||
) -> Result<(), FirmwareUpdaterError> {
|
||||
assert!(data.len() >= F::ERASE_SIZE);
|
||||
|
||||
@ -264,25 +263,23 @@ impl FirmwareUpdater {
|
||||
.erase(dfu_flash, offset as u32, (offset + data.len()) as u32)
|
||||
.await?;
|
||||
|
||||
FirmwareWriter(self.dfu)
|
||||
.write_block(offset, data, dfu_flash, block_size)
|
||||
.await?;
|
||||
self.dfu.write(dfu_flash, offset as u32, data).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Prepare for an incoming DFU update by erasing the entire DFU area and
|
||||
/// returning a `FirmwareWriter`.
|
||||
/// returning its `Partition`.
|
||||
///
|
||||
/// Using this instead of `write_firmware` allows for an optimized API in
|
||||
/// exchange for added complexity.
|
||||
pub async fn prepare_update<F: AsyncNorFlash>(
|
||||
&mut self,
|
||||
dfu_flash: &mut F,
|
||||
) -> Result<FirmwareWriter, FirmwareUpdaterError> {
|
||||
) -> Result<Partition, FirmwareUpdaterError> {
|
||||
self.dfu.wipe(dfu_flash).await?;
|
||||
|
||||
Ok(FirmwareWriter(self.dfu))
|
||||
Ok(self.dfu)
|
||||
}
|
||||
|
||||
//
|
||||
@ -469,29 +466,25 @@ impl FirmwareUpdater {
|
||||
offset: usize,
|
||||
data: &[u8],
|
||||
dfu_flash: &mut F,
|
||||
block_size: usize,
|
||||
) -> Result<(), FirmwareUpdaterError> {
|
||||
assert!(data.len() >= F::ERASE_SIZE);
|
||||
|
||||
self.dfu
|
||||
.erase_blocking(dfu_flash, offset as u32, (offset + data.len()) as u32)?;
|
||||
|
||||
FirmwareWriter(self.dfu).write_block_blocking(offset, data, dfu_flash, block_size)?;
|
||||
self.dfu.write_blocking(dfu_flash, offset as u32, data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Prepare for an incoming DFU update by erasing the entire DFU area and
|
||||
/// returning a `FirmwareWriter`.
|
||||
/// returning its `Partition`.
|
||||
///
|
||||
/// Using this instead of `write_firmware_blocking` allows for an optimized
|
||||
/// API in exchange for added complexity.
|
||||
pub fn prepare_update_blocking<F: NorFlash>(
|
||||
&mut self,
|
||||
flash: &mut F,
|
||||
) -> Result<FirmwareWriter, FirmwareUpdaterError> {
|
||||
pub fn prepare_update_blocking<F: NorFlash>(&mut self, flash: &mut F) -> Result<Partition, FirmwareUpdaterError> {
|
||||
self.dfu.wipe_blocking(flash)?;
|
||||
|
||||
Ok(FirmwareWriter(self.dfu))
|
||||
Ok(self.dfu)
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
use embedded_storage::nor_flash::NorFlash;
|
||||
use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
|
||||
|
||||
use crate::Partition;
|
||||
|
||||
/// FirmwareWriter allows writing blocks to an already erased flash.
|
||||
pub struct FirmwareWriter(pub(crate) Partition);
|
||||
|
||||
impl FirmwareWriter {
|
||||
/// Write data to a flash page.
|
||||
///
|
||||
/// The buffer must follow alignment requirements of the target flash and a multiple of page size big.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Failing to meet alignment and size requirements may result in a panic.
|
||||
pub async fn write_block<F: AsyncNorFlash>(
|
||||
&mut self,
|
||||
offset: usize,
|
||||
data: &[u8],
|
||||
flash: &mut F,
|
||||
block_size: usize,
|
||||
) -> Result<(), F::Error> {
|
||||
let mut offset = offset as u32;
|
||||
for chunk in data.chunks(block_size) {
|
||||
self.0.write(flash, offset, chunk).await?;
|
||||
offset += chunk.len() as u32;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write data to a flash page.
|
||||
///
|
||||
/// The buffer must follow alignment requirements of the target flash and a multiple of page size big.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Failing to meet alignment and size requirements may result in a panic.
|
||||
pub fn write_block_blocking<F: NorFlash>(
|
||||
&mut self,
|
||||
offset: usize,
|
||||
data: &[u8],
|
||||
flash: &mut F,
|
||||
block_size: usize,
|
||||
) -> Result<(), F::Error> {
|
||||
let mut offset = offset as u32;
|
||||
for chunk in data.chunks(block_size) {
|
||||
self.0.write_blocking(flash, offset, chunk)?;
|
||||
offset += chunk.len() as u32;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -7,13 +7,11 @@ mod fmt;
|
||||
|
||||
mod boot_loader;
|
||||
mod firmware_updater;
|
||||
mod firmware_writer;
|
||||
mod mem_flash;
|
||||
mod partition;
|
||||
|
||||
pub use boot_loader::{BootError, BootFlash, BootLoader, Flash, FlashConfig, MultiFlashConfig, SingleFlashConfig};
|
||||
pub use firmware_updater::{FirmwareUpdater, FirmwareUpdaterError};
|
||||
pub use firmware_writer::FirmwareWriter;
|
||||
pub use partition::Partition;
|
||||
|
||||
pub(crate) const BOOT_MAGIC: u8 = 0xD0;
|
||||
@ -107,7 +105,7 @@ mod tests {
|
||||
let mut updater = FirmwareUpdater::new(DFU, STATE);
|
||||
let mut offset = 0;
|
||||
for chunk in update.chunks(4096) {
|
||||
block_on(updater.write_firmware(offset, chunk, &mut flash, 4096)).unwrap();
|
||||
block_on(updater.write_firmware(offset, chunk, &mut flash)).unwrap();
|
||||
offset += chunk.len();
|
||||
}
|
||||
block_on(updater.mark_updated(&mut flash, &mut aligned)).unwrap();
|
||||
@ -180,7 +178,7 @@ mod tests {
|
||||
|
||||
let mut offset = 0;
|
||||
for chunk in update.chunks(2048) {
|
||||
block_on(updater.write_firmware(offset, chunk, &mut dfu, chunk.len())).unwrap();
|
||||
block_on(updater.write_firmware(offset, chunk, &mut dfu)).unwrap();
|
||||
offset += chunk.len();
|
||||
}
|
||||
block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap();
|
||||
@ -233,7 +231,7 @@ mod tests {
|
||||
|
||||
let mut offset = 0;
|
||||
for chunk in update.chunks(4096) {
|
||||
block_on(updater.write_firmware(offset, chunk, &mut dfu, chunk.len())).unwrap();
|
||||
block_on(updater.write_firmware(offset, chunk, &mut dfu)).unwrap();
|
||||
offset += chunk.len();
|
||||
}
|
||||
block_on(updater.mark_updated(&mut state, &mut aligned)).unwrap();
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Before upgrading check that everything is available on all tier1 targets here:
|
||||
# https://rust-lang.github.io/rustup-components-history
|
||||
[toolchain]
|
||||
channel = "nightly-2023-02-07"
|
||||
channel = "nightly-2023-04-02"
|
||||
components = [ "rust-src", "rustfmt", "llvm-tools-preview" ]
|
||||
targets = [
|
||||
"thumbv7em-none-eabi",
|
||||
|
25
tests/nrf/src/bin/timer.rs
Normal file
25
tests/nrf/src/bin/timer.rs
Normal file
@ -0,0 +1,25 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
use defmt::{assert, info};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let _p = embassy_nrf::init(Default::default());
|
||||
info!("Hello World!");
|
||||
|
||||
let start = Instant::now();
|
||||
Timer::after(Duration::from_millis(100)).await;
|
||||
let end = Instant::now();
|
||||
let ms = (end - start).as_millis();
|
||||
info!("slept for {} ms", ms);
|
||||
assert!(ms >= 99);
|
||||
assert!(ms < 110);
|
||||
|
||||
info!("Test OK");
|
||||
cortex_m::asm::bkpt();
|
||||
}
|
Loading…
Reference in New Issue
Block a user