aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-01-04 07:44:23 +0000
committerGitHub <[email protected]>2023-01-04 07:44:23 +0000
commitbf4c0de16a119b9e3a42daf76c4bc60face3c2a1 (patch)
tree1d45b18b0c0b00e783163cf11950ac7bf49efba5
parent35afb60dd490d95a972ad64db8a38652538bceba (diff)
parent8497f98de244f0f8800df78d6e83a2fb886016bf (diff)
Merge #1139
1139: Wdt config changes r=lulf a=huntc Per commits: * By passing WDT config around we can control it more easily and promote sharing it between files. * The memory layout of the s140 crept into a number of memory files, which can cause confusion (well, it did for me!). * Obtaining the current WDT config is useful so that we do not have to duplicate configurations around the place. A constructor method has been introduced that attempts to return the current running WDT config from the WDT peripheral. The bootloader example has also been updated to show how the watchdog can be obtained and used. Co-authored-by: huntc <[email protected]>
-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}