Add general purpose waiting future
diff --git a/examples/adc.rs b/examples/adc.rs
index 8ba602b..5af2521 100644
--- a/examples/adc.rs
+++ b/examples/adc.rs
@@ -16,6 +16,6 @@
loop {
adc.sample(0).unwrap();
- timer::sleep(Duration::from_ms(2000));
+ timer::sleep_sync(Duration::from_ms(2000));
}
}
diff --git a/examples/blink.rs b/examples/blink.rs
index 8e8980e..c011be0 100644
--- a/examples/blink.rs
+++ b/examples/blink.rs
@@ -1,5 +1,6 @@
#![no_std]
+use core::executor;
use libtock::led;
use libtock::timer;
use libtock::timer::Duration;
@@ -21,6 +22,6 @@
count = count.wrapping_add(1);
// This delay uses an underlying timer in the kernel.
- timer::sleep(Duration::from_ms(250));
+ executor::block_on(timer::sleep(Duration::from_ms(250)));
}
}
diff --git a/examples/blink_random.rs b/examples/blink_random.rs
index d114d39..748de9a 100644
--- a/examples/blink_random.rs
+++ b/examples/blink_random.rs
@@ -16,9 +16,9 @@
for &x in buf.iter() {
blink_nibble(x);
- timer::sleep(Duration::from_ms(100));
+ timer::sleep_sync(Duration::from_ms(100));
blink_nibble(x >> 4);
- timer::sleep(Duration::from_ms(100));
+ timer::sleep_sync(Duration::from_ms(100));
}
}
}
diff --git a/examples/button_leds.rs b/examples/button_leds.rs
index 2ab7615..ba91486 100644
--- a/examples/button_leds.rs
+++ b/examples/button_leds.rs
@@ -22,6 +22,6 @@
}
loop {
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/examples/button_read.rs b/examples/button_read.rs
index 539fa6c..507449b 100644
--- a/examples/button_read.rs
+++ b/examples/button_read.rs
@@ -20,6 +20,6 @@
ButtonState::Released => writeln!(console, "released"),
}
.unwrap();
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/examples/button_subscribe.rs b/examples/button_subscribe.rs
index 6644e8d..2d35679 100644
--- a/examples/button_subscribe.rs
+++ b/examples/button_subscribe.rs
@@ -31,6 +31,6 @@
}
loop {
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/examples/gpio.rs b/examples/gpio.rs
index a09a2b2..1e918e2 100644
--- a/examples/gpio.rs
+++ b/examples/gpio.rs
@@ -11,8 +11,8 @@
loop {
pin.set_high();
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
pin.set_low();
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/examples/gpio_read.rs b/examples/gpio_read.rs
index a5d7f5b..b5ec69b 100644
--- a/examples/gpio_read.rs
+++ b/examples/gpio_read.rs
@@ -18,6 +18,6 @@
} else {
writeln!(console, "false").unwrap();
}
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/examples/hello.rs b/examples/hello.rs
index a1e30f2..0117c74 100644
--- a/examples/hello.rs
+++ b/examples/hello.rs
@@ -10,6 +10,6 @@
for i in 0.. {
writeln!(console, "Hello world! {}", i).unwrap();
- timer::sleep(Duration::from_ms(500))
+ timer::sleep_sync(Duration::from_ms(500))
}
}
diff --git a/examples/sensors.rs b/examples/sensors.rs
index 7b3afd3..f565629 100644
--- a/examples/sensors.rs
+++ b/examples/sensors.rs
@@ -17,6 +17,6 @@
writeln!(console, "Temperature: {}\n", temperature.read()).unwrap();
writeln!(console, "Light: {}\n", light.read()).unwrap();
writeln!(console, "Accel: {}\n", ninedof.read_acceleration()).unwrap();
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/examples/seven_segment.rs b/examples/seven_segment.rs
index 9f767e6..22ece37 100644
--- a/examples/seven_segment.rs
+++ b/examples/seven_segment.rs
@@ -33,6 +33,6 @@
loop {
i = (i + 1) % 11;
shift_register.write_bits(&number_to_bits(i));
- timer::sleep(Duration::from_ms(200));
+ timer::sleep_sync(Duration::from_ms(200));
}
}
diff --git a/examples/simple_ble.rs b/examples/simple_ble.rs
index a467f97..65f6d42 100644
--- a/examples/simple_ble.rs
+++ b/examples/simple_ble.rs
@@ -44,8 +44,8 @@
loop {
led.on();
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
led.off();
- timer::sleep(Duration::from_ms(500));
+ timer::sleep_sync(Duration::from_ms(500));
}
}
diff --git a/src/console.rs b/src/console.rs
index ecd7ad1..7942fb7 100644
--- a/src/console.rs
+++ b/src/console.rs
@@ -1,5 +1,7 @@
+use crate::futures;
use crate::syscalls;
use core::cell::Cell;
+use core::executor;
use core::fmt;
const DRIVER_NUMBER: usize = 1;
@@ -65,7 +67,7 @@
return;
}
- syscalls::yieldk_for(|| is_written.get());
+ executor::block_on(futures::wait_until(|| is_written.get()));
}
}
diff --git a/src/futures.rs b/src/futures.rs
new file mode 100644
index 0000000..0223507
--- /dev/null
+++ b/src/futures.rs
@@ -0,0 +1,29 @@
+use core::future::Future;
+use core::pin::Pin;
+use core::task::Context;
+use core::task::Poll;
+
+// TODO: Consider using FnMut
+pub async fn wait_until<F: Fn() -> bool>(condition: F) {
+ wait_for_value(move || if condition() { Some(()) } else { None }).await
+}
+
+pub async fn wait_for_value<T, F: Fn() -> Option<T>>(value_provider: F) -> T {
+ WaitForValue { value_provider }.await
+}
+
+struct WaitForValue<F> {
+ value_provider: F,
+}
+
+impl<T, F: Fn() -> Option<T>> Future for WaitForValue<F> {
+ type Output = T;
+
+ fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+ if let Some(value) = (self.value_provider)() {
+ Poll::Ready(value)
+ } else {
+ Poll::Pending
+ }
+ }
+}
diff --git a/src/lang_items.rs b/src/lang_items.rs
index 6d91bb0..39deb02 100644
--- a/src/lang_items.rs
+++ b/src/lang_items.rs
@@ -48,11 +48,11 @@
for led in led::all() {
led.on();
}
- timer::sleep(Duration::from_ms(100));
+ timer::sleep_sync(Duration::from_ms(100));
for led in led::all() {
led.off();
}
- timer::sleep(Duration::from_ms(100));
+ timer::sleep_sync(Duration::from_ms(100));
}
}
@@ -61,7 +61,7 @@
loop {
for led in led::all() {
led.on();
- timer::sleep(Duration::from_ms(100));
+ timer::sleep_sync(Duration::from_ms(100));
led.off();
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 1d4f26b..004c4d3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,6 +19,7 @@
pub mod console;
pub mod debug;
pub mod electronics;
+pub mod futures;
pub mod gpio;
pub mod led;
pub mod memop;
diff --git a/src/rng.rs b/src/rng.rs
index 411030e..915745c 100644
--- a/src/rng.rs
+++ b/src/rng.rs
@@ -1,5 +1,7 @@
+use crate::futures;
use crate::syscalls;
use core::cell::Cell;
+use core::executor;
const DRIVER_NUMBER: usize = 0x40001;
@@ -40,6 +42,6 @@
return false;
}
- syscalls::yieldk_for(|| is_filled.get());
+ executor::block_on(futures::wait_until(|| is_filled.get()));
return true;
}
diff --git a/src/sensors/mod.rs b/src/sensors/mod.rs
index f15a9db..7e62d8e 100644
--- a/src/sensors/mod.rs
+++ b/src/sensors/mod.rs
@@ -1,6 +1,8 @@
-use crate::syscalls::{self, yieldk_for};
+use crate::futures;
+use crate::syscalls;
use core::cell::Cell;
use core::convert::From;
+use core::executor;
use core::fmt;
use core::mem;
@@ -30,7 +32,7 @@
mem::transmute(&res),
);
syscalls::command(driver_num, 1, 0, 0);
- yieldk_for(|| res.get().is_some());
+ executor::block_on(futures::wait_until(|| res.get().is_some()));
res.get().unwrap()
}
}
diff --git a/src/sensors/ninedof.rs b/src/sensors/ninedof.rs
index a7a3a7e..7c347c8 100644
--- a/src/sensors/ninedof.rs
+++ b/src/sensors/ninedof.rs
@@ -1,5 +1,7 @@
-use crate::syscalls::{self, yieldk_for};
+use crate::futures;
+use crate::syscalls;
use core::cell::Cell;
+use core::executor;
use core::fmt;
use core::mem;
@@ -36,7 +38,7 @@
unsafe {
subscribe(Self::cb, mem::transmute(&res));
start_accel_reading();
- yieldk_for(|| res.ready.get());
+ executor::block_on(futures::wait_until(|| res.ready.get()));
}
res.res.get()
}
@@ -46,7 +48,7 @@
unsafe {
subscribe(Self::cb, mem::transmute(&res));
start_magnetometer_reading();
- yieldk_for(|| res.ready.get());
+ executor::block_on(futures::wait_until(|| res.ready.get()));
}
res.res.get()
}
diff --git a/src/syscalls.rs b/src/syscalls.rs
index f4caca0..8aed414 100644
--- a/src/syscalls.rs
+++ b/src/syscalls.rs
@@ -56,12 +56,6 @@
}
}
-pub fn yieldk_for<F: Fn() -> bool>(cond: F) {
- while !cond() {
- yieldk();
- }
-}
-
pub fn subscribe<CB: SubscribableCallback>(
driver_number: usize,
subscribe_number: usize,
diff --git a/src/timer.rs b/src/timer.rs
index ae60b07..94359c1 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -1,10 +1,12 @@
use crate::callback::CallbackSubscription;
use crate::callback::SubscribableCallback;
+use crate::futures;
use crate::result;
use crate::result::TockResult;
use crate::result::TockValue;
use crate::syscalls;
use core::cell::Cell;
+use core::executor;
use core::isize;
use core::ops::{Add, AddAssign, Sub};
@@ -22,14 +24,24 @@
pub const SUBSCRIBE_CALLBACK: usize = 0;
}
-pub fn sleep(duration: Duration<isize>) {
+pub fn sleep_sync(duration: Duration<isize>) {
let expired = Cell::new(false);
let mut with_callback = with_callback(|_, _| expired.set(true));
let mut timer = with_callback.init().unwrap();
timer.set_alarm(duration).unwrap();
- syscalls::yieldk_for(|| expired.get());
+ executor::block_on(futures::wait_until(|| expired.get()));
+}
+
+pub async fn sleep(duration: Duration<isize>) {
+ let expired = Cell::new(false);
+ let mut with_callback = with_callback(|_, _| expired.set(true));
+
+ let mut timer = with_callback.init().unwrap();
+ timer.set_alarm(duration).unwrap();
+
+ futures::wait_until(|| expired.get()).await;
}
pub fn with_callback<CB>(callback: CB) -> WithCallback<CB> {