Remove duplicated alarm syscall. (#636)
The alarm syscall is implemented in libtock-rs, but was duplicated here. This removes the duplicated code and changes the references to point to libtock-rs directly. Co-authored-by: kaczmarczyck <43844792+kaczmarczyck@users.noreply.github.com>
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -168,6 +168,7 @@ dependencies = [
|
||||
"ed25519-compact",
|
||||
"enum-iterator",
|
||||
"lang_items",
|
||||
"libtock_alarm",
|
||||
"libtock_buttons",
|
||||
"libtock_console",
|
||||
"libtock_drivers",
|
||||
@@ -374,6 +375,7 @@ dependencies = [
|
||||
name = "lang_items"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_alarm",
|
||||
"libtock_console",
|
||||
"libtock_drivers",
|
||||
"libtock_leds",
|
||||
@@ -389,6 +391,13 @@ version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "libtock_alarm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_platform",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libtock_buttons"
|
||||
version = "0.1.0"
|
||||
@@ -407,6 +416,7 @@ dependencies = [
|
||||
name = "libtock_drivers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libtock_alarm",
|
||||
"libtock_console",
|
||||
"libtock_platform",
|
||||
]
|
||||
|
||||
@@ -19,6 +19,7 @@ features = ["no_auto_layout", "no_debug_memop"]
|
||||
libtock_buttons = { path = "third_party/libtock-rs/apis/buttons" }
|
||||
libtock_platform = { path = "third_party/libtock-rs/platform" }
|
||||
libtock_drivers = { path = "third_party/libtock-drivers" }
|
||||
libtock_alarm = { path = "third_party/libtock-rs/apis/alarm" }
|
||||
libtock_console = { path = "third_party/libtock-rs/apis/console" }
|
||||
libtock_leds = { path = "third_party/libtock-rs/apis/leds" }
|
||||
lang_items = { path = "third_party/lang-items" }
|
||||
|
||||
10
src/env/tock/clock.rs
vendored
10
src/env/tock/clock.rs
vendored
@@ -13,7 +13,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use libtock_drivers::timer::{get_clock_frequency, get_ticks};
|
||||
use libtock_alarm::Alarm;
|
||||
use libtock_drivers::result::FlexUnwrap;
|
||||
use libtock_drivers::timer::Timer;
|
||||
use libtock_platform::Syscalls;
|
||||
use opensk::api::clock::Clock;
|
||||
|
||||
@@ -63,7 +65,7 @@ impl<S: Syscalls> TockClock<S> {
|
||||
///
|
||||
/// Call this regularly to timeout reliably despite wrapping clock ticks.
|
||||
pub fn tickle(&mut self) {
|
||||
let cur_tick = get_ticks::<S>().ok().unwrap();
|
||||
let cur_tick = Timer::<S>::get_ticks().flex_unwrap();
|
||||
if cur_tick < self.now.tick {
|
||||
self.now.epoch += 1;
|
||||
}
|
||||
@@ -77,7 +79,7 @@ impl<S: Syscalls> Clock for TockClock<S> {
|
||||
fn make_timer(&mut self, milliseconds: usize) -> Self::Timer {
|
||||
let milliseconds = milliseconds as u32;
|
||||
self.tickle();
|
||||
let clock_frequency = get_clock_frequency::<S>().ok().unwrap();
|
||||
let clock_frequency = Alarm::<S>::get_frequency().ok().unwrap().0;
|
||||
let delta_tick = match milliseconds.checked_mul(clock_frequency) {
|
||||
Some(x) => x / 1000,
|
||||
// All CTAP timeouts are multiples of 100 so far. Worst case we timeout too early.
|
||||
@@ -95,7 +97,7 @@ impl<S: Syscalls> Clock for TockClock<S> {
|
||||
|
||||
#[cfg(feature = "debug_ctap")]
|
||||
fn timestamp_us(&mut self) -> usize {
|
||||
let clock_frequency = get_clock_frequency::<S>().ok().unwrap();
|
||||
let clock_frequency = Alarm::<S>::get_frequency().ok().unwrap().0;
|
||||
let total_ticks = 0x100_0000u64 * self.now.epoch as u64 + self.now.tick as u64;
|
||||
(total_ticks.wrapping_mul(1_000_000u64) / clock_frequency as u64) as usize
|
||||
}
|
||||
|
||||
1
third_party/lang-items/Cargo.toml
vendored
1
third_party/lang-items/Cargo.toml
vendored
@@ -18,6 +18,7 @@ libtock_drivers = { path = "../libtock-drivers" }
|
||||
libtock_platform = { path = "../../third_party/libtock-rs/platform" }
|
||||
libtock_low_level_debug = { path = "../../third_party/libtock-rs/apis/low_level_debug" }
|
||||
libtock_leds = { path = "../../third_party/libtock-rs/apis/leds" }
|
||||
libtock_alarm = { path = "../../third_party/libtock-rs/apis/alarm" }
|
||||
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }
|
||||
|
||||
[dependencies.linked_list_allocator]
|
||||
|
||||
8
third_party/lang-items/src/util.rs
vendored
8
third_party/lang-items/src/util.rs
vendored
@@ -1,4 +1,4 @@
|
||||
use libtock_drivers::timer;
|
||||
use libtock_alarm::{Alarm, Milliseconds};
|
||||
use libtock_leds::Leds;
|
||||
use libtock_low_level_debug::{AlertCode, LowLevelDebug};
|
||||
use libtock_platform as platform;
|
||||
@@ -28,13 +28,13 @@ impl<S: Syscalls, C: platform::subscribe::Config> Util<S, C> {
|
||||
let _ = Leds::<S>::on(led);
|
||||
}
|
||||
}
|
||||
let _ = timer::Alarm::<S, C>::sleep_for(timer::Milliseconds(100));
|
||||
let _ = Alarm::<S, C>::sleep_for(Milliseconds(100));
|
||||
if let Ok(led_count) = Leds::<S>::count() {
|
||||
for led in 0..led_count {
|
||||
let _ = Leds::<S>::off(led);
|
||||
}
|
||||
}
|
||||
let _ = timer::Alarm::<S, C>::sleep_for(timer::Milliseconds(100));
|
||||
let _ = Alarm::<S, C>::sleep_for(Milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ impl<S: Syscalls, C: platform::subscribe::Config> Util<S, C> {
|
||||
if let Ok(leds) = Leds::<S>::count() {
|
||||
for led in 0..leds {
|
||||
let _ = Leds::<S>::on(led);
|
||||
let _ = timer::Alarm::<S, C>::sleep_for(timer::Milliseconds(100));
|
||||
let _ = Alarm::<S, C>::sleep_for(Milliseconds(100));
|
||||
let _ = Leds::<S>::off(led);
|
||||
}
|
||||
}
|
||||
|
||||
1
third_party/libtock-drivers/Cargo.toml
vendored
1
third_party/libtock-drivers/Cargo.toml
vendored
@@ -9,6 +9,7 @@ license = "MIT/Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
libtock_alarm = { path = "../../third_party/libtock-rs/apis/alarm" }
|
||||
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }
|
||||
libtock_platform = { path = "../../third_party/libtock-rs/platform" }
|
||||
|
||||
|
||||
121
third_party/libtock-drivers/src/timer.rs
vendored
121
third_party/libtock-drivers/src/timer.rs
vendored
@@ -8,105 +8,16 @@
|
||||
//!
|
||||
//! Adapted from the [libtock-rs](https://github.com/tock/libtock-rs/blob/master/apis/alarm/src/lib.rs) alarm driver interface
|
||||
|
||||
use crate::result::{FlexUnwrap, OtherError, TockError, TockResult};
|
||||
use crate::util::Util;
|
||||
use core::cell::Cell;
|
||||
use crate::result::{OtherError, TockResult};
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Add, AddAssign, Sub};
|
||||
use libtock_alarm::{Hz, Alarm, Milliseconds, Convert};
|
||||
use libtock_platform as platform;
|
||||
use libtock_platform::{share, DefaultConfig, ErrorCode, Syscalls};
|
||||
use libtock_platform::{DefaultConfig, ErrorCode, Syscalls};
|
||||
use platform::share::Handle;
|
||||
use platform::subscribe::OneId;
|
||||
use platform::{Subscribe, Upcall};
|
||||
|
||||
pub struct Alarm<S: Syscalls, C: platform::subscribe::Config = DefaultConfig>(S, C);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Hz(pub u32);
|
||||
|
||||
pub trait Convert {
|
||||
/// Converts a time unit by rounding up.
|
||||
fn to_ticks(self, freq: Hz) -> Ticks;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Ticks(pub u32);
|
||||
|
||||
impl Convert for Ticks {
|
||||
fn to_ticks(self, _freq: Hz) -> Ticks {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ticks<S: Syscalls>() -> TockResult<u32> {
|
||||
Ok(S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?)
|
||||
}
|
||||
|
||||
pub fn get_clock_frequency<S: Syscalls>() -> TockResult<u32> {
|
||||
Ok(S::command(DRIVER_NUM, command::FREQUENCY, 0, 0).to_result::<u32, ErrorCode>()?)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Milliseconds(pub u32);
|
||||
|
||||
impl Convert for Milliseconds {
|
||||
fn to_ticks(self, freq: Hz) -> Ticks {
|
||||
// Saturating multiplication will top out at about 1 hour at 1MHz.
|
||||
// It's large enough for an alarm, and much simpler than failing
|
||||
// or losing precision for short sleeps.
|
||||
|
||||
/// u32::div_ceil is still unstable.
|
||||
fn div_ceil(a: u32, other: u32) -> u32 {
|
||||
let d = a / other;
|
||||
let m = a % other;
|
||||
if m == 0 {
|
||||
d
|
||||
} else {
|
||||
d + 1
|
||||
}
|
||||
}
|
||||
Ticks(div_ceil(self.0.saturating_mul(freq.0), 1000))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Syscalls, C: platform::subscribe::Config> Alarm<S, C> {
|
||||
/// Run a check against the console capsule to ensure it is present.
|
||||
///
|
||||
/// Returns number of concurrent notifications supported,
|
||||
/// 0 if unbounded.
|
||||
#[inline(always)]
|
||||
pub fn driver_check() -> Result<u32, ErrorCode> {
|
||||
S::command(DRIVER_NUM, command::DRIVER_CHECK, 0, 0).to_result()
|
||||
}
|
||||
|
||||
pub fn get_frequency() -> Result<Hz, ErrorCode> {
|
||||
S::command(DRIVER_NUM, command::FREQUENCY, 0, 0)
|
||||
.to_result()
|
||||
.map(Hz)
|
||||
}
|
||||
|
||||
pub fn sleep_for<T: Convert>(time: T) -> Result<(), ErrorCode> {
|
||||
let freq = Self::get_frequency()?;
|
||||
let ticks = time.to_ticks(freq);
|
||||
|
||||
let called: Cell<Option<(u32, u32)>> = Cell::new(None);
|
||||
share::scope(|subscribe| {
|
||||
S::subscribe::<_, _, C, DRIVER_NUM, { subscribe::CALLBACK }>(subscribe, &called)?;
|
||||
|
||||
S::command(DRIVER_NUM, command::SET_RELATIVE, ticks.0, 0)
|
||||
.to_result()
|
||||
.map(|_when: u32| ())?;
|
||||
|
||||
loop {
|
||||
S::yield_wait();
|
||||
if let Some((_when, _ref)) = called.get() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Timer<S: Syscalls, C: platform::subscribe::Config = DefaultConfig> {
|
||||
clock_frequency: Hz,
|
||||
s: PhantomData<S>,
|
||||
@@ -157,16 +68,13 @@ impl<S: Syscalls, C: platform::subscribe::Config, CB: Fn(ClockValue)>
|
||||
S::command(DRIVER_NUM, command::DRIVER_CHECK, 0, 0).to_result::<(), ErrorCode>()?;
|
||||
// Alarm driver only returns success as only a single concurrent timer is supported.
|
||||
|
||||
let clock_frequency =
|
||||
S::command(DRIVER_NUM, command::FREQUENCY, 0, 0).to_result::<u32, ErrorCode>()?;
|
||||
let clock_frequency = Alarm::<S>::get_frequency()?;
|
||||
|
||||
if clock_frequency < 1_000 {
|
||||
if clock_frequency.0 < 1_000 {
|
||||
// The alarm's frequency must be at least 1 kHz.
|
||||
return Err(OtherError::TimerDriverErroneousClockFrequency.into());
|
||||
}
|
||||
|
||||
let clock_frequency = Hz(clock_frequency);
|
||||
|
||||
Ok(Timer {
|
||||
clock_frequency,
|
||||
c: PhantomData,
|
||||
@@ -202,19 +110,8 @@ impl<S: Syscalls, C: platform::subscribe::Config> Timer<S, C> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sleep(duration: Duration<isize>) -> TockResult<()> {
|
||||
let expired = Cell::new(false);
|
||||
let mut with_callback = with_callback::<S, C, _>(|_| expired.set(true));
|
||||
|
||||
let mut timer = with_callback.init().flex_unwrap();
|
||||
timer.set_alarm(duration).flex_unwrap();
|
||||
|
||||
Util::<S>::yieldk_for(|| expired.get());
|
||||
|
||||
match timer.stop_alarm() {
|
||||
Ok(_) | Err(TockError::Command(ErrorCode::Already)) => Ok(()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
pub fn get_ticks() -> TockResult<u32> {
|
||||
Ok(S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?)
|
||||
}
|
||||
|
||||
/// Returns the clock frequency of the timer.
|
||||
@@ -224,10 +121,8 @@ impl<S: Syscalls, C: platform::subscribe::Config> Timer<S, C> {
|
||||
|
||||
/// Returns the current counter tick value.
|
||||
pub fn get_current_counter_ticks(&self) -> TockResult<ClockValue> {
|
||||
let ticks = S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?;
|
||||
|
||||
Ok(ClockValue {
|
||||
num_ticks: ticks as isize,
|
||||
num_ticks: Self::get_ticks()? as isize,
|
||||
clock_frequency: self.clock_frequency(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user