aboutsummaryrefslogtreecommitdiff
path: root/examples/boot/application
diff options
context:
space:
mode:
authorQuentin Smith <[email protected]>2023-07-17 21:31:43 -0400
committerQuentin Smith <[email protected]>2023-07-17 21:31:43 -0400
commit6f02403184eb7fb7990fb88fc9df9c4328a690a3 (patch)
tree748f510e190bb2724750507a6e69ed1a8e08cb20 /examples/boot/application
parentd896f80405aa8963877049ed999e4aba25d6e2bb (diff)
parent6b5df4523aa1c4902f02e803450ae4b418e0e3ca (diff)
Merge remote-tracking branch 'origin/main' into nrf-pdm
Diffstat (limited to 'examples/boot/application')
-rw-r--r--examples/boot/application/nrf/.cargo/config.toml4
-rw-r--r--examples/boot/application/nrf/Cargo.toml21
-rw-r--r--examples/boot/application/nrf/README.md14
-rw-r--r--examples/boot/application/nrf/memory-bl-nrf91.x19
-rw-r--r--examples/boot/application/nrf/memory-bl.x2
-rw-r--r--examples/boot/application/nrf/memory-nrf91.x16
-rw-r--r--examples/boot/application/nrf/memory.x2
-rw-r--r--examples/boot/application/nrf/src/bin/a.rs41
-rw-r--r--examples/boot/application/nrf/src/bin/b.rs6
-rw-r--r--examples/boot/application/rp/.cargo/config.toml12
-rw-r--r--examples/boot/application/rp/Cargo.toml35
-rw-r--r--examples/boot/application/rp/README.md28
-rw-r--r--examples/boot/application/rp/build.rs35
-rw-r--r--examples/boot/application/rp/memory.x15
-rw-r--r--examples/boot/application/rp/src/bin/a.rs67
-rw-r--r--examples/boot/application/rp/src/bin/b.rs23
-rw-r--r--examples/boot/application/stm32f3/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32f3/Cargo.toml14
-rw-r--r--examples/boot/application/stm32f3/src/bin/a.rs20
-rw-r--r--examples/boot/application/stm32f7/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32f7/Cargo.toml15
-rw-r--r--examples/boot/application/stm32f7/src/bin/a.rs33
-rw-r--r--examples/boot/application/stm32h7/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32h7/Cargo.toml15
-rwxr-xr-xexamples/boot/application/stm32h7/flash-boot.sh3
-rw-r--r--examples/boot/application/stm32h7/src/bin/a.rs33
-rw-r--r--examples/boot/application/stm32l0/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32l0/Cargo.toml14
-rw-r--r--examples/boot/application/stm32l0/src/bin/a.rs20
-rw-r--r--examples/boot/application/stm32l1/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32l1/Cargo.toml14
-rw-r--r--examples/boot/application/stm32l1/src/bin/a.rs20
-rw-r--r--examples/boot/application/stm32l4/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32l4/Cargo.toml14
-rw-r--r--examples/boot/application/stm32l4/src/bin/a.rs20
-rw-r--r--examples/boot/application/stm32wl/.cargo/config.toml4
-rw-r--r--examples/boot/application/stm32wl/Cargo.toml14
-rw-r--r--examples/boot/application/stm32wl/src/bin/a.rs20
38 files changed, 497 insertions, 140 deletions
diff --git a/examples/boot/application/nrf/.cargo/config.toml b/examples/boot/application/nrf/.cargo/config.toml
index 8ca28df39..17616a054 100644
--- a/examples/boot/application/nrf/.cargo/config.toml
+++ b/examples/boot/application/nrf/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace nRF82840_xxAA with your chip as listed in `probe-run --list-chips` 2# replace nRF82840_xxAA with your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip nRF52840_xxAA" 3runner = "probe-rs run --chip nRF52840_xxAA"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabi" 6target = "thumbv7em-none-eabi"
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index b9ff92578..2a0cf7818 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -2,19 +2,26 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-nrf-examples" 3name = "embassy-boot-nrf-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync" }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly"] }
10embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly", "nrf52840"] } 11embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] }
11embassy-boot-nrf = { version = "0.1.0", path = "../../../../embassy-boot/nrf" } 12embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot", features = ["nightly"] }
13embassy-boot-nrf = { version = "0.1.0", path = "../../../../embassy-boot/nrf", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 14embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 15
14defmt = { version = "0.3", optional = true } 16defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 17defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 18panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 19embedded-hal = { version = "0.2.6" }
18 20
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
23
24[features]
25ed25519-dalek = ["embassy-boot/ed25519-dalek"]
26ed25519-salty = ["embassy-boot/ed25519-salty"]
27skip-include = []
diff --git a/examples/boot/application/nrf/README.md b/examples/boot/application/nrf/README.md
index 703377a20..9d6d20336 100644
--- a/examples/boot/application/nrf/README.md
+++ b/examples/boot/application/nrf/README.md
@@ -1,6 +1,6 @@
1# Examples using bootloader 1# Examples using bootloader
2 2
3Example for nRF52 demonstrating the bootloader. The example consists of application binaries, 'a' 3Example for nRF demonstrating the bootloader. The example consists of application binaries, 'a'
4which allows you to press a button to start the DFU process, and 'b' which is the updated 4which allows you to press a button to start the DFU process, and 'b' which is the updated
5application. 5application.
6 6
@@ -20,15 +20,19 @@ application.
20cp memory-bl.x ../../bootloader/nrf/memory.x 20cp memory-bl.x ../../bootloader/nrf/memory.x
21 21
22# Flash bootloader 22# Flash bootloader
23cargo flash --manifest-path ../../bootloader/nrf/Cargo.toml --features embassy-nrf/nrf52840 --release --chip nRF52840_xxAA 23cargo flash --manifest-path ../../bootloader/nrf/Cargo.toml --features embassy-nrf/nrf52840 --target thumbv7em-none-eabi --release --chip nRF52840_xxAA
24# Build 'b' 24# Build 'b'
25cargo build --release --bin b 25cargo build --release --bin b --features embassy-nrf/nrf52840
26# Generate binary for 'b' 26# Generate binary for 'b'
27cargo objcopy --release --bin b -- -O binary b.bin 27cargo objcopy --release --bin b --features embassy-nrf/nrf52840 --target thumbv7em-none-eabi -- -O binary b.bin
28``` 28```
29 29
30# Flash `a` (which includes b.bin) 30# Flash `a` (which includes b.bin)
31 31
32``` 32```
33cargo flash --release --bin a --chip nRF52840_xxAA 33cargo flash --release --bin a --features embassy-nrf/nrf52840 --target thumbv7em-none-eabi --chip nRF52840_xxAA
34``` 34```
35
36You should then see a solid LED. Pressing button 1 will cause the DFU to be loaded by the bootloader. Upon
37successfully loading, you'll see the LED flash. After 5 seconds, because there is no petting of the watchdog,
38you'll see the LED go solid again. This indicates that the bootloader has reverted the update.
diff --git a/examples/boot/application/nrf/memory-bl-nrf91.x b/examples/boot/application/nrf/memory-bl-nrf91.x
new file mode 100644
index 000000000..14ceffa73
--- /dev/null
+++ b/examples/boot/application/nrf/memory-bl-nrf91.x
@@ -0,0 +1,19 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 /* Assumes Secure Partition Manager (SPM) flashed at the start */
5 FLASH : ORIGIN = 0x00050000, LENGTH = 24K
6 BOOTLOADER_STATE : ORIGIN = 0x00056000, LENGTH = 4K
7 ACTIVE : ORIGIN = 0x00057000, LENGTH = 64K
8 DFU : ORIGIN = 0x00067000, LENGTH = 68K
9 RAM (rwx) : ORIGIN = 0x20018000, LENGTH = 32K
10}
11
12__bootloader_state_start = ORIGIN(BOOTLOADER_STATE);
13__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE);
14
15__bootloader_active_start = ORIGIN(ACTIVE);
16__bootloader_active_end = ORIGIN(ACTIVE) + LENGTH(ACTIVE);
17
18__bootloader_dfu_start = ORIGIN(DFU);
19__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU);
diff --git a/examples/boot/application/nrf/memory-bl.x b/examples/boot/application/nrf/memory-bl.x
index 8a32b905f..257d65644 100644
--- a/examples/boot/application/nrf/memory-bl.x
+++ b/examples/boot/application/nrf/memory-bl.x
@@ -5,7 +5,7 @@ MEMORY
5 BOOTLOADER_STATE : ORIGIN = 0x00006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x00006000, LENGTH = 4K
6 ACTIVE : ORIGIN = 0x00007000, LENGTH = 64K 6 ACTIVE : ORIGIN = 0x00007000, LENGTH = 64K
7 DFU : ORIGIN = 0x00017000, LENGTH = 68K 7 DFU : ORIGIN = 0x00017000, LENGTH = 68K
8 RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 32K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9} 9}
10 10
11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); 11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE);
diff --git a/examples/boot/application/nrf/memory-nrf91.x b/examples/boot/application/nrf/memory-nrf91.x
new file mode 100644
index 000000000..2bc13c0d6
--- /dev/null
+++ b/examples/boot/application/nrf/memory-nrf91.x
@@ -0,0 +1,16 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 /* Assumes Secure Partition Manager (SPM) flashed at the start */
5 BOOTLOADER : ORIGIN = 0x00050000, LENGTH = 24K
6 BOOTLOADER_STATE : ORIGIN = 0x00056000, LENGTH = 4K
7 FLASH : ORIGIN = 0x00057000, LENGTH = 64K
8 DFU : ORIGIN = 0x00067000, LENGTH = 68K
9 RAM (rwx) : ORIGIN = 0x20018000, LENGTH = 32K
10}
11
12__bootloader_state_start = ORIGIN(BOOTLOADER_STATE);
13__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE);
14
15__bootloader_dfu_start = ORIGIN(DFU);
16__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU);
diff --git a/examples/boot/application/nrf/memory.x b/examples/boot/application/nrf/memory.x
index 3a54ca460..c6926e422 100644
--- a/examples/boot/application/nrf/memory.x
+++ b/examples/boot/application/nrf/memory.x
@@ -5,7 +5,7 @@ MEMORY
5 BOOTLOADER_STATE : ORIGIN = 0x00006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x00006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x00007000, LENGTH = 64K 6 FLASH : ORIGIN = 0x00007000, LENGTH = 64K
7 DFU : ORIGIN = 0x00017000, LENGTH = 68K 7 DFU : ORIGIN = 0x00017000, LENGTH = 68K
8 RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 32K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9} 9}
10 10
11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE); 11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE);
diff --git a/examples/boot/application/nrf/src/bin/a.rs b/examples/boot/application/nrf/src/bin/a.rs
index bd8fa3246..021d77f3b 100644
--- a/examples/boot/application/nrf/src/bin/a.rs
+++ b/examples/boot/application/nrf/src/bin/a.rs
@@ -1,42 +1,71 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![macro_use] 3#![macro_use]
4#![feature(generic_associated_types)]
5#![feature(type_alias_impl_trait)] 4#![feature(type_alias_impl_trait)]
6 5
7use embassy_boot_nrf::FirmwareUpdater; 6use embassy_boot_nrf::{FirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync; 7use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 8use embassy_executor::Spawner;
10use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
11use embassy_nrf::nvmc::Nvmc; 10use embassy_nrf::nvmc::Nvmc;
11use embassy_nrf::wdt::{self, Watchdog};
12use embassy_sync::mutex::Mutex;
12use panic_reset as _; 13use panic_reset as _;
13 14
15#[cfg(feature = "skip-include")]
16static APP_B: &[u8] = &[0, 1, 2, 3];
17#[cfg(not(feature = "skip-include"))]
14static APP_B: &[u8] = include_bytes!("../../b.bin"); 18static APP_B: &[u8] = include_bytes!("../../b.bin");
15 19
16#[embassy_executor::main] 20#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 21async fn main(_spawner: Spawner) {
18 let p = embassy_nrf::init(Default::default()); 22 let p = embassy_nrf::init(Default::default());
23
19 let mut button = Input::new(p.P0_11, Pull::Up); 24 let mut button = Input::new(p.P0_11, Pull::Up);
20 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); 25 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
26
21 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard); 27 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard);
22 //let mut button = Input::new(p.P1_02, Pull::Up); 28 //let mut button = Input::new(p.P1_02, Pull::Up);
23 29
30 // nRF91 DK
31 // let mut led = Output::new(p.P0_02, Level::Low, OutputDrive::Standard);
32 // let mut button = Input::new(p.P0_06, Pull::Up);
33
34 // The following code block illustrates how to obtain a watchdog that is configured
35 // as per the existing watchdog. Ordinarily, we'd use the handle returned to "pet" the
36 // watchdog periodically. If we don't, and we're not going to for this example, then
37 // the watchdog will cause the device to reset as per its configured timeout in the bootloader.
38 // This helps is avoid a situation where new firmware might be bad and block our executor.
39 // If firmware is bad in this way then the bootloader will revert to any previous version.
40 let wdt_config = wdt::Config::try_new(&p.WDT).unwrap();
41 let (_wdt, [_wdt_handle]) = match Watchdog::try_new(p.WDT, wdt_config) {
42 Ok(x) => x,
43 Err(_) => {
44 // Watchdog already active with the wrong number of handles, waiting for it to timeout...
45 loop {
46 cortex_m::asm::wfe();
47 }
48 }
49 };
50
24 let nvmc = Nvmc::new(p.NVMC); 51 let nvmc = Nvmc::new(p.NVMC);
25 let mut nvmc = BlockingAsync::new(nvmc); 52 let nvmc = Mutex::new(BlockingAsync::new(nvmc));
26 53
27 let mut updater = FirmwareUpdater::default(); 54 let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc);
55 let mut updater = FirmwareUpdater::new(config);
28 loop { 56 loop {
29 led.set_low(); 57 led.set_low();
30 button.wait_for_any_edge().await; 58 button.wait_for_any_edge().await;
31 if button.is_low() { 59 if button.is_low() {
32 let mut offset = 0; 60 let mut offset = 0;
61 let mut magic = [0; 4];
33 for chunk in APP_B.chunks(4096) { 62 for chunk in APP_B.chunks(4096) {
34 let mut buf: [u8; 4096] = [0; 4096]; 63 let mut buf: [u8; 4096] = [0; 4096];
35 buf[..chunk.len()].copy_from_slice(chunk); 64 buf[..chunk.len()].copy_from_slice(chunk);
36 updater.write_firmware(offset, &buf, &mut nvmc, 4096).await.unwrap(); 65 updater.write_firmware(&mut magic, offset, &buf).await.unwrap();
37 offset += chunk.len(); 66 offset += chunk.len();
38 } 67 }
39 updater.update(&mut nvmc).await.unwrap(); 68 updater.mark_updated(&mut magic).await.unwrap();
40 led.set_high(); 69 led.set_high();
41 cortex_m::peripheral::SCB::sys_reset(); 70 cortex_m::peripheral::SCB::sys_reset();
42 } 71 }
diff --git a/examples/boot/application/nrf/src/bin/b.rs b/examples/boot/application/nrf/src/bin/b.rs
index 5394bf0c7..15ebce5fa 100644
--- a/examples/boot/application/nrf/src/bin/b.rs
+++ b/examples/boot/application/nrf/src/bin/b.rs
@@ -1,7 +1,6 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![macro_use] 3#![macro_use]
4#![feature(generic_associated_types)]
5#![feature(type_alias_impl_trait)] 4#![feature(type_alias_impl_trait)]
6 5
7use embassy_executor::Spawner; 6use embassy_executor::Spawner;
@@ -13,7 +12,10 @@ use panic_reset as _;
13async fn main(_spawner: Spawner) { 12async fn main(_spawner: Spawner) {
14 let p = embassy_nrf::init(Default::default()); 13 let p = embassy_nrf::init(Default::default());
15 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); 14 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
16 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard); 15 // let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard);
16
17 // nRF91 DK
18 // let mut led = Output::new(p.P0_02, Level::Low, OutputDrive::Standard);
17 19
18 loop { 20 loop {
19 led.set_high(); 21 led.set_high();
diff --git a/examples/boot/application/rp/.cargo/config.toml b/examples/boot/application/rp/.cargo/config.toml
new file mode 100644
index 000000000..cd8d1ef02
--- /dev/null
+++ b/examples/boot/application/rp/.cargo/config.toml
@@ -0,0 +1,12 @@
1[unstable]
2build-std = ["core"]
3build-std-features = ["panic_immediate_abort"]
4
5[target.'cfg(all(target_arch = "arm", target_os = "none"))']
6runner = "probe-rs run --chip RP2040"
7
8[build]
9target = "thumbv6m-none-eabi"
10
11[env]
12DEFMT_LOG = "trace"
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml
new file mode 100644
index 000000000..95b2da954
--- /dev/null
+++ b/examples/boot/application/rp/Cargo.toml
@@ -0,0 +1,35 @@
1[package]
2edition = "2021"
3name = "embassy-boot-rp-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly"] }
11embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] }
12embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp", features = ["nightly"] }
13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
14
15defmt = "0.3"
16defmt-rtt = "0.4"
17panic-probe = { version = "0.3", features = ["print-defmt"], optional = true }
18panic-reset = { version = "0.1.1", optional = true }
19embedded-hal = { version = "0.2.6" }
20
21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
22cortex-m-rt = "0.7.0"
23embedded-storage = "0.3.0"
24
25[features]
26default = ["panic-reset"]
27debug = [
28 "embassy-rp/defmt",
29 "embassy-boot-rp/defmt",
30 "panic-probe"
31]
32skip-include = []
33
34[profile.release]
35debug = true
diff --git a/examples/boot/application/rp/README.md b/examples/boot/application/rp/README.md
new file mode 100644
index 000000000..41304c526
--- /dev/null
+++ b/examples/boot/application/rp/README.md
@@ -0,0 +1,28 @@
1# Examples using bootloader
2
3Example for Raspberry Pi Pico demonstrating the bootloader. The example consists of application binaries, 'a'
4which waits for 5 seconds before flashing the 'b' binary, which blinks the LED.
5
6NOTE: The 'b' binary does not mark the new binary as active, so if you reset the device, it will roll back to the 'a' binary before automatically updating it again.
7
8## Prerequisites
9
10* `cargo-binutils`
11* `cargo-flash`
12* `embassy-boot-rp`
13
14## Usage
15
16```
17# Flash bootloader
18cargo flash --manifest-path ../../bootloader/rp/Cargo.toml --release --chip RP2040
19
20# Build 'b'
21cargo build --release --bin b
22
23# Generate binary for 'b'
24cargo objcopy --release --bin b -- -O binary b.bin
25
26# Flash `a` (which includes b.bin)
27cargo flash --release --bin a --chip RP2040
28```
diff --git a/examples/boot/application/rp/build.rs b/examples/boot/application/rp/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/boot/application/rp/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/boot/application/rp/memory.x b/examples/boot/application/rp/memory.x
new file mode 100644
index 000000000..c19473114
--- /dev/null
+++ b/examples/boot/application/rp/memory.x
@@ -0,0 +1,15 @@
1MEMORY
2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
5 BOOTLOADER_STATE : ORIGIN = 0x10006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x10007000, LENGTH = 512K
7 DFU : ORIGIN = 0x10087000, LENGTH = 516K
8 RAM : ORIGIN = 0x20000000, LENGTH = 256K
9}
10
11__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOT2);
12__bootloader_state_end = ORIGIN(BOOTLOADER_STATE) + LENGTH(BOOTLOADER_STATE) - ORIGIN(BOOT2);
13
14__bootloader_dfu_start = ORIGIN(DFU) - ORIGIN(BOOT2);
15__bootloader_dfu_end = ORIGIN(DFU) + LENGTH(DFU) - ORIGIN(BOOT2);
diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs
new file mode 100644
index 000000000..c8497494c
--- /dev/null
+++ b/examples/boot/application/rp/src/bin/a.rs
@@ -0,0 +1,67 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use core::cell::RefCell;
6
7use defmt_rtt as _;
8use embassy_boot_rp::*;
9use embassy_executor::Spawner;
10use embassy_rp::flash::Flash;
11use embassy_rp::gpio::{Level, Output};
12use embassy_rp::watchdog::Watchdog;
13use embassy_sync::blocking_mutex::Mutex;
14use embassy_time::{Duration, Timer};
15use embedded_storage::nor_flash::NorFlash;
16#[cfg(feature = "panic-probe")]
17use panic_probe as _;
18#[cfg(feature = "panic-reset")]
19use panic_reset as _;
20
21#[cfg(feature = "skip-include")]
22static APP_B: &[u8] = &[0, 1, 2, 3];
23#[cfg(not(feature = "skip-include"))]
24static APP_B: &[u8] = include_bytes!("../../b.bin");
25
26const FLASH_SIZE: usize = 2 * 1024 * 1024;
27
28#[embassy_executor::main]
29async fn main(_s: Spawner) {
30 let p = embassy_rp::init(Default::default());
31 let mut led = Output::new(p.PIN_25, Level::Low);
32
33 // Override bootloader watchdog
34 let mut watchdog = Watchdog::new(p.WATCHDOG);
35 watchdog.start(Duration::from_secs(8));
36
37 let flash: Flash<_, FLASH_SIZE> = Flash::new(p.FLASH);
38 let flash = Mutex::new(RefCell::new(flash));
39
40 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash);
41 let mut updater = BlockingFirmwareUpdater::new(config);
42
43 Timer::after(Duration::from_secs(5)).await;
44 watchdog.feed();
45 led.set_high();
46 let mut offset = 0;
47 let mut buf: AlignedBuffer<4096> = AlignedBuffer([0; 4096]);
48 defmt::info!("preparing update");
49 let writer = updater
50 .prepare_update(&mut buf.0[..1])
51 .map_err(|e| defmt::warn!("E: {:?}", defmt::Debug2Format(&e)))
52 .unwrap();
53 defmt::info!("writer created, starting write");
54 for chunk in APP_B.chunks(4096) {
55 buf.0[..chunk.len()].copy_from_slice(chunk);
56 defmt::info!("writing block at offset {}", offset);
57 writer.write(offset, &buf.0[..]).unwrap();
58 offset += chunk.len() as u32;
59 }
60 watchdog.feed();
61 defmt::info!("firmware written, marking update");
62 updater.mark_updated(&mut buf.0[..1]).unwrap();
63 Timer::after(Duration::from_secs(2)).await;
64 led.set_low();
65 defmt::info!("update marked, resetting");
66 cortex_m::peripheral::SCB::sys_reset();
67}
diff --git a/examples/boot/application/rp/src/bin/b.rs b/examples/boot/application/rp/src/bin/b.rs
new file mode 100644
index 000000000..47dec329c
--- /dev/null
+++ b/examples/boot/application/rp/src/bin/b.rs
@@ -0,0 +1,23 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use embassy_executor::Spawner;
6use embassy_rp::gpio;
7use embassy_time::{Duration, Timer};
8use gpio::{Level, Output};
9use {defmt_rtt as _, panic_reset as _};
10
11#[embassy_executor::main]
12async fn main(_s: Spawner) {
13 let p = embassy_rp::init(Default::default());
14 let mut led = Output::new(p.PIN_25, Level::Low);
15
16 loop {
17 led.set_high();
18 Timer::after(Duration::from_millis(100)).await;
19
20 led.set_low();
21 Timer::after(Duration::from_millis(100)).await;
22 }
23}
diff --git a/examples/boot/application/stm32f3/.cargo/config.toml b/examples/boot/application/stm32f3/.cargo/config.toml
index a76d6cab4..4a7ec0a5b 100644
--- a/examples/boot/application/stm32f3/.cargo/config.toml
+++ b/examples/boot/application/stm32f3/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32F429ZITx with your chip as listed in `probe-run --list-chips` 2# replace STM32F429ZITx with your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32F303VCTx" 3runner = "probe-rs run --chip STM32F303VCTx"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabihf" 6target = "thumbv7em-none-eabihf"
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index f143d1e8d..3b0fc4d9d 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -2,21 +2,22 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32f3-examples" 3name = "embassy-boot-stm32f3-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
18 19
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
21 22
22[features] 23[features]
@@ -25,3 +26,4 @@ defmt = [
25 "embassy-stm32/defmt", 26 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 27 "embassy-boot-stm32/defmt",
27] 28]
29skip-include = []
diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs
index 11eecc5e2..c0a11d699 100644
--- a/examples/boot/application/stm32f3/src/bin/a.rs
+++ b/examples/boot/application/stm32f3/src/bin/a.rs
@@ -4,21 +4,25 @@
4 4
5#[cfg(feature = "defmt-rtt")] 5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 6use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 7use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync; 8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex;
13use panic_reset as _; 14use panic_reset as _;
14 15
16#[cfg(feature = "skip-include")]
17static APP_B: &[u8] = &[0, 1, 2, 3];
18#[cfg(not(feature = "skip-include"))]
15static APP_B: &[u8] = include_bytes!("../../b.bin"); 19static APP_B: &[u8] = include_bytes!("../../b.bin");
16 20
17#[embassy_executor::main] 21#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
19 let p = embassy_stm32::init(Default::default()); 23 let p = embassy_stm32::init(Default::default());
20 let flash = Flash::unlock(p.FLASH); 24 let flash = Flash::new_blocking(p.FLASH);
21 let mut flash = BlockingAsync::new(flash); 25 let flash = Mutex::new(BlockingAsync::new(flash));
22 26
23 let button = Input::new(p.PC13, Pull::Up); 27 let button = Input::new(p.PC13, Pull::Up);
24 let mut button = ExtiInput::new(button, p.EXTI13); 28 let mut button = ExtiInput::new(button, p.EXTI13);
@@ -26,16 +30,18 @@ async fn main(_spawner: Spawner) {
26 let mut led = Output::new(p.PA5, Level::Low, Speed::Low); 30 let mut led = Output::new(p.PA5, Level::Low, Speed::Low);
27 led.set_high(); 31 led.set_high();
28 32
29 let mut updater = FirmwareUpdater::default(); 33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash);
34 let mut updater = FirmwareUpdater::new(config);
30 button.wait_for_falling_edge().await; 35 button.wait_for_falling_edge().await;
31 let mut offset = 0; 36 let mut offset = 0;
37 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
32 for chunk in APP_B.chunks(2048) { 38 for chunk in APP_B.chunks(2048) {
33 let mut buf: [u8; 2048] = [0; 2048]; 39 let mut buf: [u8; 2048] = [0; 2048];
34 buf[..chunk.len()].copy_from_slice(chunk); 40 buf[..chunk.len()].copy_from_slice(chunk);
35 updater.write_firmware(offset, &buf, &mut flash, 2048).await.unwrap(); 41 updater.write_firmware(magic.as_mut(), offset, &buf).await.unwrap();
36 offset += chunk.len(); 42 offset += chunk.len();
37 } 43 }
38 updater.update(&mut flash).await.unwrap(); 44 updater.mark_updated(magic.as_mut()).await.unwrap();
39 led.set_low(); 45 led.set_low();
40 cortex_m::peripheral::SCB::sys_reset(); 46 cortex_m::peripheral::SCB::sys_reset();
41} 47}
diff --git a/examples/boot/application/stm32f7/.cargo/config.toml b/examples/boot/application/stm32f7/.cargo/config.toml
index a90e1ccbb..9088eea6e 100644
--- a/examples/boot/application/stm32f7/.cargo/config.toml
+++ b/examples/boot/application/stm32f7/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32F429ZITx with your chip as listed in `probe-run --list-chips` 2# replace STM32F429ZITx with your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32F767ZITx -v" 3runner = "probe-rs run --chip STM32F767ZITx"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabihf" 6target = "thumbv7em-none-eabihf"
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index 29c87eee1..323b4ab2c 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -2,21 +2,23 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32f7-examples" 3name = "embassy-boot-stm32f7-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19embedded-storage = "0.3.0"
18 20
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
21 23
22[features] 24[features]
@@ -25,3 +27,4 @@ defmt = [
25 "embassy-stm32/defmt", 27 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 28 "embassy-boot-stm32/defmt",
27] 29]
30skip-include = []
diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs
index a3b66e7c9..dea682a96 100644
--- a/examples/boot/application/stm32f7/src/bin/a.rs
+++ b/examples/boot/application/stm32f7/src/bin/a.rs
@@ -2,23 +2,29 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use core::cell::RefCell;
6
5#[cfg(feature = "defmt-rtt")] 7#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 8use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 9use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 10use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 11use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 12use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 13use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
14use embassy_sync::blocking_mutex::Mutex;
15use embedded_storage::nor_flash::NorFlash;
13use panic_reset as _; 16use panic_reset as _;
14 17
18#[cfg(feature = "skip-include")]
19static APP_B: &[u8] = &[0, 1, 2, 3];
20#[cfg(not(feature = "skip-include"))]
15static APP_B: &[u8] = include_bytes!("../../b.bin"); 21static APP_B: &[u8] = include_bytes!("../../b.bin");
16 22
17#[embassy_executor::main] 23#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
19 let p = embassy_stm32::init(Default::default()); 25 let p = embassy_stm32::init(Default::default());
20 let flash = Flash::unlock(p.FLASH); 26 let flash = Flash::new_blocking(p.FLASH);
21 let mut flash = BlockingAsync::new(flash); 27 let flash = Mutex::new(RefCell::new(flash));
22 28
23 let button = Input::new(p.PC13, Pull::Down); 29 let button = Input::new(p.PC13, Pull::Down);
24 let mut button = ExtiInput::new(button, p.EXTI13); 30 let mut button = ExtiInput::new(button, p.EXTI13);
@@ -26,16 +32,19 @@ async fn main(_spawner: Spawner) {
26 let mut led = Output::new(p.PB7, Level::Low, Speed::Low); 32 let mut led = Output::new(p.PB7, Level::Low, Speed::Low);
27 led.set_high(); 33 led.set_high();
28 34
29 let mut updater = FirmwareUpdater::default(); 35 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash);
36 let mut updater = BlockingFirmwareUpdater::new(config);
37 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
38 let writer = updater.prepare_update(magic.as_mut()).unwrap();
30 button.wait_for_rising_edge().await; 39 button.wait_for_rising_edge().await;
31 let mut offset = 0; 40 let mut offset = 0;
32 let mut buf: [u8; 256 * 1024] = [0; 256 * 1024]; 41 let mut buf = AlignedBuffer([0; 4096]);
33 for chunk in APP_B.chunks(256 * 1024) { 42 for chunk in APP_B.chunks(4096) {
34 buf[..chunk.len()].copy_from_slice(chunk); 43 buf.as_mut()[..chunk.len()].copy_from_slice(chunk);
35 updater.write_firmware(offset, &buf, &mut flash, 2048).await.unwrap(); 44 writer.write(offset, buf.as_ref()).unwrap();
36 offset += chunk.len(); 45 offset += chunk.len() as u32;
37 } 46 }
38 updater.update(&mut flash).await.unwrap(); 47 updater.mark_updated(magic.as_mut()).unwrap();
39 led.set_low(); 48 led.set_low();
40 cortex_m::peripheral::SCB::sys_reset(); 49 cortex_m::peripheral::SCB::sys_reset();
41} 50}
diff --git a/examples/boot/application/stm32h7/.cargo/config.toml b/examples/boot/application/stm32h7/.cargo/config.toml
index fefdd370e..caa0d3a93 100644
--- a/examples/boot/application/stm32h7/.cargo/config.toml
+++ b/examples/boot/application/stm32h7/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32F429ZITx with your chip as listed in `probe-run --list-chips` 2# replace STM32F429ZITx with your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32H743ZITx" 3runner = "probe-rs run --chip STM32H743ZITx"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabihf" 6target = "thumbv7em-none-eabihf"
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index 5669527fe..b2abdc891 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -2,21 +2,23 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32h7-examples" 3name = "embassy-boot-stm32h7-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync" }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19embedded-storage = "0.3.0"
18 20
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
21 23
22[features] 24[features]
@@ -25,3 +27,4 @@ defmt = [
25 "embassy-stm32/defmt", 27 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 28 "embassy-boot-stm32/defmt",
27] 29]
30skip-include = []
diff --git a/examples/boot/application/stm32h7/flash-boot.sh b/examples/boot/application/stm32h7/flash-boot.sh
index debdb17a7..4912a50b7 100755
--- a/examples/boot/application/stm32h7/flash-boot.sh
+++ b/examples/boot/application/stm32h7/flash-boot.sh
@@ -1,8 +1,9 @@
1#!/bin/bash 1#!/bin/bash
2probe-rs erase --chip STM32H743ZITx
2mv ../../bootloader/stm32/memory.x ../../bootloader/stm32/memory-old.x 3mv ../../bootloader/stm32/memory.x ../../bootloader/stm32/memory-old.x
3cp memory-bl.x ../../bootloader/stm32/memory.x 4cp memory-bl.x ../../bootloader/stm32/memory.x
4 5
5cargo flash --manifest-path ../../bootloader/stm32/Cargo.toml --release --features embassy-stm32/stm32f767zi --chip STM32F767ZITx --target thumbv7em-none-eabihf 6cargo flash --manifest-path ../../bootloader/stm32/Cargo.toml --release --features embassy-stm32/stm32h743zi --chip STM32H743ZITx --target thumbv7em-none-eabihf
6 7
7rm ../../bootloader/stm32/memory.x 8rm ../../bootloader/stm32/memory.x
8mv ../../bootloader/stm32/memory-old.x ../../bootloader/stm32/memory.x 9mv ../../bootloader/stm32/memory-old.x ../../bootloader/stm32/memory.x
diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs
index 0ecf60348..719176692 100644
--- a/examples/boot/application/stm32h7/src/bin/a.rs
+++ b/examples/boot/application/stm32h7/src/bin/a.rs
@@ -2,23 +2,29 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use core::cell::RefCell;
6
5#[cfg(feature = "defmt-rtt")] 7#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 8use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 9use embassy_boot_stm32::{AlignedBuffer, BlockingFirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 10use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 11use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 12use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 13use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
14use embassy_sync::blocking_mutex::Mutex;
15use embedded_storage::nor_flash::NorFlash;
13use panic_reset as _; 16use panic_reset as _;
14 17
18#[cfg(feature = "skip-include")]
19static APP_B: &[u8] = &[0, 1, 2, 3];
20#[cfg(not(feature = "skip-include"))]
15static APP_B: &[u8] = include_bytes!("../../b.bin"); 21static APP_B: &[u8] = include_bytes!("../../b.bin");
16 22
17#[embassy_executor::main] 23#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
19 let p = embassy_stm32::init(Default::default()); 25 let p = embassy_stm32::init(Default::default());
20 let flash = Flash::unlock(p.FLASH); 26 let flash = Flash::new_blocking(p.FLASH);
21 let mut flash = BlockingAsync::new(flash); 27 let flash = Mutex::new(RefCell::new(flash));
22 28
23 let button = Input::new(p.PC13, Pull::Down); 29 let button = Input::new(p.PC13, Pull::Down);
24 let mut button = ExtiInput::new(button, p.EXTI13); 30 let mut button = ExtiInput::new(button, p.EXTI13);
@@ -26,16 +32,19 @@ async fn main(_spawner: Spawner) {
26 let mut led = Output::new(p.PB14, Level::Low, Speed::Low); 32 let mut led = Output::new(p.PB14, Level::Low, Speed::Low);
27 led.set_high(); 33 led.set_high();
28 34
29 let mut updater = FirmwareUpdater::default(); 35 let config = FirmwareUpdaterConfig::from_linkerfile_blocking(&flash);
36 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
37 let mut updater = BlockingFirmwareUpdater::new(config);
38 let writer = updater.prepare_update(magic.as_mut()).unwrap();
30 button.wait_for_rising_edge().await; 39 button.wait_for_rising_edge().await;
31 let mut offset = 0; 40 let mut offset = 0;
32 let mut buf: [u8; 128 * 1024] = [0; 128 * 1024]; 41 let mut buf = AlignedBuffer([0; 4096]);
33 for chunk in APP_B.chunks(128 * 1024) { 42 for chunk in APP_B.chunks(4096) {
34 buf[..chunk.len()].copy_from_slice(chunk); 43 buf.as_mut()[..chunk.len()].copy_from_slice(chunk);
35 updater.write_firmware(offset, &buf, &mut flash, 2048).await.unwrap(); 44 writer.write(offset, buf.as_ref()).unwrap();
36 offset += chunk.len(); 45 offset += chunk.len() as u32;
37 } 46 }
38 updater.update(&mut flash).await.unwrap(); 47 updater.mark_updated(magic.as_mut()).unwrap();
39 led.set_low(); 48 led.set_low();
40 cortex_m::peripheral::SCB::sys_reset(); 49 cortex_m::peripheral::SCB::sys_reset();
41} 50}
diff --git a/examples/boot/application/stm32l0/.cargo/config.toml b/examples/boot/application/stm32l0/.cargo/config.toml
index 2627967ab..6099f015c 100644
--- a/examples/boot/application/stm32l0/.cargo/config.toml
+++ b/examples/boot/application/stm32l0/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-run --list-chips` 2# replace your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32L072CZTx" 3runner = "probe-rs run --chip STM32L072CZTx"
4 4
5[build] 5[build]
6target = "thumbv6m-none-eabi" 6target = "thumbv6m-none-eabi"
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index 48624d5ec..0b7e72d5e 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -2,21 +2,22 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32l0-examples" 3name = "embassy-boot-stm32l0-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
18 19
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
21 22
22[features] 23[features]
@@ -25,3 +26,4 @@ defmt = [
25 "embassy-stm32/defmt", 26 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 27 "embassy-boot-stm32/defmt",
27] 28]
29skip-include = []
diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs
index f4f1d7119..ce80056e6 100644
--- a/examples/boot/application/stm32l0/src/bin/a.rs
+++ b/examples/boot/application/stm32l0/src/bin/a.rs
@@ -4,22 +4,26 @@
4 4
5#[cfg(feature = "defmt-rtt")] 5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 6use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 7use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync; 8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex;
13use embassy_time::{Duration, Timer}; 14use embassy_time::{Duration, Timer};
14use panic_reset as _; 15use panic_reset as _;
15 16
17#[cfg(feature = "skip-include")]
18static APP_B: &[u8] = &[0, 1, 2, 3];
19#[cfg(not(feature = "skip-include"))]
16static APP_B: &[u8] = include_bytes!("../../b.bin"); 20static APP_B: &[u8] = include_bytes!("../../b.bin");
17 21
18#[embassy_executor::main] 22#[embassy_executor::main]
19async fn main(_spawner: Spawner) { 23async fn main(_spawner: Spawner) {
20 let p = embassy_stm32::init(Default::default()); 24 let p = embassy_stm32::init(Default::default());
21 let flash = Flash::unlock(p.FLASH); 25 let flash = Flash::new_blocking(p.FLASH);
22 let mut flash = BlockingAsync::new(flash); 26 let flash = Mutex::new(BlockingAsync::new(flash));
23 27
24 let button = Input::new(p.PB2, Pull::Up); 28 let button = Input::new(p.PB2, Pull::Up);
25 let mut button = ExtiInput::new(button, p.EXTI2); 29 let mut button = ExtiInput::new(button, p.EXTI2);
@@ -28,17 +32,19 @@ async fn main(_spawner: Spawner) {
28 32
29 led.set_high(); 33 led.set_high();
30 34
31 let mut updater = FirmwareUpdater::default(); 35 let config = FirmwareUpdaterConfig::from_linkerfile(&flash);
36 let mut updater = FirmwareUpdater::new(config);
32 button.wait_for_falling_edge().await; 37 button.wait_for_falling_edge().await;
33 let mut offset = 0; 38 let mut offset = 0;
39 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
34 for chunk in APP_B.chunks(128) { 40 for chunk in APP_B.chunks(128) {
35 let mut buf: [u8; 128] = [0; 128]; 41 let mut buf: [u8; 128] = [0; 128];
36 buf[..chunk.len()].copy_from_slice(chunk); 42 buf[..chunk.len()].copy_from_slice(chunk);
37 updater.write_firmware(offset, &buf, &mut flash, 128).await.unwrap(); 43 updater.write_firmware(magic.as_mut(), offset, &buf).await.unwrap();
38 offset += chunk.len(); 44 offset += chunk.len();
39 } 45 }
40 46
41 updater.update(&mut flash).await.unwrap(); 47 updater.mark_updated(magic.as_mut()).await.unwrap();
42 led.set_low(); 48 led.set_low();
43 Timer::after(Duration::from_secs(1)).await; 49 Timer::after(Duration::from_secs(1)).await;
44 cortex_m::peripheral::SCB::sys_reset(); 50 cortex_m::peripheral::SCB::sys_reset();
diff --git a/examples/boot/application/stm32l1/.cargo/config.toml b/examples/boot/application/stm32l1/.cargo/config.toml
index 404b6b55c..9cabd14ba 100644
--- a/examples/boot/application/stm32l1/.cargo/config.toml
+++ b/examples/boot/application/stm32l1/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-run --list-chips` 2# replace your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32L151CBxxA" 3runner = "probe-rs run --chip STM32L151CBxxA"
4 4
5[build] 5[build]
6target = "thumbv7m-none-eabi" 6target = "thumbv7m-none-eabi"
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index 00b638ca5..5f3f365c1 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -2,21 +2,22 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32l1-examples" 3name = "embassy-boot-stm32l1-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
18 19
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
21 22
22[features] 23[features]
@@ -25,3 +26,4 @@ defmt = [
25 "embassy-stm32/defmt", 26 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 27 "embassy-boot-stm32/defmt",
27] 28]
29skip-include = []
diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs
index f4f1d7119..1e9bf3cb9 100644
--- a/examples/boot/application/stm32l1/src/bin/a.rs
+++ b/examples/boot/application/stm32l1/src/bin/a.rs
@@ -4,22 +4,26 @@
4 4
5#[cfg(feature = "defmt-rtt")] 5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 6use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 7use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync; 8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex;
13use embassy_time::{Duration, Timer}; 14use embassy_time::{Duration, Timer};
14use panic_reset as _; 15use panic_reset as _;
15 16
17#[cfg(feature = "skip-include")]
18static APP_B: &[u8] = &[0, 1, 2, 3];
19#[cfg(not(feature = "skip-include"))]
16static APP_B: &[u8] = include_bytes!("../../b.bin"); 20static APP_B: &[u8] = include_bytes!("../../b.bin");
17 21
18#[embassy_executor::main] 22#[embassy_executor::main]
19async fn main(_spawner: Spawner) { 23async fn main(_spawner: Spawner) {
20 let p = embassy_stm32::init(Default::default()); 24 let p = embassy_stm32::init(Default::default());
21 let flash = Flash::unlock(p.FLASH); 25 let flash = Flash::new_blocking(p.FLASH);
22 let mut flash = BlockingAsync::new(flash); 26 let flash = Mutex::new(BlockingAsync::new(flash));
23 27
24 let button = Input::new(p.PB2, Pull::Up); 28 let button = Input::new(p.PB2, Pull::Up);
25 let mut button = ExtiInput::new(button, p.EXTI2); 29 let mut button = ExtiInput::new(button, p.EXTI2);
@@ -28,17 +32,19 @@ async fn main(_spawner: Spawner) {
28 32
29 led.set_high(); 33 led.set_high();
30 34
31 let mut updater = FirmwareUpdater::default(); 35 let config = FirmwareUpdaterConfig::from_linkerfile(&flash);
36 let mut updater = FirmwareUpdater::new(config);
32 button.wait_for_falling_edge().await; 37 button.wait_for_falling_edge().await;
38 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
33 let mut offset = 0; 39 let mut offset = 0;
34 for chunk in APP_B.chunks(128) { 40 for chunk in APP_B.chunks(128) {
35 let mut buf: [u8; 128] = [0; 128]; 41 let mut buf: [u8; 128] = [0; 128];
36 buf[..chunk.len()].copy_from_slice(chunk); 42 buf[..chunk.len()].copy_from_slice(chunk);
37 updater.write_firmware(offset, &buf, &mut flash, 128).await.unwrap(); 43 updater.write_firmware(magic.as_mut(), offset, &buf).await.unwrap();
38 offset += chunk.len(); 44 offset += chunk.len();
39 } 45 }
40 46
41 updater.update(&mut flash).await.unwrap(); 47 updater.mark_updated(magic.as_mut()).await.unwrap();
42 led.set_low(); 48 led.set_low();
43 Timer::after(Duration::from_secs(1)).await; 49 Timer::after(Duration::from_secs(1)).await;
44 cortex_m::peripheral::SCB::sys_reset(); 50 cortex_m::peripheral::SCB::sys_reset();
diff --git a/examples/boot/application/stm32l4/.cargo/config.toml b/examples/boot/application/stm32l4/.cargo/config.toml
index 43520e323..c803215f6 100644
--- a/examples/boot/application/stm32l4/.cargo/config.toml
+++ b/examples/boot/application/stm32l4/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-run --list-chips` 2# replace your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32L475VG" 3runner = "probe-rs run --chip STM32L475VG"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabihf" 6target = "thumbv7em-none-eabihf"
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index 51ba730d5..44eb5aba8 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -2,21 +2,22 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32l4-examples" 3name = "embassy-boot-stm32l4-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
18 19
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
21 22
22[features] 23[features]
@@ -25,3 +26,4 @@ defmt = [
25 "embassy-stm32/defmt", 26 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 27 "embassy-boot-stm32/defmt",
27] 28]
29skip-include = []
diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs
index 178b2e04a..a514ab5be 100644
--- a/examples/boot/application/stm32l4/src/bin/a.rs
+++ b/examples/boot/application/stm32l4/src/bin/a.rs
@@ -4,21 +4,25 @@
4 4
5#[cfg(feature = "defmt-rtt")] 5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 6use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 7use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync; 8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex;
13use panic_reset as _; 14use panic_reset as _;
14 15
16#[cfg(feature = "skip-include")]
17static APP_B: &[u8] = &[0, 1, 2, 3];
18#[cfg(not(feature = "skip-include"))]
15static APP_B: &[u8] = include_bytes!("../../b.bin"); 19static APP_B: &[u8] = include_bytes!("../../b.bin");
16 20
17#[embassy_executor::main] 21#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
19 let p = embassy_stm32::init(Default::default()); 23 let p = embassy_stm32::init(Default::default());
20 let flash = Flash::unlock(p.FLASH); 24 let flash = Flash::new_blocking(p.FLASH);
21 let mut flash = BlockingAsync::new(flash); 25 let flash = Mutex::new(BlockingAsync::new(flash));
22 26
23 let button = Input::new(p.PC13, Pull::Up); 27 let button = Input::new(p.PC13, Pull::Up);
24 let mut button = ExtiInput::new(button, p.EXTI13); 28 let mut button = ExtiInput::new(button, p.EXTI13);
@@ -26,16 +30,18 @@ async fn main(_spawner: Spawner) {
26 let mut led = Output::new(p.PB14, Level::Low, Speed::Low); 30 let mut led = Output::new(p.PB14, Level::Low, Speed::Low);
27 led.set_high(); 31 led.set_high();
28 32
29 let mut updater = FirmwareUpdater::default(); 33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash);
34 let mut updater = FirmwareUpdater::new(config);
30 button.wait_for_falling_edge().await; 35 button.wait_for_falling_edge().await;
36 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
31 let mut offset = 0; 37 let mut offset = 0;
32 for chunk in APP_B.chunks(2048) { 38 for chunk in APP_B.chunks(2048) {
33 let mut buf: [u8; 2048] = [0; 2048]; 39 let mut buf: [u8; 2048] = [0; 2048];
34 buf[..chunk.len()].copy_from_slice(chunk); 40 buf[..chunk.len()].copy_from_slice(chunk);
35 updater.write_firmware(offset, &buf, &mut flash, 2048).await.unwrap(); 41 updater.write_firmware(magic.as_mut(), offset, &buf).await.unwrap();
36 offset += chunk.len(); 42 offset += chunk.len();
37 } 43 }
38 updater.update(&mut flash).await.unwrap(); 44 updater.mark_updated(magic.as_mut()).await.unwrap();
39 led.set_low(); 45 led.set_low();
40 cortex_m::peripheral::SCB::sys_reset(); 46 cortex_m::peripheral::SCB::sys_reset();
41} 47}
diff --git a/examples/boot/application/stm32wl/.cargo/config.toml b/examples/boot/application/stm32wl/.cargo/config.toml
index e395d75b4..4f8094ff2 100644
--- a/examples/boot/application/stm32wl/.cargo/config.toml
+++ b/examples/boot/application/stm32wl/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace your chip as listed in `probe-run --list-chips` 2# replace your chip as listed in `probe-rs chip list`
3runner = "probe-run --chip STM32WLE5JCIx" 3runner = "probe-rs run --chip STM32WLE5JCIx"
4 4
5[build] 5[build]
6target = "thumbv7em-none-eabihf" 6target = "thumbv7em-none-eabihf"
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 182acf694..fdad55060 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -2,21 +2,22 @@
2edition = "2021" 2edition = "2021"
3name = "embassy-boot-stm32wl-examples" 3name = "embassy-boot-stm32wl-examples"
4version = "0.1.0" 4version = "0.1.0"
5license = "MIT OR Apache-2.0"
5 6
6[dependencies] 7[dependencies]
7embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } 8embassy-sync = { version = "0.2.0", path = "../../../../embassy-sync", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } 9embassy-executor = { version = "0.2.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] }
9embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-32768hz"] } 10embassy-time = { version = "0.1.2", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] }
10embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] }
11embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } 12embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32", features = ["nightly"] }
12embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.1.0", path = "../../../../embassy-embedded-hal" }
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
15defmt-rtt = { version = "0.3", optional = true } 16defmt-rtt = { version = "0.4", optional = true }
16panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
17embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
18 19
19cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
20cortex-m-rt = "0.7.0" 21cortex-m-rt = "0.7.0"
21 22
22[features] 23[features]
@@ -25,3 +26,4 @@ defmt = [
25 "embassy-stm32/defmt", 26 "embassy-stm32/defmt",
26 "embassy-boot-stm32/defmt", 27 "embassy-boot-stm32/defmt",
27] 28]
29skip-include = []
diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs
index c71a42654..52a197a5c 100644
--- a/examples/boot/application/stm32wl/src/bin/a.rs
+++ b/examples/boot/application/stm32wl/src/bin/a.rs
@@ -4,21 +4,25 @@
4 4
5#[cfg(feature = "defmt-rtt")] 5#[cfg(feature = "defmt-rtt")]
6use defmt_rtt::*; 6use defmt_rtt::*;
7use embassy_boot_stm32::FirmwareUpdater; 7use embassy_boot_stm32::{AlignedBuffer, FirmwareUpdater, FirmwareUpdaterConfig};
8use embassy_embedded_hal::adapter::BlockingAsync; 8use embassy_embedded_hal::adapter::BlockingAsync;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::exti::ExtiInput; 10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::flash::Flash; 11use embassy_stm32::flash::{Flash, WRITE_SIZE};
12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed}; 12use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
13use embassy_sync::mutex::Mutex;
13use panic_reset as _; 14use panic_reset as _;
14 15
16#[cfg(feature = "skip-include")]
17static APP_B: &[u8] = &[0, 1, 2, 3];
18#[cfg(not(feature = "skip-include"))]
15static APP_B: &[u8] = include_bytes!("../../b.bin"); 19static APP_B: &[u8] = include_bytes!("../../b.bin");
16 20
17#[embassy_executor::main] 21#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
19 let p = embassy_stm32::init(Default::default()); 23 let p = embassy_stm32::init(Default::default());
20 let flash = Flash::unlock(p.FLASH); 24 let flash = Flash::new_blocking(p.FLASH);
21 let mut flash = BlockingAsync::new(flash); 25 let flash = Mutex::new(BlockingAsync::new(flash));
22 26
23 let button = Input::new(p.PA0, Pull::Up); 27 let button = Input::new(p.PA0, Pull::Up);
24 let mut button = ExtiInput::new(button, p.EXTI0); 28 let mut button = ExtiInput::new(button, p.EXTI0);
@@ -26,18 +30,20 @@ async fn main(_spawner: Spawner) {
26 let mut led = Output::new(p.PB9, Level::Low, Speed::Low); 30 let mut led = Output::new(p.PB9, Level::Low, Speed::Low);
27 led.set_high(); 31 led.set_high();
28 32
29 let mut updater = FirmwareUpdater::default(); 33 let config = FirmwareUpdaterConfig::from_linkerfile(&flash);
34 let mut updater = FirmwareUpdater::new(config);
30 button.wait_for_falling_edge().await; 35 button.wait_for_falling_edge().await;
31 //defmt::info!("Starting update"); 36 //defmt::info!("Starting update");
37 let mut magic = AlignedBuffer([0; WRITE_SIZE]);
32 let mut offset = 0; 38 let mut offset = 0;
33 for chunk in APP_B.chunks(2048) { 39 for chunk in APP_B.chunks(2048) {
34 let mut buf: [u8; 2048] = [0; 2048]; 40 let mut buf: [u8; 2048] = [0; 2048];
35 buf[..chunk.len()].copy_from_slice(chunk); 41 buf[..chunk.len()].copy_from_slice(chunk);
36 // defmt::info!("Writing chunk at 0x{:x}", offset); 42 // defmt::info!("Writing chunk at 0x{:x}", offset);
37 updater.write_firmware(offset, &buf, &mut flash, 2048).await.unwrap(); 43 updater.write_firmware(magic.as_mut(), offset, &buf).await.unwrap();
38 offset += chunk.len(); 44 offset += chunk.len();
39 } 45 }
40 updater.update(&mut flash).await.unwrap(); 46 updater.mark_updated(magic.as_mut()).await.unwrap();
41 //defmt::info!("Marked as updated"); 47 //defmt::info!("Marked as updated");
42 led.set_low(); 48 led.set_low();
43 cortex_m::peripheral::SCB::sys_reset(); 49 cortex_m::peripheral::SCB::sys_reset();