aboutsummaryrefslogtreecommitdiff
path: root/examples/boot
diff options
context:
space:
mode:
authorjrmoulton <[email protected]>2025-06-10 15:47:54 -0600
committerjrmoulton <[email protected]>2025-06-10 15:48:36 -0600
commitcfad9798ff99d4de0571a512d156b5fe1ef1d427 (patch)
treefc3bf670f82d139de19466cddad1e909db7f3d2e /examples/boot
parentfc342915e6155dec7bafa3e135da7f37a9a07f5c (diff)
parent6186d111a5c150946ee5b7e9e68d987a38c1a463 (diff)
merge new embassy changes
Diffstat (limited to 'examples/boot')
-rw-r--r--examples/boot/application/nrf/Cargo.toml18
-rw-r--r--examples/boot/application/nrf/build.rs3
-rw-r--r--examples/boot/application/nrf/src/bin/a.rs11
-rw-r--r--examples/boot/application/rp/Cargo.toml18
-rw-r--r--examples/boot/application/stm32f3/Cargo.toml16
-rw-r--r--examples/boot/application/stm32f7/Cargo.toml16
-rw-r--r--examples/boot/application/stm32h7/Cargo.toml16
-rw-r--r--examples/boot/application/stm32l0/Cargo.toml16
-rw-r--r--examples/boot/application/stm32l1/Cargo.toml16
-rw-r--r--examples/boot/application/stm32l4/Cargo.toml16
-rw-r--r--examples/boot/application/stm32wb-dfu/Cargo.toml18
-rw-r--r--examples/boot/application/stm32wb-dfu/memory.x8
-rw-r--r--examples/boot/application/stm32wb-dfu/secrets/key.sec2
-rw-r--r--examples/boot/application/stm32wb-dfu/src/main.rs32
-rw-r--r--examples/boot/application/stm32wl/Cargo.toml16
-rw-r--r--examples/boot/application/stm32wl/memory.x6
-rw-r--r--examples/boot/application/stm32wl/src/bin/a.rs2
-rw-r--r--examples/boot/application/stm32wl/src/bin/b.rs2
-rw-r--r--examples/boot/bootloader/nrf/Cargo.toml6
-rw-r--r--examples/boot/bootloader/nrf/src/main.rs6
-rw-r--r--examples/boot/bootloader/rp/Cargo.toml6
-rw-r--r--examples/boot/bootloader/stm32-dual-bank/Cargo.toml6
-rw-r--r--examples/boot/bootloader/stm32/Cargo.toml6
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/Cargo.toml9
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/README.md58
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/memory.x8
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/secrets/key.pub.short1
-rw-r--r--examples/boot/bootloader/stm32wb-dfu/src/main.rs44
28 files changed, 258 insertions, 124 deletions
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml
index 93e49faef..4d633e8a8 100644
--- a/examples/boot/application/nrf/Cargo.toml
+++ b/examples/boot/application/nrf/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] }
11embassy-nrf = { version = "0.2.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] } 11embassy-nrf = { version = "0.3.1", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", ] }
12embassy-boot = { version = "0.3.0", path = "../../../../embassy-boot", features = [] } 12embassy-boot = { version = "0.4.0", path = "../../../../embassy-boot", features = [] }
13embassy-boot-nrf = { version = "0.3.0", path = "../../../../embassy-boot-nrf", features = [] } 13embassy-boot-nrf = { version = "0.4.0", path = "../../../../embassy-boot-nrf", features = [] }
14embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 14embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
15 15
16defmt = { version = "0.3", optional = true } 16defmt = { version = "1.0.1", optional = true }
17defmt-rtt = { version = "0.4", optional = true } 17defmt-rtt = { version = "1.0.0", optional = true }
18panic-reset = { version = "0.1.1" } 18panic-reset = { version = "0.1.1" }
19embedded-hal = { version = "0.2.6" } 19embedded-hal = { version = "0.2.6" }
20 20
diff --git a/examples/boot/application/nrf/build.rs b/examples/boot/application/nrf/build.rs
index cd1a264c4..e1da69328 100644
--- a/examples/boot/application/nrf/build.rs
+++ b/examples/boot/application/nrf/build.rs
@@ -31,4 +31,7 @@ fn main() {
31 31
32 println!("cargo:rustc-link-arg-bins=--nmagic"); 32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 if env::var("CARGO_FEATURE_DEFMT").is_ok() {
35 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
36 }
34} 37}
diff --git a/examples/boot/application/nrf/src/bin/a.rs b/examples/boot/application/nrf/src/bin/a.rs
index 851a3d721..2c1d1a7bb 100644
--- a/examples/boot/application/nrf/src/bin/a.rs
+++ b/examples/boot/application/nrf/src/bin/a.rs
@@ -2,6 +2,9 @@
2#![no_main] 2#![no_main]
3#![macro_use] 3#![macro_use]
4 4
5#[cfg(feature = "defmt")]
6use defmt_rtt as _;
7use embassy_boot::State;
5use embassy_boot_nrf::{FirmwareUpdater, FirmwareUpdaterConfig}; 8use embassy_boot_nrf::{FirmwareUpdater, FirmwareUpdaterConfig};
6use embassy_embedded_hal::adapter::BlockingAsync; 9use embassy_embedded_hal::adapter::BlockingAsync;
7use embassy_executor::Spawner; 10use embassy_executor::Spawner;
@@ -22,6 +25,7 @@ async fn main(_spawner: Spawner) {
22 25
23 let mut button = Input::new(p.P0_11, Pull::Up); 26 let mut button = Input::new(p.P0_11, Pull::Up);
24 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); 27 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
28 let mut led_reverted = Output::new(p.P0_14, Level::High, OutputDrive::Standard);
25 29
26 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard); 30 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard);
27 //let mut button = Input::new(p.P1_02, Pull::Up); 31 //let mut button = Input::new(p.P1_02, Pull::Up);
@@ -53,6 +57,13 @@ async fn main(_spawner: Spawner) {
53 let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc, &nvmc); 57 let config = FirmwareUpdaterConfig::from_linkerfile(&nvmc, &nvmc);
54 let mut magic = [0; 4]; 58 let mut magic = [0; 4];
55 let mut updater = FirmwareUpdater::new(config, &mut magic); 59 let mut updater = FirmwareUpdater::new(config, &mut magic);
60 let state = updater.get_state().await.unwrap();
61 if state == State::Revert {
62 led_reverted.set_low();
63 } else {
64 led_reverted.set_high();
65 }
66
56 loop { 67 loop {
57 led.set_low(); 68 led.set_low();
58 button.wait_for_any_edge().await; 69 button.wait_for_any_edge().await;
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml
index 8bb8afdfe..be283fb27 100644
--- a/examples/boot/application/rp/Cargo.toml
+++ b/examples/boot/application/rp/Cargo.toml
@@ -5,16 +5,16 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-16384", "arch-cortex-m", "executor-thread", "integrated-timers", "arch-cortex-m", "executor-thread"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [] }
11embassy-rp = { version = "0.2.0", path = "../../../../embassy-rp", features = ["time-driver", "rp2040"] } 11embassy-rp = { version = "0.4.0", path = "../../../../embassy-rp", features = ["time-driver", "rp2040"] }
12embassy-boot-rp = { version = "0.3.0", path = "../../../../embassy-boot-rp", features = [] } 12embassy-boot-rp = { version = "0.5.0", path = "../../../../embassy-boot-rp", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = "0.3" 15defmt = "1.0.1"
16defmt-rtt = "0.4" 16defmt-rtt = "1.0.0"
17panic-probe = { version = "0.3", features = ["print-defmt"], optional = true } 17panic-probe = { version = "1.0.0", features = ["print-defmt"], optional = true }
18panic-reset = { version = "0.1.1", optional = true } 18panic-reset = { version = "0.1.1", optional = true }
19embedded-hal = { version = "0.2.6" } 19embedded-hal = { version = "0.2.6" }
20 20
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml
index 1c2934298..b3466e288 100644
--- a/examples/boot/application/stm32f3/Cargo.toml
+++ b/examples/boot/application/stm32f3/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f303re", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32" } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32" }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml
index 09e34c7df..72dbded5f 100644
--- a/examples/boot/application/stm32f7/Cargo.toml
+++ b/examples/boot/application/stm32f7/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32f767zi", "time-driver-any", "exti", "single-bank"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19embedded-storage = "0.3.1" 19embedded-storage = "0.3.1"
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml
index 5e7f4d5e7..57fb8312c 100644
--- a/examples/boot/application/stm32h7/Cargo.toml
+++ b/examples/boot/application/stm32h7/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32h743zi", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19embedded-storage = "0.3.1" 19embedded-storage = "0.3.1"
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml
index 60fdcfafb..7dbbba138 100644
--- a/examples/boot/application/stm32l0/Cargo.toml
+++ b/examples/boot/application/stm32l0/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l072cz", "time-driver-any", "exti", "memory-x"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml
index fe3ab2c04..9549b2048 100644
--- a/examples/boot/application/stm32l1/Cargo.toml
+++ b/examples/boot/application/stm32l1/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l151cb-a", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml
index 169856358..03daeb0bc 100644
--- a/examples/boot/application/stm32l4/Cargo.toml
+++ b/examples/boot/application/stm32l4/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32l475vg", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32wb-dfu/Cargo.toml b/examples/boot/application/stm32wb-dfu/Cargo.toml
index 7cef8fe0d..e582628aa 100644
--- a/examples/boot/application/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/application/stm32wb-dfu/Cargo.toml
@@ -5,17 +5,17 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wb55rg", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14embassy-usb = { version = "0.3.0", path = "../../../../embassy-usb" } 14embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb" }
15embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] } 15embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["application", "cortex-m"] }
16 16
17defmt = { version = "0.3", optional = true } 17defmt = { version = "1.0.1", optional = true }
18defmt-rtt = { version = "0.4", optional = true } 18defmt-rtt = { version = "1.0.0", optional = true }
19panic-reset = { version = "0.1.1" } 19panic-reset = { version = "0.1.1" }
20embedded-hal = { version = "0.2.6" } 20embedded-hal = { version = "0.2.6" }
21 21
diff --git a/examples/boot/application/stm32wb-dfu/memory.x b/examples/boot/application/stm32wb-dfu/memory.x
index ff1b800d2..f1e6b053c 100644
--- a/examples/boot/application/stm32wb-dfu/memory.x
+++ b/examples/boot/application/stm32wb-dfu/memory.x
@@ -1,10 +1,10 @@
1MEMORY 1MEMORY
2{ 2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 24K 4 BOOTLOADER : ORIGIN = 0x08000000, LENGTH = 48K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x0800C000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 128K 6 FLASH : ORIGIN = 0x0800D000, LENGTH = 120K
7 DFU : ORIGIN = 0x08028000, LENGTH = 132K 7 DFU : ORIGIN = 0x0802B000, LENGTH = 120K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
9} 9}
10 10
diff --git a/examples/boot/application/stm32wb-dfu/secrets/key.sec b/examples/boot/application/stm32wb-dfu/secrets/key.sec
new file mode 100644
index 000000000..52e7f125b
--- /dev/null
+++ b/examples/boot/application/stm32wb-dfu/secrets/key.sec
@@ -0,0 +1,2 @@
1untrusted comment: signify secret key
2RWRCSwAAAAATdHQF3B4jEIoNZrjADRp2LbjJjNdNNzKwTCe4IB6mDNq96pe53nbNxwbdCc/T4hrz7W+Kx1MwrZ0Yz5xebSK5Z0Kh/3Cdf039U5f+eoTDS2fIGbohyUbrtwKzjyE0qXI=
diff --git a/examples/boot/application/stm32wb-dfu/src/main.rs b/examples/boot/application/stm32wb-dfu/src/main.rs
index 0ab99ff90..5e7b71f5a 100644
--- a/examples/boot/application/stm32wb-dfu/src/main.rs
+++ b/examples/boot/application/stm32wb-dfu/src/main.rs
@@ -13,7 +13,7 @@ use embassy_stm32::usb::{self, Driver};
13use embassy_stm32::{bind_interrupts, peripherals}; 13use embassy_stm32::{bind_interrupts, peripherals};
14use embassy_sync::blocking_mutex::Mutex; 14use embassy_sync::blocking_mutex::Mutex;
15use embassy_time::Duration; 15use embassy_time::Duration;
16use embassy_usb::Builder; 16use embassy_usb::{msos, Builder};
17use embassy_usb_dfu::consts::DfuAttributes; 17use embassy_usb_dfu::consts::DfuAttributes;
18use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate}; 18use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate};
19use panic_reset as _; 19use panic_reset as _;
@@ -22,6 +22,11 @@ bind_interrupts!(struct Irqs {
22 USB_LP => usb::InterruptHandler<peripherals::USB>; 22 USB_LP => usb::InterruptHandler<peripherals::USB>;
23}); 23});
24 24
25// This is a randomly generated GUID to allow clients on Windows to find your device.
26//
27// N.B. update to a custom GUID for your own device!
28const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"];
29
25#[embassy_executor::main] 30#[embassy_executor::main]
26async fn main(_spawner: Spawner) { 31async fn main(_spawner: Spawner) {
27 let mut config = embassy_stm32::Config::default(); 32 let mut config = embassy_stm32::Config::default();
@@ -44,7 +49,7 @@ async fn main(_spawner: Spawner) {
44 let mut config_descriptor = [0; 256]; 49 let mut config_descriptor = [0; 256];
45 let mut bos_descriptor = [0; 256]; 50 let mut bos_descriptor = [0; 256];
46 let mut control_buf = [0; 64]; 51 let mut control_buf = [0; 64];
47 let mut state = Control::new(firmware_state, DfuAttributes::CAN_DOWNLOAD); 52 let mut state = Control::new(firmware_state, DfuAttributes::CAN_DOWNLOAD, ResetImmediate);
48 let mut builder = Builder::new( 53 let mut builder = Builder::new(
49 driver, 54 driver,
50 config, 55 config,
@@ -54,7 +59,28 @@ async fn main(_spawner: Spawner) {
54 &mut control_buf, 59 &mut control_buf,
55 ); 60 );
56 61
57 usb_dfu::<_, _, ResetImmediate>(&mut builder, &mut state, Duration::from_millis(2500)); 62 // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows.
63 // Otherwise users need to do this manually using a tool like Zadig.
64 //
65 // It seems these always need to be at added at the device level for this to work and for
66 // composite devices they also need to be added on the function level (as shown later).
67 //
68 builder.msos_descriptor(msos::windows_version::WIN8_1, 2);
69 builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
70 builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
71 "DeviceInterfaceGUIDs",
72 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
73 ));
74
75 usb_dfu(&mut builder, &mut state, Duration::from_millis(2500), |func| {
76 // You likely don't have to add these function level headers if your USB device is not composite
77 // (i.e. if your device does not expose another interface in addition to DFU)
78 func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
79 func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
80 "DeviceInterfaceGUIDs",
81 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
82 ));
83 });
58 84
59 let mut dev = builder.build(); 85 let mut dev = builder.build();
60 dev.run().await 86 dev.run().await
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml
index 860a835a9..3ed04b472 100644
--- a/examples/boot/application/stm32wl/Cargo.toml
+++ b/examples/boot/application/stm32wl/Cargo.toml
@@ -5,15 +5,15 @@ version = "0.1.0"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 8embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
9embassy-executor = { version = "0.6.0", path = "../../../../embassy-executor", features = ["task-arena-size-8192", "arch-cortex-m", "executor-thread", "integrated-timers"] } 9embassy-executor = { version = "0.7.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread"] }
10embassy-time = { version = "0.3.2", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] } 10embassy-time = { version = "0.4.0", path = "../../../../embassy-time", features = [ "tick-hz-32_768"] }
11embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] } 11embassy-stm32 = { version = "0.2.0", path = "../../../../embassy-stm32", features = ["stm32wl55jc-cm4", "time-driver-any", "exti"] }
12embassy-boot-stm32 = { version = "0.2.0", path = "../../../../embassy-boot-stm32", features = [] } 12embassy-boot-stm32 = { version = "0.3.0", path = "../../../../embassy-boot-stm32", features = [] }
13embassy-embedded-hal = { version = "0.2.0", path = "../../../../embassy-embedded-hal" } 13embassy-embedded-hal = { version = "0.3.0", path = "../../../../embassy-embedded-hal" }
14 14
15defmt = { version = "0.3", optional = true } 15defmt = { version = "1.0.1", optional = true }
16defmt-rtt = { version = "0.4", optional = true } 16defmt-rtt = { version = "1.0.0", optional = true }
17panic-reset = { version = "0.1.1" } 17panic-reset = { version = "0.1.1" }
18embedded-hal = { version = "0.2.6" } 18embedded-hal = { version = "0.2.6" }
19 19
diff --git a/examples/boot/application/stm32wl/memory.x b/examples/boot/application/stm32wl/memory.x
index 5af1723f5..20109e37e 100644
--- a/examples/boot/application/stm32wl/memory.x
+++ b/examples/boot/application/stm32wl/memory.x
@@ -5,8 +5,8 @@ MEMORY
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K
6 FLASH : ORIGIN = 0x08008000, LENGTH = 64K 6 FLASH : ORIGIN = 0x08008000, LENGTH = 64K
7 DFU : ORIGIN = 0x08018000, LENGTH = 68K 7 DFU : ORIGIN = 0x08018000, LENGTH = 68K
8 SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64 8 SHARED_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128
9 RAM (rwx) : ORIGIN = 0x20000040, LENGTH = 32K - 64 9 RAM (rwx) : ORIGIN = 0x20000080, LENGTH = 32K - 128
10} 10}
11 11
12__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER); 12__bootloader_state_start = ORIGIN(BOOTLOADER_STATE) - ORIGIN(BOOTLOADER);
@@ -21,4 +21,4 @@ SECTIONS
21 { 21 {
22 *(.shared_data) 22 *(.shared_data)
23 } > SHARED_RAM 23 } > SHARED_RAM
24} \ No newline at end of file 24}
diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs
index 127de0237..e4526927f 100644
--- a/examples/boot/application/stm32wl/src/bin/a.rs
+++ b/examples/boot/application/stm32wl/src/bin/a.rs
@@ -20,7 +20,7 @@ static APP_B: &[u8] = &[0, 1, 2, 3];
20#[cfg(not(feature = "skip-include"))] 20#[cfg(not(feature = "skip-include"))]
21static APP_B: &[u8] = include_bytes!("../../b.bin"); 21static APP_B: &[u8] = include_bytes!("../../b.bin");
22 22
23#[link_section = ".shared_data"] 23#[unsafe(link_section = ".shared_data")]
24static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit(); 24static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
25 25
26#[embassy_executor::main] 26#[embassy_executor::main]
diff --git a/examples/boot/application/stm32wl/src/bin/b.rs b/examples/boot/application/stm32wl/src/bin/b.rs
index 768dadf8b..6016a9555 100644
--- a/examples/boot/application/stm32wl/src/bin/b.rs
+++ b/examples/boot/application/stm32wl/src/bin/b.rs
@@ -11,7 +11,7 @@ use embassy_stm32::SharedData;
11use embassy_time::Timer; 11use embassy_time::Timer;
12use panic_reset as _; 12use panic_reset as _;
13 13
14#[link_section = ".shared_data"] 14#[unsafe(link_section = ".shared_data")]
15static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit(); 15static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
16 16
17#[embassy_executor::main] 17#[embassy_executor::main]
diff --git a/examples/boot/bootloader/nrf/Cargo.toml b/examples/boot/bootloader/nrf/Cargo.toml
index 9d5d51a13..897890ca4 100644
--- a/examples/boot/bootloader/nrf/Cargo.toml
+++ b/examples/boot/bootloader/nrf/Cargo.toml
@@ -6,13 +6,13 @@ description = "Bootloader for nRF chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-nrf = { path = "../../../../embassy-nrf", features = [] } 12embassy-nrf = { path = "../../../../embassy-nrf", features = [] }
13embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" } 13embassy-boot-nrf = { path = "../../../../embassy-boot-nrf" }
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 15embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
16cortex-m-rt = { version = "0.7" } 16cortex-m-rt = { version = "0.7" }
17cfg-if = "1.0.0" 17cfg-if = "1.0.0"
18 18
diff --git a/examples/boot/bootloader/nrf/src/main.rs b/examples/boot/bootloader/nrf/src/main.rs
index 67c700437..b849a0df3 100644
--- a/examples/boot/bootloader/nrf/src/main.rs
+++ b/examples/boot/bootloader/nrf/src/main.rs
@@ -8,7 +8,7 @@ use cortex_m_rt::{entry, exception};
8use defmt_rtt as _; 8use defmt_rtt as _;
9use embassy_boot_nrf::*; 9use embassy_boot_nrf::*;
10use embassy_nrf::nvmc::Nvmc; 10use embassy_nrf::nvmc::Nvmc;
11use embassy_nrf::wdt; 11use embassy_nrf::wdt::{self, HaltConfig, SleepConfig};
12use embassy_sync::blocking_mutex::Mutex; 12use embassy_sync::blocking_mutex::Mutex;
13 13
14#[entry] 14#[entry]
@@ -25,8 +25,8 @@ fn main() -> ! {
25 25
26 let mut wdt_config = wdt::Config::default(); 26 let mut wdt_config = wdt::Config::default();
27 wdt_config.timeout_ticks = 32768 * 5; // timeout seconds 27 wdt_config.timeout_ticks = 32768 * 5; // timeout seconds
28 wdt_config.run_during_sleep = true; 28 wdt_config.action_during_sleep = SleepConfig::RUN;
29 wdt_config.run_during_debug_halt = false; 29 wdt_config.action_during_debug_halt = HaltConfig::PAUSE;
30 30
31 let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config); 31 let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config);
32 let flash = Mutex::new(RefCell::new(flash)); 32 let flash = Mutex::new(RefCell::new(flash));
diff --git a/examples/boot/bootloader/rp/Cargo.toml b/examples/boot/bootloader/rp/Cargo.toml
index 9df396e5e..090a581d4 100644
--- a/examples/boot/bootloader/rp/Cargo.toml
+++ b/examples/boot/bootloader/rp/Cargo.toml
@@ -6,12 +6,12 @@ description = "Example bootloader for RP2040 chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-rp = { path = "../../../../embassy-rp", features = ["rp2040"] } 12embassy-rp = { path = "../../../../embassy-rp", features = ["rp2040"] }
13embassy-boot-rp = { path = "../../../../embassy-boot-rp" } 13embassy-boot-rp = { path = "../../../../embassy-boot-rp" }
14embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 14embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
15embassy-time = { path = "../../../../embassy-time", features = [] } 15embassy-time = { path = "../../../../embassy-time", features = [] }
16 16
17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 17cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
diff --git a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
index b91b05412..67edc6a6c 100644
--- a/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
+++ b/examples/boot/bootloader/stm32-dual-bank/Cargo.toml
@@ -6,8 +6,8 @@ description = "Example bootloader for dual-bank flash STM32 chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
@@ -15,7 +15,7 @@ cortex-m = { version = "0.7.6", features = [
15 "inline-asm", 15 "inline-asm",
16 "critical-section-single-core", 16 "critical-section-single-core",
17] } 17] }
18embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 18embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
19cortex-m-rt = { version = "0.7" } 19cortex-m-rt = { version = "0.7" }
20embedded-storage = "0.3.1" 20embedded-storage = "0.3.1"
21embedded-storage-async = "0.4.0" 21embedded-storage-async = "0.4.0"
diff --git a/examples/boot/bootloader/stm32/Cargo.toml b/examples/boot/bootloader/stm32/Cargo.toml
index 541186949..fe81b5151 100644
--- a/examples/boot/bootloader/stm32/Cargo.toml
+++ b/examples/boot/bootloader/stm32/Cargo.toml
@@ -6,13 +6,13 @@ description = "Example bootloader for STM32 chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 15embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
16cortex-m-rt = { version = "0.7" } 16cortex-m-rt = { version = "0.7" }
17embedded-storage = "0.3.1" 17embedded-storage = "0.3.1"
18embedded-storage-async = "0.4.0" 18embedded-storage-async = "0.4.0"
diff --git a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
index 050b672ce..0bb93b12e 100644
--- a/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
+++ b/examples/boot/bootloader/stm32wb-dfu/Cargo.toml
@@ -6,19 +6,19 @@ description = "Example USB DFUbootloader for the STM32WB series of chips"
6license = "MIT OR Apache-2.0" 6license = "MIT OR Apache-2.0"
7 7
8[dependencies] 8[dependencies]
9defmt = { version = "0.3", optional = true } 9defmt = { version = "1.0.1", optional = true }
10defmt-rtt = { version = "0.4", optional = true } 10defmt-rtt = { version = "1.0.0", optional = true }
11 11
12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] } 12embassy-stm32 = { path = "../../../../embassy-stm32", features = [] }
13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" } 13embassy-boot-stm32 = { path = "../../../../embassy-boot-stm32" }
14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 14cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
15embassy-sync = { version = "0.6.0", path = "../../../../embassy-sync" } 15embassy-sync = { version = "0.7.0", path = "../../../../embassy-sync" }
16cortex-m-rt = { version = "0.7" } 16cortex-m-rt = { version = "0.7" }
17embedded-storage = "0.3.1" 17embedded-storage = "0.3.1"
18embedded-storage-async = "0.4.0" 18embedded-storage-async = "0.4.0"
19cfg-if = "1.0.0" 19cfg-if = "1.0.0"
20embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] } 20embassy-usb-dfu = { version = "0.1.0", path = "../../../../embassy-usb-dfu", features = ["dfu", "cortex-m"] }
21embassy-usb = { version = "0.3.0", path = "../../../../embassy-usb", default-features = false } 21embassy-usb = { version = "0.4.0", path = "../../../../embassy-usb", default-features = false }
22embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" } 22embassy-futures = { version = "0.1.1", path = "../../../../embassy-futures" }
23 23
24[features] 24[features]
@@ -30,6 +30,7 @@ defmt = [
30 "embassy-usb/defmt", 30 "embassy-usb/defmt",
31 "embassy-usb-dfu/defmt" 31 "embassy-usb-dfu/defmt"
32] 32]
33verify = ["embassy-usb-dfu/ed25519-salty"]
33 34
34[profile.dev] 35[profile.dev]
35debug = 2 36debug = 2
diff --git a/examples/boot/bootloader/stm32wb-dfu/README.md b/examples/boot/bootloader/stm32wb-dfu/README.md
index d5c6ea57c..99a7002c4 100644
--- a/examples/boot/bootloader/stm32wb-dfu/README.md
+++ b/examples/boot/bootloader/stm32wb-dfu/README.md
@@ -1,11 +1,63 @@
1# Bootloader for STM32 1# Bootloader for STM32
2 2
3The bootloader uses `embassy-boot` to interact with the flash. 3This bootloader implementation uses `embassy-boot` and `embassy-usb-dfu` to manage firmware updates and interact with the flash memory on STM32WB55 devices.
4 4
5# Usage 5## Prerequisites
6 6
7Flash the bootloader 7- Rust toolchain with `cargo` installed
8- `cargo-flash` for flashing the bootloader
9- `dfu-util` for firmware updates
10- `cargo-binutils` for binary generation
11
12## Usage
13
14### 1. Flash the Bootloader
15
16First, flash the bootloader to your device:
8 17
9``` 18```
10cargo flash --features embassy-stm32/stm32wb55rg --release --chip STM32WB55RGVx 19cargo flash --features embassy-stm32/stm32wb55rg --release --chip STM32WB55RGVx
11``` 20```
21
22### 2. Build and Flash Application
23
24Generate your application binary and flash it using DFU:
25
26```
27cargo objcopy --release -- -O binary fw.bin
28dfu-util -d c0de:cafe -w -D fw.bin
29```
30
31### 3. Sign Updates Before Flashing (Optional)
32
33Currently, embassy-usb-dfu only supports a limited implementation of the generic support for ed25519-based update verfication in embassy-boot. This implementation assumes that a signature is simply concatenated to the end of an update binary. For more details, please see https://embassy.dev/book/#_verification and/or refer to the documentation for embassy-boot-dfu.
34
35To sign (and then verify) application updates, you will first need to generate a key pair:
36
37```
38signify-openbsd -G -n -p secrets/key.pub -s secrets/key.sec
39tail -n1 secrets/key.pub | base64 -d -i - | dd ibs=10 skip=1 > secrets/key.pub.short
40```
41
42Then you will need to sign all you binaries with the private key:
43
44```
45cargo objcopy --release -- -O binary fw.bin
46shasum -a 512 -b fw.bin | head -c128 | xxd -p -r > target/fw-hash.txt
47signify-openbsd -S -s secrets/key.sec -m target/fw-hash.txt -x target/fw-hash.sig
48cp fw.bin fw-signed.bin
49tail -n1 target/fw-hash.sig | base64 -d -i - | dd ibs=10 skip=1 >> fw-signed.bin
50dfu-util -d c0de:cafe -w -D fw-signed.bin
51```
52
53Finally, as shown in this example with the `verify` feature flag enabled, you then need to embed the public key into your bootloader so that it can verify update signatures.
54
55N.B. Please note that the exact steps above are NOT a good example of how to manage your keys securely. In a production environment, you should take great care to ensure that (at least the private key) is protected and not leaked into your version control system.
56
57## Troubleshooting
58
59- Make sure your device is in DFU mode before flashing
60- Verify the USB VID:PID matches your device (c0de:cafe)
61- Check USB connections if the device is not detected
62- Make sure the transfer size option of `dfu-util` matches the bootloader configuration. By default, `dfu-util` will use the transfer size reported by the device, but you can override it with the `-t` option if needed.
63- Make sure `control_buf` size is larger than or equal to the `usb_dfu` `BLOCK_SIZE` parameter (in this example, both are set to 4096 bytes).
diff --git a/examples/boot/bootloader/stm32wb-dfu/memory.x b/examples/boot/bootloader/stm32wb-dfu/memory.x
index 858062631..77c4d2ee2 100644
--- a/examples/boot/bootloader/stm32wb-dfu/memory.x
+++ b/examples/boot/bootloader/stm32wb-dfu/memory.x
@@ -1,10 +1,10 @@
1MEMORY 1MEMORY
2{ 2{
3 /* NOTE 1 K = 1 KiBi = 1024 bytes */ 3 /* NOTE 1 K = 1 KiBi = 1024 bytes */
4 FLASH : ORIGIN = 0x08000000, LENGTH = 24K 4 FLASH : ORIGIN = 0x08000000, LENGTH = 48K
5 BOOTLOADER_STATE : ORIGIN = 0x08006000, LENGTH = 4K 5 BOOTLOADER_STATE : ORIGIN = 0x0800C000, LENGTH = 4K
6 ACTIVE : ORIGIN = 0x08008000, LENGTH = 128K 6 ACTIVE : ORIGIN = 0x0800D000, LENGTH = 120K
7 DFU : ORIGIN = 0x08028000, LENGTH = 132K 7 DFU : ORIGIN = 0x0802B000, LENGTH = 120K
8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K 8 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
9} 9}
10 10
diff --git a/examples/boot/bootloader/stm32wb-dfu/secrets/key.pub.short b/examples/boot/bootloader/stm32wb-dfu/secrets/key.pub.short
new file mode 100644
index 000000000..7a4de8585
--- /dev/null
+++ b/examples/boot/bootloader/stm32wb-dfu/secrets/key.pub.short
@@ -0,0 +1 @@
gB��p�M�S��z��Kg��!�F���!4�r \ No newline at end of file
diff --git a/examples/boot/bootloader/stm32wb-dfu/src/main.rs b/examples/boot/bootloader/stm32wb-dfu/src/main.rs
index 093b39f9d..107f243fd 100644
--- a/examples/boot/bootloader/stm32wb-dfu/src/main.rs
+++ b/examples/boot/bootloader/stm32wb-dfu/src/main.rs
@@ -12,7 +12,7 @@ use embassy_stm32::rcc::WPAN_DEFAULT;
12use embassy_stm32::usb::Driver; 12use embassy_stm32::usb::Driver;
13use embassy_stm32::{bind_interrupts, peripherals, usb}; 13use embassy_stm32::{bind_interrupts, peripherals, usb};
14use embassy_sync::blocking_mutex::Mutex; 14use embassy_sync::blocking_mutex::Mutex;
15use embassy_usb::Builder; 15use embassy_usb::{msos, Builder};
16use embassy_usb_dfu::consts::DfuAttributes; 16use embassy_usb_dfu::consts::DfuAttributes;
17use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate}; 17use embassy_usb_dfu::{usb_dfu, Control, ResetImmediate};
18 18
@@ -20,6 +20,17 @@ bind_interrupts!(struct Irqs {
20 USB_LP => usb::InterruptHandler<peripherals::USB>; 20 USB_LP => usb::InterruptHandler<peripherals::USB>;
21}); 21});
22 22
23// This is a randomly generated GUID to allow clients on Windows to find your device.
24//
25// N.B. update to a custom GUID for your own device!
26const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321}"];
27
28// This is a randomly generated example key.
29//
30// N.B. Please replace with your own!
31#[cfg(feature = "verify")]
32static PUBLIC_SIGNING_KEY: &[u8; 32] = include_bytes!("../secrets/key.pub.short");
33
23#[entry] 34#[entry]
24fn main() -> ! { 35fn main() -> ! {
25 let mut config = embassy_stm32::Config::default(); 36 let mut config = embassy_stm32::Config::default();
@@ -52,7 +63,13 @@ fn main() -> ! {
52 let mut config_descriptor = [0; 256]; 63 let mut config_descriptor = [0; 256];
53 let mut bos_descriptor = [0; 256]; 64 let mut bos_descriptor = [0; 256];
54 let mut control_buf = [0; 4096]; 65 let mut control_buf = [0; 4096];
55 let mut state = Control::new(updater, DfuAttributes::CAN_DOWNLOAD); 66
67 #[cfg(not(feature = "verify"))]
68 let mut state = Control::new(updater, DfuAttributes::CAN_DOWNLOAD, ResetImmediate);
69
70 #[cfg(feature = "verify")]
71 let mut state = Control::new(updater, DfuAttributes::CAN_DOWNLOAD, ResetImmediate, PUBLIC_SIGNING_KEY);
72
56 let mut builder = Builder::new( 73 let mut builder = Builder::new(
57 driver, 74 driver,
58 config, 75 config,
@@ -62,7 +79,28 @@ fn main() -> ! {
62 &mut control_buf, 79 &mut control_buf,
63 ); 80 );
64 81
65 usb_dfu::<_, _, _, ResetImmediate, 4096>(&mut builder, &mut state); 82 // We add MSOS headers so that the device automatically gets assigned the WinUSB driver on Windows.
83 // Otherwise users need to do this manually using a tool like Zadig.
84 //
85 // It seems these always need to be at added at the device level for this to work and for
86 // composite devices they also need to be added on the function level (as shown later).
87 //
88 builder.msos_descriptor(msos::windows_version::WIN8_1, 2);
89 builder.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
90 builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
91 "DeviceInterfaceGUIDs",
92 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
93 ));
94
95 usb_dfu::<_, _, _, _, 4096>(&mut builder, &mut state, |func| {
96 // You likely don't have to add these function level headers if your USB device is not composite
97 // (i.e. if your device does not expose another interface in addition to DFU)
98 func.msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", ""));
99 func.msos_feature(msos::RegistryPropertyFeatureDescriptor::new(
100 "DeviceInterfaceGUIDs",
101 msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS),
102 ));
103 });
66 104
67 let mut dev = builder.build(); 105 let mut dev = builder.build();
68 embassy_futures::block_on(dev.run()); 106 embassy_futures::block_on(dev.run());