From da61611f8f57410a87106961efd24d80e6a8f63e Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 26 Apr 2022 18:33:09 +0200 Subject: [PATCH] Add bootloader to CI --- ci.sh | 7 +++ embassy-boot/boot/Cargo.toml | 5 -- embassy-boot/boot/src/lib.rs | 57 ++++++++----------- embassy-boot/nrf/Cargo.toml | 2 +- embassy-boot/nrf/src/lib.rs | 2 +- embassy-boot/nrf/src/main.rs | 5 +- embassy-boot/stm32/Cargo.toml | 4 -- embassy-boot/stm32/memory.x | 12 ++-- embassy-boot/stm32/src/lib.rs | 8 ++- embassy-boot/stm32/src/main.rs | 18 +----- embassy-stm32/src/flash/mod.rs | 84 +++++++--------------------- examples/boot/nrf/.cargo/config.toml | 6 ++ examples/boot/nrf/Cargo.toml | 2 +- examples/boot/nrf/README.md | 8 +-- examples/boot/stm32l0/Cargo.toml | 2 +- examples/boot/stm32l0/README.md | 2 +- examples/boot/stm32l0/memory.x | 8 +-- examples/boot/stm32l1/Cargo.toml | 2 +- examples/boot/stm32l1/README.md | 2 +- examples/boot/stm32l1/memory.x | 8 +-- examples/boot/stm32l4/Cargo.toml | 2 +- examples/boot/stm32l4/README.md | 2 +- examples/boot/stm32l4/memory.x | 10 ++-- examples/boot/stm32wl/Cargo.toml | 2 +- examples/boot/stm32wl/README.md | 2 +- examples/boot/stm32wl/memory.x | 8 +-- examples/boot/stm32wl/src/bin/a.rs | 8 ++- examples/stm32l0/src/bin/flash.rs | 2 +- examples/stm32l1/src/bin/flash.rs | 2 +- examples/stm32wl/src/bin/flash.rs | 2 +- stm32-data | 2 +- stm32-metapac-gen/src/data.rs | 8 +++ stm32-metapac-gen/src/lib.rs | 34 +++++++++++ stm32-metapac/src/metadata.rs | 8 +++ 34 files changed, 163 insertions(+), 173 deletions(-) create mode 100644 examples/boot/nrf/.cargo/config.toml diff --git a/ci.sh b/ci.sh index 69fa08047..c6fe9c4aa 100755 --- a/ci.sh +++ b/ci.sh @@ -58,6 +58,8 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5ub,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-boot/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \ + --- build --release --manifest-path embassy-boot/stm32/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32wl55jc-cm4 \ --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml --target thumbv7em-none-eabi \ @@ -81,6 +83,11 @@ cargo batch \ --- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \ --- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \ --- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \ + --- build --release --manifest-path examples/boot/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/boot/nrf --bin b \ + --- build --release --manifest-path examples/boot/stm32l0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/boot/stm32l0 --bin b \ + --- build --release --manifest-path examples/boot/stm32l1/Cargo.toml --target thumbv7m-none-eabi --out-dir out/examples/boot/stm32l1 --bin b \ + --- build --release --manifest-path examples/boot/stm32l4/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/boot/stm32l4 --bin b \ + --- build --release --manifest-path examples/boot/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/boot/stm32wl --bin b \ --- build --release --manifest-path examples/wasm/Cargo.toml --target wasm32-unknown-unknown --out-dir out/examples/wasm \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103c8 --out-dir out/tests/bluepill-stm32f103c8 \ --- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi --out-dir out/tests/nucleo-stm32f429zi \ diff --git a/embassy-boot/boot/Cargo.toml b/embassy-boot/boot/Cargo.toml index 04deab30b..0a3006ffc 100644 --- a/embassy-boot/boot/Cargo.toml +++ b/embassy-boot/boot/Cargo.toml @@ -21,8 +21,3 @@ log = "0.4" env_logger = "0.9" rand = "0.8" futures = { version = "0.3", features = ["executor"] } - -[features] -write-4 = [] -write-8 = [] -invert-erase = [] diff --git a/embassy-boot/boot/src/lib.rs b/embassy-boot/boot/src/lib.rs index 080ea2426..554709250 100644 --- a/embassy-boot/boot/src/lib.rs +++ b/embassy-boot/boot/src/lib.rs @@ -1,5 +1,7 @@ #![feature(type_alias_impl_trait)] #![feature(generic_associated_types)] +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] #![no_std] ///! embassy-boot is a bootloader and firmware updater for embedded devices with flash ///! storage implemented using embedded-storage @@ -17,24 +19,9 @@ mod fmt; use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; use embedded_storage_async::nor_flash::AsyncNorFlash; -#[cfg(not(any(feature = "write-4", feature = "write-8",)))] -compile_error!("No write size/alignment specified. Must specify exactly one of the following features: write-4, write-8"); - const BOOT_MAGIC: u8 = 0xD0; const SWAP_MAGIC: u8 = 0xF0; -#[cfg(feature = "write-4")] -const WRITE_SIZE: usize = 4; - -#[cfg(feature = "write-8")] -const WRITE_SIZE: usize = 8; - -#[cfg(feature = "invert-erase")] -const ERASE_VALUE: u8 = 0x00; - -#[cfg(not(feature = "invert-erase"))] -const ERASE_VALUE: u8 = 0xFF; - #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Partition { @@ -96,7 +83,7 @@ pub trait FlashProvider { /// BootLoader works with any flash implementing embedded_storage and can also work with /// different page sizes and flash write sizes. -pub struct BootLoader { +pub struct BootLoader { // Page with current state of bootloader. The state partition has the following format: // | Range | Description | // | 0 - WRITE_SIZE | Magic indicating bootloader state. BOOT_MAGIC means boot, SWAP_MAGIC means swap. | @@ -108,7 +95,9 @@ pub struct BootLoader { dfu: Partition, } -impl BootLoader { +impl + BootLoader +{ pub fn new(active: Partition, dfu: Partition, state: Partition) -> Self { assert_eq!(active.len() % PAGE_SIZE, 0); assert_eq!(dfu.len() % PAGE_SIZE, 0); @@ -352,8 +341,6 @@ impl BootLoader { self.copy_page_once_to_active(page * 2 + 1, dfu_page, active_page, p)?; } - info!("DONE COPYING"); - Ok(()) } @@ -379,7 +366,6 @@ impl BootLoader { let flash = p.flash(); flash.read(self.state.from as u32, &mut magic)?; - info!("Read magic: {:x}", magic); if magic == [SWAP_MAGIC; WRITE_SIZE] { Ok(State::Swap) } else { @@ -451,13 +437,9 @@ pub struct FirmwareUpdater { dfu: Partition, } -#[cfg(feature = "write-4")] -#[repr(align(4))] -pub struct Aligned([u8; 4]); - -#[cfg(feature = "write-8")] -#[repr(align(8))] -pub struct Aligned([u8; 8]); +// NOTE: Aligned to the largest write size supported by flash +#[repr(align(32))] +pub struct Aligned([u8; N]); impl Default for FirmwareUpdater { fn default() -> Self { @@ -480,6 +462,9 @@ impl Default for FirmwareUpdater { &__bootloader_state_end as *const u32 as usize, ) }; + + trace!("DFU: 0x{:x} - 0x{:x}", dfu.from, dfu.to); + trace!("STATE: 0x{:x} - 0x{:x}", state.from, state.to); FirmwareUpdater::new(dfu, state) } } @@ -496,14 +481,20 @@ impl FirmwareUpdater { /// Instruct bootloader that DFU should commence at next boot. /// Must be provided with an aligned buffer to use for reading and writing magic; - pub async fn mark_update(&mut self, flash: &mut F) -> Result<(), F::Error> { - let mut aligned = Aligned([0; WRITE_SIZE]); + pub async fn mark_update(&mut self, flash: &mut F) -> Result<(), F::Error> + where + [(); F::WRITE_SIZE]:, + { + let mut aligned = Aligned([0; { F::WRITE_SIZE }]); self.set_magic(&mut aligned.0, SWAP_MAGIC, flash).await } /// Mark firmware boot successfully - pub async fn mark_booted(&mut self, flash: &mut F) -> Result<(), F::Error> { - let mut aligned = Aligned([0; WRITE_SIZE]); + pub async fn mark_booted(&mut self, flash: &mut F) -> Result<(), F::Error> + where + [(); F::WRITE_SIZE]:, + { + let mut aligned = Aligned([0; { F::WRITE_SIZE }]); self.set_magic(&mut aligned.0, BOOT_MAGIC, flash).await } @@ -626,7 +617,7 @@ mod tests { flash.0[0..4].copy_from_slice(&[BOOT_MAGIC; 4]); let mut flash = SingleFlashProvider::new(&mut flash); - let mut bootloader = BootLoader::<4096>::new(ACTIVE, DFU, STATE); + let mut bootloader = BootLoader::<4096, 4, 0xFF>::new(ACTIVE, DFU, STATE); assert_eq!(State::Boot, bootloader.prepare_boot(&mut flash).unwrap()); } @@ -643,7 +634,7 @@ mod tests { flash.0[i] = original[i - ACTIVE.from]; } - let mut bootloader = BootLoader::<4096>::new(ACTIVE, DFU, STATE); + let mut bootloader = BootLoader::<4096, 4, 0xFF>::new(ACTIVE, DFU, STATE); let mut updater = FirmwareUpdater::new(DFU, STATE); let mut offset = 0; for chunk in update.chunks(4096) { diff --git a/embassy-boot/nrf/Cargo.toml b/embassy-boot/nrf/Cargo.toml index 78157d246..97207ac29 100644 --- a/embassy-boot/nrf/Cargo.toml +++ b/embassy-boot/nrf/Cargo.toml @@ -13,7 +13,7 @@ defmt-rtt = { version = "0.3", optional = true } embassy = { path = "../../embassy", default-features = false } embassy-nrf = { path = "../../embassy-nrf", default-features = false, features = ["nightly"] } -embassy-boot = { path = "../boot", default-features = false, features = ["write-4"] } +embassy-boot = { path = "../boot", default-features = false } cortex-m = { version = "0.7" } cortex-m-rt = { version = "0.7" } embedded-storage = "0.3.0" diff --git a/embassy-boot/nrf/src/lib.rs b/embassy-boot/nrf/src/lib.rs index 500cae500..c12899d77 100644 --- a/embassy-boot/nrf/src/lib.rs +++ b/embassy-boot/nrf/src/lib.rs @@ -13,7 +13,7 @@ use embassy_nrf::{ use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; pub struct BootLoader { - boot: embassy_boot::BootLoader, + boot: embassy_boot::BootLoader, } impl BootLoader { diff --git a/embassy-boot/nrf/src/main.rs b/embassy-boot/nrf/src/main.rs index 63de7c869..0ccd3774d 100644 --- a/embassy-boot/nrf/src/main.rs +++ b/embassy-boot/nrf/src/main.rs @@ -46,8 +46,5 @@ unsafe fn DefaultHandler(_: i16) -> ! { #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { - unsafe { - cortex_m::asm::udf(); - core::hint::unreachable_unchecked(); - } + cortex_m::asm::udf(); } diff --git a/embassy-boot/stm32/Cargo.toml b/embassy-boot/stm32/Cargo.toml index 76bc480bf..a706e4c06 100644 --- a/embassy-boot/stm32/Cargo.toml +++ b/embassy-boot/stm32/Cargo.toml @@ -27,10 +27,6 @@ defmt = [ "embassy-stm32/defmt", ] debug = ["defmt-rtt"] -flash-2k = ["embassy-boot/write-8"] -flash-128 = ["embassy-boot/write-4"] -flash-256 = ["embassy-boot/write-4"] -invert-erase = ["embassy-boot/invert-erase"] thumbv6 = [] [profile.dev] diff --git a/embassy-boot/stm32/memory.x b/embassy-boot/stm32/memory.x index c5356ed37..110c23259 100644 --- a/embassy-boot/stm32/memory.x +++ b/embassy-boot/stm32/memory.x @@ -8,11 +8,11 @@ MEMORY RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 16K } -__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); -__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE); +__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(FLASH); +__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(FLASH); -__bootloader_active_start = ORIGIN(ACTIVE); -__bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE); +__bootloader_active_start = ORIGIN(ACTIVE) - ORIGIN(FLASH); +__bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE) - ORIGIN(FLASH); -__bootloader_dfu_start = ORIGIN(DFU); -__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU); +__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(FLASH); +__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(FLASH); diff --git a/embassy-boot/stm32/src/lib.rs b/embassy-boot/stm32/src/lib.rs index d1754a310..68220780c 100644 --- a/embassy-boot/stm32/src/lib.rs +++ b/embassy-boot/stm32/src/lib.rs @@ -5,12 +5,13 @@ mod fmt; pub use embassy_boot::{FirmwareUpdater, FlashProvider, Partition, SingleFlashProvider, State}; +use embassy_stm32::flash::{ERASE_SIZE, ERASE_VALUE, WRITE_SIZE}; -pub struct BootLoader { - boot: embassy_boot::BootLoader, +pub struct BootLoader { + boot: embassy_boot::BootLoader, } -impl BootLoader { +impl BootLoader { /// Create a new bootloader instance using parameters from linker script pub fn default() -> Self { extern "C" { @@ -65,6 +66,7 @@ impl BootLoader { pub unsafe fn load(&mut self, start: usize) -> ! { trace!("Loading app at 0x{:x}", start); + #[allow(unused_mut)] let mut p = cortex_m::Peripherals::steal(); #[cfg(not(feature = "thumbv6"))] p.SCB.invalidate_icache(); diff --git a/embassy-boot/stm32/src/main.rs b/embassy-boot/stm32/src/main.rs index 6fe0fb66d..563bc55d3 100644 --- a/embassy-boot/stm32/src/main.rs +++ b/embassy-boot/stm32/src/main.rs @@ -9,9 +9,6 @@ use defmt_rtt as _; use embassy_boot_stm32::*; use embassy_stm32::flash::Flash; -#[cfg(not(any(feature = "flash-2k", feature = "flash-256", feature = "flash-128")))] -compile_error!("No flash size specified. Must specify exactly one of the following features: flash-2k, flash-256, flash-128"); - #[entry] fn main() -> ! { let p = embassy_stm32::init(Default::default()); @@ -24,15 +21,7 @@ fn main() -> ! { } */ - #[cfg(feature = "flash-2k")] - let mut bl: BootLoader<2048> = BootLoader::default(); - - #[cfg(feature = "flash-256")] - let mut bl: BootLoader<256> = BootLoader::default(); - - #[cfg(feature = "flash-128")] - let mut bl: BootLoader<128> = BootLoader::default(); - + let mut bl = BootLoader::default(); let mut flash = Flash::unlock(p.FLASH); let start = bl.prepare(&mut SingleFlashProvider::new(&mut flash)); core::mem::drop(flash); @@ -55,8 +44,5 @@ unsafe fn DefaultHandler(_: i16) -> ! { #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { - unsafe { - cortex_m::asm::udf(); - core::hint::unreachable_unchecked(); - } + cortex_m::asm::udf(); } diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index 7a282497f..cff3119fd 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -10,59 +10,12 @@ use embedded_storage::nor_flash::{ ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, }; -const FLASH_BASE: usize = 0x8000000; - -#[cfg(flash_l4)] -mod config { - use super::*; - pub(crate) const FLASH_SIZE: usize = 0x100000; - pub(crate) const FLASH_START: usize = FLASH_BASE; - pub(crate) const FLASH_END: usize = FLASH_START + FLASH_SIZE; - pub(crate) const PAGE_SIZE: usize = 2048; - pub(crate) const WORD_SIZE: usize = 8; -} - -#[cfg(flash_wb)] -mod config { - use super::*; - pub(crate) const FLASH_SIZE: usize = 0x100000; - pub(crate) const FLASH_START: usize = FLASH_BASE; - pub(crate) const FLASH_END: usize = FLASH_START + FLASH_SIZE; - pub(crate) const PAGE_SIZE: usize = 4096; - pub(crate) const WORD_SIZE: usize = 8; -} - -#[cfg(flash_wl)] -mod config { - use super::*; - pub(crate) const FLASH_SIZE: usize = 0x40000; - pub(crate) const FLASH_START: usize = FLASH_BASE; - pub(crate) const FLASH_END: usize = FLASH_START + FLASH_SIZE; - pub(crate) const PAGE_SIZE: usize = 2048; - pub(crate) const WORD_SIZE: usize = 8; -} - -#[cfg(flash_l0)] -mod config { - use super::*; - pub(crate) const FLASH_SIZE: usize = 0x30000; - pub(crate) const FLASH_START: usize = FLASH_BASE; - pub(crate) const FLASH_END: usize = FLASH_START + FLASH_SIZE; - pub(crate) const PAGE_SIZE: usize = 128; - pub(crate) const WORD_SIZE: usize = 4; -} - -#[cfg(flash_l1)] -mod config { - use super::*; - pub(crate) const FLASH_SIZE: usize = 0x80000; - pub(crate) const FLASH_START: usize = FLASH_BASE; - pub(crate) const FLASH_END: usize = FLASH_START + FLASH_SIZE; - pub(crate) const PAGE_SIZE: usize = 256; - pub(crate) const WORD_SIZE: usize = 4; -} - -use config::*; +pub use crate::pac::ERASE_SIZE; +pub use crate::pac::ERASE_VALUE; +pub use crate::pac::FLASH_BASE; +pub use crate::pac::FLASH_SIZE; +pub use crate::pac::WRITE_SIZE; +const FLASH_END: usize = FLASH_BASE + FLASH_SIZE; pub struct Flash<'d> { _inner: FLASH, @@ -114,6 +67,7 @@ impl<'d> Flash<'d> { } pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { + let offset = FLASH_BASE as u32 + offset; if offset as usize >= FLASH_END || offset as usize + bytes.len() > FLASH_END { return Err(Error::Size); } @@ -124,23 +78,25 @@ impl<'d> Flash<'d> { } pub fn blocking_write(&mut self, offset: u32, buf: &[u8]) -> Result<(), Error> { + let offset = FLASH_BASE as u32 + offset; if offset as usize + buf.len() > FLASH_END { return Err(Error::Size); } - if offset as usize % WORD_SIZE != 0 || buf.len() as usize % WORD_SIZE != 0 { + if offset as usize % WRITE_SIZE != 0 || buf.len() as usize % WRITE_SIZE != 0 { return Err(Error::Unaligned); } + trace!("Writing {} bytes at 0x{:x}", buf.len(), offset); self.clear_all_err(); #[cfg(any(flash_wl, flash_wb, flash_l4))] unsafe { - pac::FLASH.cr().write(|w| w.set_pg(true)); + pac::FLASH.cr().write(|w| w.set_pg(true)) } let mut ret: Result<(), Error> = Ok(()); let mut offset = offset; - for chunk in buf.chunks(WORD_SIZE) { + for chunk in buf.chunks(WRITE_SIZE) { for val in chunk.chunks(4) { unsafe { write_volatile( @@ -159,23 +115,25 @@ impl<'d> Flash<'d> { #[cfg(any(flash_wl, flash_wb, flash_l4))] unsafe { - pac::FLASH.cr().write(|w| w.set_pg(false)); + pac::FLASH.cr().write(|w| w.set_pg(false)) } ret } pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { + let from = FLASH_BASE as u32 + from; + let to = FLASH_BASE as u32 + to; if to < from || to as usize > FLASH_END { return Err(Error::Size); } - if from as usize % PAGE_SIZE != 0 || to as usize % PAGE_SIZE != 0 { + if from as usize % ERASE_SIZE != 0 || to as usize % ERASE_SIZE != 0 { return Err(Error::Unaligned); } self.clear_all_err(); - for page in (from..to).step_by(PAGE_SIZE) { + for page in (from..to).step_by(ERASE_SIZE) { #[cfg(any(flash_l0, flash_l1))] unsafe { pac::FLASH.pecr().modify(|w| { @@ -188,7 +146,7 @@ impl<'d> Flash<'d> { #[cfg(any(flash_wl, flash_wb, flash_l4))] unsafe { - let idx = page / PAGE_SIZE as u32; + let idx = page / ERASE_SIZE as u32; pac::FLASH.cr().modify(|w| { w.set_per(true); @@ -333,7 +291,7 @@ impl NorFlashError for Error { } impl<'d> ReadNorFlash for Flash<'d> { - const READ_SIZE: usize = WORD_SIZE; + const READ_SIZE: usize = WRITE_SIZE; fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { self.blocking_read(offset, bytes) @@ -345,8 +303,8 @@ impl<'d> ReadNorFlash for Flash<'d> { } impl<'d> NorFlash for Flash<'d> { - const WRITE_SIZE: usize = WORD_SIZE; - const ERASE_SIZE: usize = PAGE_SIZE; + const WRITE_SIZE: usize = WRITE_SIZE; + const ERASE_SIZE: usize = ERASE_SIZE; fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { self.blocking_erase(from, to) diff --git a/examples/boot/nrf/.cargo/config.toml b/examples/boot/nrf/.cargo/config.toml new file mode 100644 index 000000000..c75b5c539 --- /dev/null +++ b/examples/boot/nrf/.cargo/config.toml @@ -0,0 +1,6 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace nRF82840_xxAA with your chip as listed in `probe-run --list-chips` +runner = "probe-run --chip nRF52840_xxAA" + +[build] +target = "thumbv7em-none-eabi" diff --git a/examples/boot/nrf/Cargo.toml b/examples/boot/nrf/Cargo.toml index 0a5bb8f9d..da8333b7c 100644 --- a/examples/boot/nrf/Cargo.toml +++ b/examples/boot/nrf/Cargo.toml @@ -6,7 +6,7 @@ version = "0.1.0" [dependencies] embassy = { version = "0.1.0", path = "../../../embassy", features = ["nightly"] } -embassy-nrf = { version = "0.1.0", path = "../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] } +embassy-nrf = { version = "0.1.0", path = "../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly", "nrf52840"] } embassy-boot-nrf = { version = "0.1.0", path = "../../../embassy-boot/nrf" } embassy-traits = { version = "0.1.0", path = "../../../embassy-traits" } diff --git a/examples/boot/nrf/README.md b/examples/boot/nrf/README.md index b97513a9d..453df7f31 100644 --- a/examples/boot/nrf/README.md +++ b/examples/boot/nrf/README.md @@ -17,15 +17,15 @@ application. ``` # Flash bootloader -cargo flash --manifest-path ../../embassy-boot/nrf/Cargo.toml --release --features embassy-nrf/nrf52840 --chip nRF52840_xxAA +cargo flash --manifest-path ../../../embassy-boot/nrf/Cargo.toml --features embassy-nrf/nrf52840 --release --chip nRF52840_xxAA # Build 'b' -cargo build --release --features embassy-nrf/nrf52840 --bin b +cargo build --release --bin b # Generate binary for 'b' -cargo objcopy --release --features embassy-nrf/nrf52840 --bin b -- -O binary b.bin +cargo objcopy --release --bin b -- -O binary b.bin ``` # Flash `a` (which includes b.bin) ``` -cargo flash --release --features embassy-nrf/nrf52840 --bin a --chip nRF52840_xxAA +cargo flash --release --bin a --chip nRF52840_xxAA ``` diff --git a/examples/boot/stm32l0/Cargo.toml b/examples/boot/stm32l0/Cargo.toml index 2e093d771..5cb1add5b 100644 --- a/examples/boot/stm32l0/Cargo.toml +++ b/examples/boot/stm32l0/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" [dependencies] embassy = { version = "0.1.0", path = "../../../embassy", features = ["nightly"] } embassy-stm32 = { version = "0.1.0", path = "../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } -embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32", features = ["flash-128", "invert-erase", "thumbv6"] } +embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32", features = ["thumbv6"] } embassy-traits = { version = "0.1.0", path = "../../../embassy-traits" } defmt = { version = "0.3", optional = true } diff --git a/examples/boot/stm32l0/README.md b/examples/boot/stm32l0/README.md index 9c8660821..b498fdc2d 100644 --- a/examples/boot/stm32l0/README.md +++ b/examples/boot/stm32l0/README.md @@ -15,7 +15,7 @@ application. ``` # Flash bootloader -cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32l072cz,flash-128,invert-erase,thumbv6 --chip STM32L072CZTx +cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32l072cz,thumbv6 --chip STM32L072CZTx # Build 'b' cargo build --release --bin b # Generate binary for 'b' diff --git a/examples/boot/stm32l0/memory.x b/examples/boot/stm32l0/memory.x index fd5bf1a5d..d0d2bd7bb 100644 --- a/examples/boot/stm32l0/memory.x +++ b/examples/boot/stm32l0/memory.x @@ -8,8 +8,8 @@ MEMORY RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 16K } -__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); -__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE); +__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); +__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); -__bootloader_dfu_start = ORIGIN(DFU); -__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU); +__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOTLOADER); +__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOTLOADER); diff --git a/examples/boot/stm32l1/Cargo.toml b/examples/boot/stm32l1/Cargo.toml index ec396bef2..9f97462f6 100644 --- a/examples/boot/stm32l1/Cargo.toml +++ b/examples/boot/stm32l1/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" [dependencies] embassy = { version = "0.1.0", path = "../../../embassy", features = ["nightly"] } embassy-stm32 = { version = "0.1.0", path = "../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } -embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32", features = ["flash-256", "invert-erase"] } +embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32" } embassy-traits = { version = "0.1.0", path = "../../../embassy-traits" } defmt = { version = "0.3", optional = true } diff --git a/examples/boot/stm32l1/README.md b/examples/boot/stm32l1/README.md index 1a9e85a75..0d4accbff 100644 --- a/examples/boot/stm32l1/README.md +++ b/examples/boot/stm32l1/README.md @@ -15,7 +15,7 @@ application. ``` # Flash bootloader -cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32l151cb-a,flash-256,invert-erase --chip STM32L151CBxxA +cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32l151cb-a --chip STM32L151CBxxA # Build 'b' cargo build --release --bin b # Generate binary for 'b' diff --git a/examples/boot/stm32l1/memory.x b/examples/boot/stm32l1/memory.x index fd5bf1a5d..d0d2bd7bb 100644 --- a/examples/boot/stm32l1/memory.x +++ b/examples/boot/stm32l1/memory.x @@ -8,8 +8,8 @@ MEMORY RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 16K } -__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); -__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE); +__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); +__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); -__bootloader_dfu_start = ORIGIN(DFU); -__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU); +__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOTLOADER); +__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOTLOADER); diff --git a/examples/boot/stm32l4/Cargo.toml b/examples/boot/stm32l4/Cargo.toml index 394f26a12..53424a666 100644 --- a/examples/boot/stm32l4/Cargo.toml +++ b/examples/boot/stm32l4/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" [dependencies] embassy = { version = "0.1.0", path = "../../../embassy", features = ["nightly"] } embassy-stm32 = { version = "0.1.0", path = "../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } -embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32", features = ["flash-2k"] } +embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32" } embassy-traits = { version = "0.1.0", path = "../../../embassy-traits" } defmt = { version = "0.3", optional = true } diff --git a/examples/boot/stm32l4/README.md b/examples/boot/stm32l4/README.md index 09e09d6ef..8966c2fb5 100644 --- a/examples/boot/stm32l4/README.md +++ b/examples/boot/stm32l4/README.md @@ -15,7 +15,7 @@ application. ``` # Flash bootloader -cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32l475vg,flash-2k --chip STM32L475VG +cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32l475vg --chip STM32L475VG # Build 'b' cargo build --release --bin b # Generate binary for 'b' diff --git a/examples/boot/stm32l4/memory.x b/examples/boot/stm32l4/memory.x index fd5bf1a5d..14b2a2c9f 100644 --- a/examples/boot/stm32l4/memory.x +++ b/examples/boot/stm32l4/memory.x @@ -5,11 +5,11 @@ MEMORY BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K FLASH : ORIGIN = 0x08008000, LENGTH = 32K DFU : ORIGIN = 0x08010000, LENGTH = 36K - RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 16K + RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 32K } -__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); -__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE); +__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); +__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); -__bootloader_dfu_start = ORIGIN(DFU); -__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU); +__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOTLOADER); +__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOTLOADER); diff --git a/examples/boot/stm32wl/Cargo.toml b/examples/boot/stm32wl/Cargo.toml index 9c69f4a65..fb64886e6 100644 --- a/examples/boot/stm32wl/Cargo.toml +++ b/examples/boot/stm32wl/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" [dependencies] embassy = { version = "0.1.0", path = "../../../embassy", features = ["nightly"] } embassy-stm32 = { version = "0.1.0", path = "../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } -embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32", features = ["flash-2k"] } +embassy-boot-stm32 = { version = "0.1.0", path = "../../../embassy-boot/stm32" } embassy-traits = { version = "0.1.0", path = "../../../embassy-traits" } defmt = { version = "0.3", optional = true } diff --git a/examples/boot/stm32wl/README.md b/examples/boot/stm32wl/README.md index a26a23852..edcdacf91 100644 --- a/examples/boot/stm32wl/README.md +++ b/examples/boot/stm32wl/README.md @@ -15,7 +15,7 @@ application. ``` # Flash bootloader -cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32wl55jc-cm4,flash-2k --chip STM32WLE5JCIx +cargo flash --manifest-path ../../../embassy-boot/stm32/Cargo.toml --release --features embassy-stm32/stm32wl55jc-cm4 --chip STM32WLE5JCIx # Build 'b' cargo build --release --bin b # Generate binary for 'b' diff --git a/examples/boot/stm32wl/memory.x b/examples/boot/stm32wl/memory.x index 78dd69c35..14b2a2c9f 100644 --- a/examples/boot/stm32wl/memory.x +++ b/examples/boot/stm32wl/memory.x @@ -8,8 +8,8 @@ MEMORY RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 32K } -__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); -__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE); +__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); +__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); -__bootloader_dfu_start = ORIGIN(DFU); -__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU); +__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOTLOADER); +__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOTLOADER); diff --git a/examples/boot/stm32wl/src/bin/a.rs b/examples/boot/stm32wl/src/bin/a.rs index b1f4a4a03..d01a72f2d 100644 --- a/examples/boot/stm32wl/src/bin/a.rs +++ b/examples/boot/stm32wl/src/bin/a.rs @@ -17,16 +17,18 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy::main] async fn main(_s: embassy::executor::Spawner, p: Peripherals) { - let flash = Flash::new(p.FLASH); + let flash = Flash::unlock(p.FLASH); let mut flash = BlockingAsync::new(flash); let button = Input::new(p.PA0, Pull::Up); let mut button = ExtiInput::new(button, p.EXTI0); let mut led = Output::new(p.PB9, Level::Low, Speed::Low); + led.set_high(); let mut updater = FirmwareUpdater::default(); button.wait_for_falling_edge().await; + //defmt::info!("Starting update"); let mut offset = 0; for chunk in APP_B.chunks(2048) { let mut buf: [u8; 2048] = [0; 2048]; @@ -39,7 +41,7 @@ async fn main(_s: embassy::executor::Spawner, p: Peripherals) { offset += chunk.len(); } updater.mark_update(&mut flash).await.unwrap(); - // defmt::info!("Marked as updated"); - led.set_high(); + //defmt::info!("Marked as updated"); + led.set_low(); cortex_m::peripheral::SCB::sys_reset(); } diff --git a/examples/stm32l0/src/bin/flash.rs b/examples/stm32l0/src/bin/flash.rs index 0ab7b133b..c2ccb5b69 100644 --- a/examples/stm32l0/src/bin/flash.rs +++ b/examples/stm32l0/src/bin/flash.rs @@ -15,7 +15,7 @@ use panic_probe as _; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello Flash!"); - const ADDR: u32 = 0x8026000; + const ADDR: u32 = 0x26000; let mut f = Flash::unlock(p.FLASH); diff --git a/examples/stm32l1/src/bin/flash.rs b/examples/stm32l1/src/bin/flash.rs index b234289af..eea838cba 100644 --- a/examples/stm32l1/src/bin/flash.rs +++ b/examples/stm32l1/src/bin/flash.rs @@ -15,7 +15,7 @@ use panic_probe as _; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello Flash!"); - const ADDR: u32 = 0x8026000; + const ADDR: u32 = 0x26000; let mut f = Flash::unlock(p.FLASH); diff --git a/examples/stm32wl/src/bin/flash.rs b/examples/stm32wl/src/bin/flash.rs index 9e13c702a..f84818224 100644 --- a/examples/stm32wl/src/bin/flash.rs +++ b/examples/stm32wl/src/bin/flash.rs @@ -15,7 +15,7 @@ use panic_probe as _; async fn main(_spawner: Spawner, p: Peripherals) { info!("Hello Flash!"); - const ADDR: u32 = 0x8036000; + const ADDR: u32 = 0x36000; let mut f = Flash::unlock(p.FLASH); diff --git a/stm32-data b/stm32-data index 419701c83..5d2577752 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit 419701c835dd0da3c37d8de02c95115f500dfa6b +Subproject commit 5d25777521bfdb493674d43944b6df191606ef08 diff --git a/stm32-metapac-gen/src/data.rs b/stm32-metapac-gen/src/data.rs index a74c60ac0..17eccfe9a 100644 --- a/stm32-metapac-gen/src/data.rs +++ b/stm32-metapac-gen/src/data.rs @@ -16,6 +16,14 @@ pub struct MemoryRegion { pub kind: MemoryRegionKind, pub address: u32, pub size: u32, + pub settings: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone, Deserialize)] +pub struct FlashSettings { + pub erase_size: u32, + pub write_size: u32, + pub erase_value: u8, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs index c959e1a61..f5d61ca31 100644 --- a/stm32-metapac-gen/src/lib.rs +++ b/stm32-metapac-gen/src/lib.rs @@ -129,6 +129,40 @@ impl Gen { ) .unwrap(); + let flash = chip.memory.iter().find(|r| r.name == "BANK_1").unwrap(); + write!( + &mut extra, + "pub const FLASH_BASE: usize = {};\n", + flash.address, + ) + .unwrap(); + write!( + &mut extra, + "pub const FLASH_SIZE: usize = {};\n", + flash.size, + ) + .unwrap(); + if let Some(settings) = &flash.settings { + write!( + &mut extra, + "pub const ERASE_SIZE: usize = {};\n", + settings.erase_size, + ) + .unwrap(); + write!( + &mut extra, + "pub const WRITE_SIZE: usize = {};\n", + settings.write_size, + ) + .unwrap(); + write!( + &mut extra, + "pub const ERASE_VALUE: u8 = {};\n", + settings.erase_value, + ) + .unwrap(); + } + // Cleanups! transform::sort::Sort {}.run(&mut ir).unwrap(); transform::Sanitize {}.run(&mut ir).unwrap(); diff --git a/stm32-metapac/src/metadata.rs b/stm32-metapac/src/metadata.rs index 23b759f6c..d05830e94 100644 --- a/stm32-metapac/src/metadata.rs +++ b/stm32-metapac/src/metadata.rs @@ -15,6 +15,14 @@ pub struct MemoryRegion { pub kind: MemoryRegionKind, pub address: u32, pub size: u32, + pub settings: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct FlashSettings { + pub erase_size: u32, + pub write_size: u32, + pub erase_value: u8, } #[derive(Debug, Eq, PartialEq, Clone)]