aboutsummaryrefslogtreecommitdiff
path: root/examples/boot/application/nrf
diff options
context:
space:
mode:
Diffstat (limited to 'examples/boot/application/nrf')
-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
9 files changed, 101 insertions, 24 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();