Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

Commit

Permalink
implement sleep using WFE
Browse files Browse the repository at this point in the history
closes #1
  • Loading branch information
japaric committed Mar 9, 2020
1 parent ed1c4fe commit a008306
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 9 deletions.
3 changes: 2 additions & 1 deletion async-cortex-m/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ publish = false
version = "0.0.0-alpha.0"

[dependencies]
cortex-m = "0.6.2"
cortex-m-udf = { path = "../cortex-m-udf" }
generic-array = "0.13.2"
heapless = { git = "https://github.com/japaric/heapless", branch = "slab" }
pin-utils = "0.1.0-alpha.4"
typenum = "1.11.2"
typenum = "1.11.2"
11 changes: 4 additions & 7 deletions async-cortex-m/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use core::{
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};

use cortex_m::asm;
use heapless::Vec;
use pin_utils::pin_mut;

Expand Down Expand Up @@ -107,13 +108,9 @@ impl Executor {
}
}

// TODO try to sleep (WFI) here
// just calling WFI here will result in missed notifications because
// a `Waker` (called from an interrupt handler) may run just after
// we exit the `for` loop but before WFI is called. Then the system
// won't wake up until the *next* interrupt handler is triggered
// (which could end up never running if the applications used only a
// single interrupt)
// try to sleep; this will be a no-op if any of the previous tasks generated a SEV or an
// interrupt ran (regardless of whether it generated a wake-up or not)
asm::wfe();
};
self.in_block_on.set(false);
val
Expand Down
4 changes: 4 additions & 0 deletions async-cortex-m/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use core::{
task::{Context, Poll},
};

use cortex_m::asm;

use crate::executor;

/// Drives the future `f` to completion
Expand Down Expand Up @@ -39,7 +41,9 @@ pub async fn r#yield() {
Poll::Ready(())
} else {
self.yielded = true;
// wake ourselves
cx.waker().wake_by_ref();
asm::sev();
Poll::Pending
}
}
Expand Down
3 changes: 3 additions & 0 deletions async-cortex-m/src/unsync/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use core::{
task::{Context, Poll},
};

use cortex_m::asm;
use generic_array::{typenum::Unsigned, GenericArray};

use super::waker_set::WakerSet;
Expand Down Expand Up @@ -136,6 +137,7 @@ impl<T> Channel<T> {
self.read.set(read.wrapping_add(1));
// notify a sender
self.send_wakers.notify_one();
asm::sev();
Some(val)
} else {
// empty
Expand All @@ -160,6 +162,7 @@ impl<T> Channel<T> {
self.write.set(write.wrapping_add(1));
// notify a receiver
self.recv_wakers.notify_one();
asm::sev();
Ok(())
} else {
// full
Expand Down
3 changes: 3 additions & 0 deletions async-cortex-m/src/unsync/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use core::{
task::{Context, Poll},
};

use cortex_m::asm;

use super::waker_set::WakerSet;

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

Expand Down
2 changes: 1 addition & 1 deletion nrf52/examples/7-echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn main() -> ! {

let (mut tx, mut rx) = serial::take();
task::block_on(async {
let mut buf = [0; 16];
let mut buf = [0; 1];
loop {
rx.read(&mut buf).await;
tx.write(&buf).await;
Expand Down

0 comments on commit a008306

Please sign in to comment.