Skip to content

Commit a008306

Browse files
committed
implement sleep using WFE
closes #1
1 parent ed1c4fe commit a008306

File tree

6 files changed

+17
-9
lines changed

6 files changed

+17
-9
lines changed

async-cortex-m/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ publish = false
77
version = "0.0.0-alpha.0"
88

99
[dependencies]
10+
cortex-m = "0.6.2"
1011
cortex-m-udf = { path = "../cortex-m-udf" }
1112
generic-array = "0.13.2"
1213
heapless = { git = "https://github.com/japaric/heapless", branch = "slab" }
1314
pin-utils = "0.1.0-alpha.4"
14-
typenum = "1.11.2"
15+
typenum = "1.11.2"

async-cortex-m/src/executor.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::{
77
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
88
};
99

10+
use cortex_m::asm;
1011
use heapless::Vec;
1112
use pin_utils::pin_mut;
1213

@@ -107,13 +108,9 @@ impl Executor {
107108
}
108109
}
109110

110-
// TODO try to sleep (WFI) here
111-
// just calling WFI here will result in missed notifications because
112-
// a `Waker` (called from an interrupt handler) may run just after
113-
// we exit the `for` loop but before WFI is called. Then the system
114-
// won't wake up until the *next* interrupt handler is triggered
115-
// (which could end up never running if the applications used only a
116-
// single interrupt)
111+
// try to sleep; this will be a no-op if any of the previous tasks generated a SEV or an
112+
// interrupt ran (regardless of whether it generated a wake-up or not)
113+
asm::wfe();
117114
};
118115
self.in_block_on.set(false);
119116
val

async-cortex-m/src/task.rs

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use core::{
66
task::{Context, Poll},
77
};
88

9+
use cortex_m::asm;
10+
911
use crate::executor;
1012

1113
/// Drives the future `f` to completion
@@ -39,7 +41,9 @@ pub async fn r#yield() {
3941
Poll::Ready(())
4042
} else {
4143
self.yielded = true;
44+
// wake ourselves
4245
cx.waker().wake_by_ref();
46+
asm::sev();
4347
Poll::Pending
4448
}
4549
}

async-cortex-m/src/unsync/channel.rs

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use core::{
1212
task::{Context, Poll},
1313
};
1414

15+
use cortex_m::asm;
1516
use generic_array::{typenum::Unsigned, GenericArray};
1617

1718
use super::waker_set::WakerSet;
@@ -136,6 +137,7 @@ impl<T> Channel<T> {
136137
self.read.set(read.wrapping_add(1));
137138
// notify a sender
138139
self.send_wakers.notify_one();
140+
asm::sev();
139141
Some(val)
140142
} else {
141143
// empty
@@ -160,6 +162,7 @@ impl<T> Channel<T> {
160162
self.write.set(write.wrapping_add(1));
161163
// notify a receiver
162164
self.recv_wakers.notify_one();
165+
asm::sev();
163166
Ok(())
164167
} else {
165168
// full

async-cortex-m/src/unsync/mutex.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use core::{
88
task::{Context, Poll},
99
};
1010

11+
use cortex_m::asm;
12+
1113
use super::waker_set::WakerSet;
1214

1315
/// A mutual exclusion primitive for protecting shared data
@@ -92,6 +94,7 @@ impl<T> Drop for MutexGuard<'_, T> {
9294
fn drop(&mut self) {
9395
self.0.locked.set(false);
9496
self.0.wakers.notify_any();
97+
asm::wfe();
9598
}
9699
}
97100

nrf52/examples/7-echo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn main() -> ! {
3535

3636
let (mut tx, mut rx) = serial::take();
3737
task::block_on(async {
38-
let mut buf = [0; 16];
38+
let mut buf = [0; 1];
3939
loop {
4040
rx.read(&mut buf).await;
4141
tx.write(&buf).await;

0 commit comments

Comments
 (0)