aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-boot/nrf/src/lib.rs6
-rw-r--r--embassy-nrf/src/wdt.rs24
-rw-r--r--examples/boot/application/nrf/README.md4
-rw-r--r--examples/boot/application/nrf/memory-bl.x2
-rw-r--r--examples/boot/application/nrf/memory.x2
-rw-r--r--examples/boot/application/nrf/src/bin/a.rs18
-rw-r--r--examples/boot/bootloader/nrf/memory-bm.x2
-rw-r--r--examples/boot/bootloader/nrf/memory.x2
-rw-r--r--examples/boot/bootloader/nrf/src/main.rs9
9 files changed, 59 insertions, 10 deletions
diff --git a/embassy-boot/nrf/src/lib.rs b/embassy-boot/nrf/src/lib.rs
index 205bbd6df..f40ae62d6 100644
--- a/embassy-boot/nrf/src/lib.rs
+++ b/embassy-boot/nrf/src/lib.rs
@@ -149,11 +149,7 @@ pub struct WatchdogFlash<'d> {
149 149
150impl<'d> WatchdogFlash<'d> { 150impl<'d> WatchdogFlash<'d> {
151 /// Start a new watchdog with a given flash and WDT peripheral and a timeout 151 /// Start a new watchdog with a given flash and WDT peripheral and a timeout
152 pub fn start(flash: Nvmc<'d>, wdt: WDT, timeout: u32) -> Self { 152 pub fn start(flash: Nvmc<'d>, wdt: WDT, config: wdt::Config) -> Self {
153 let mut config = wdt::Config::default();
154 config.timeout_ticks = 32768 * timeout; // timeout seconds
155 config.run_during_sleep = true;
156 config.run_during_debug_halt = false;
157 let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) { 153 let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) {
158 Ok(x) => x, 154 Ok(x) => x,
159 Err(_) => { 155 Err(_) => {
diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs
index 8760aa301..330ca98bf 100644
--- a/embassy-nrf/src/wdt.rs
+++ b/embassy-nrf/src/wdt.rs
@@ -23,6 +23,30 @@ pub struct Config {
23 pub run_during_debug_halt: bool, 23 pub run_during_debug_halt: bool,
24} 24}
25 25
26impl Config {
27 /// Create a config structure from the current configuration of the WDT
28 /// peripheral.
29 pub fn try_new(_wdt: &peripherals::WDT) -> Option<Self> {
30 let r = unsafe { &*WDT::ptr() };
31
32 #[cfg(not(feature = "_nrf9160"))]
33 let runstatus = r.runstatus.read().runstatus().bit();
34 #[cfg(feature = "_nrf9160")]
35 let runstatus = r.runstatus.read().runstatuswdt().bit();
36
37 if runstatus {
38 let config = r.config.read();
39 Some(Self {
40 timeout_ticks: r.crv.read().bits(),
41 run_during_sleep: config.sleep().bit(),
42 run_during_debug_halt: config.halt().bit(),
43 })
44 } else {
45 None
46 }
47 }
48}
49
26impl Default for Config { 50impl Default for Config {
27 fn default() -> Self { 51 fn default() -> Self {
28 Self { 52 Self {
diff --git a/examples/boot/application/nrf/README.md b/examples/boot/application/nrf/README.md
index 703377a20..a6719b505 100644
--- a/examples/boot/application/nrf/README.md
+++ b/examples/boot/application/nrf/README.md
@@ -32,3 +32,7 @@ cargo objcopy --release --bin b -- -O binary b.bin
32``` 32```
33cargo flash --release --bin a --chip nRF52840_xxAA 33cargo flash --release --bin a --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. \ No newline at end of file
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.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 7a404a914..83191f388 100644
--- a/examples/boot/application/nrf/src/bin/a.rs
+++ b/examples/boot/application/nrf/src/bin/a.rs
@@ -8,6 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
10use embassy_nrf::nvmc::Nvmc; 10use embassy_nrf::nvmc::Nvmc;
11use embassy_nrf::wdt::{self, Watchdog};
11use panic_reset as _; 12use panic_reset as _;
12 13
13static APP_B: &[u8] = include_bytes!("../../b.bin"); 14static APP_B: &[u8] = include_bytes!("../../b.bin");
@@ -20,6 +21,23 @@ async fn main(_spawner: Spawner) {
20 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard); 21 //let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard);
21 //let mut button = Input::new(p.P1_02, Pull::Up); 22 //let mut button = Input::new(p.P1_02, Pull::Up);
22 23
24 // The following code block illustrates how to obtain a watchdog that is configured
25 // as per the existing watchdog. Ordinarily, we'd use the handle returned to "pet" the
26 // watchdog periodically. If we don't, and we're not going to for this example, then
27 // the watchdog will cause the device to reset as per its configured timeout in the bootloader.
28 // This helps is avoid a situation where new firmware might be bad and block our executor.
29 // If firmware is bad in this way then the bootloader will revert to any previous version.
30 let wdt_config = wdt::Config::try_new(&p.WDT).unwrap();
31 let (_wdt, [_wdt_handle]) = match Watchdog::try_new(p.WDT, wdt_config) {
32 Ok(x) => x,
33 Err(_) => {
34 // Watchdog already active with the wrong number of handles, waiting for it to timeout...
35 loop {
36 cortex_m::asm::wfe();
37 }
38 }
39 };
40
23 let nvmc = Nvmc::new(p.NVMC); 41 let nvmc = Nvmc::new(p.NVMC);
24 let mut nvmc = BlockingAsync::new(nvmc); 42 let mut nvmc = BlockingAsync::new(nvmc);
25 43
diff --git a/examples/boot/bootloader/nrf/memory-bm.x b/examples/boot/bootloader/nrf/memory-bm.x
index 8a32b905f..257d65644 100644
--- a/examples/boot/bootloader/nrf/memory-bm.x
+++ b/examples/boot/bootloader/nrf/memory-bm.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/bootloader/nrf/memory.x b/examples/boot/bootloader/nrf/memory.x
index 8a32b905f..257d65644 100644
--- a/examples/boot/bootloader/nrf/memory.x
+++ b/examples/boot/bootloader/nrf/memory.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/bootloader/nrf/src/main.rs b/examples/boot/bootloader/nrf/src/main.rs
index 8266206b3..aca3b857a 100644
--- a/examples/boot/bootloader/nrf/src/main.rs
+++ b/examples/boot/bootloader/nrf/src/main.rs
@@ -6,6 +6,7 @@ use cortex_m_rt::{entry, exception};
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_boot_nrf::*; 7use embassy_boot_nrf::*;
8use embassy_nrf::nvmc::Nvmc; 8use embassy_nrf::nvmc::Nvmc;
9use embassy_nrf::wdt;
9 10
10#[entry] 11#[entry]
11fn main() -> ! { 12fn main() -> ! {
@@ -20,8 +21,14 @@ fn main() -> ! {
20 */ 21 */
21 22
22 let mut bl = BootLoader::default(); 23 let mut bl = BootLoader::default();
24
25 let mut wdt_config = wdt::Config::default();
26 wdt_config.timeout_ticks = 32768 * 5; // timeout seconds
27 wdt_config.run_during_sleep = true;
28 wdt_config.run_during_debug_halt = false;
29
23 let start = bl.prepare(&mut SingleFlashConfig::new(&mut BootFlash::<_, 4096>::new( 30 let start = bl.prepare(&mut SingleFlashConfig::new(&mut BootFlash::<_, 4096>::new(
24 WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, 5), 31 WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config),
25 ))); 32 )));
26 unsafe { bl.load(start) } 33 unsafe { bl.load(start) }
27} 34}