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",
|
"ed25519-compact",
|
||||||
"enum-iterator",
|
"enum-iterator",
|
||||||
"lang_items",
|
"lang_items",
|
||||||
|
"libtock_alarm",
|
||||||
"libtock_buttons",
|
"libtock_buttons",
|
||||||
"libtock_console",
|
"libtock_console",
|
||||||
"libtock_drivers",
|
"libtock_drivers",
|
||||||
@@ -374,6 +375,7 @@ dependencies = [
|
|||||||
name = "lang_items"
|
name = "lang_items"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"libtock_alarm",
|
||||||
"libtock_console",
|
"libtock_console",
|
||||||
"libtock_drivers",
|
"libtock_drivers",
|
||||||
"libtock_leds",
|
"libtock_leds",
|
||||||
@@ -389,6 +391,13 @@ version = "0.2.133"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libtock_alarm"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libtock_platform",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libtock_buttons"
|
name = "libtock_buttons"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -407,6 +416,7 @@ dependencies = [
|
|||||||
name = "libtock_drivers"
|
name = "libtock_drivers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"libtock_alarm",
|
||||||
"libtock_console",
|
"libtock_console",
|
||||||
"libtock_platform",
|
"libtock_platform",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ features = ["no_auto_layout", "no_debug_memop"]
|
|||||||
libtock_buttons = { path = "third_party/libtock-rs/apis/buttons" }
|
libtock_buttons = { path = "third_party/libtock-rs/apis/buttons" }
|
||||||
libtock_platform = { path = "third_party/libtock-rs/platform" }
|
libtock_platform = { path = "third_party/libtock-rs/platform" }
|
||||||
libtock_drivers = { path = "third_party/libtock-drivers" }
|
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_console = { path = "third_party/libtock-rs/apis/console" }
|
||||||
libtock_leds = { path = "third_party/libtock-rs/apis/leds" }
|
libtock_leds = { path = "third_party/libtock-rs/apis/leds" }
|
||||||
lang_items = { path = "third_party/lang-items" }
|
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.
|
// limitations under the License.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
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 libtock_platform::Syscalls;
|
||||||
use opensk::api::clock::Clock;
|
use opensk::api::clock::Clock;
|
||||||
|
|
||||||
@@ -63,7 +65,7 @@ impl<S: Syscalls> TockClock<S> {
|
|||||||
///
|
///
|
||||||
/// Call this regularly to timeout reliably despite wrapping clock ticks.
|
/// Call this regularly to timeout reliably despite wrapping clock ticks.
|
||||||
pub fn tickle(&mut self) {
|
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 {
|
if cur_tick < self.now.tick {
|
||||||
self.now.epoch += 1;
|
self.now.epoch += 1;
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ impl<S: Syscalls> Clock for TockClock<S> {
|
|||||||
fn make_timer(&mut self, milliseconds: usize) -> Self::Timer {
|
fn make_timer(&mut self, milliseconds: usize) -> Self::Timer {
|
||||||
let milliseconds = milliseconds as u32;
|
let milliseconds = milliseconds as u32;
|
||||||
self.tickle();
|
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) {
|
let delta_tick = match milliseconds.checked_mul(clock_frequency) {
|
||||||
Some(x) => x / 1000,
|
Some(x) => x / 1000,
|
||||||
// All CTAP timeouts are multiples of 100 so far. Worst case we timeout too early.
|
// 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")]
|
#[cfg(feature = "debug_ctap")]
|
||||||
fn timestamp_us(&mut self) -> usize {
|
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;
|
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
|
(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_platform = { path = "../../third_party/libtock-rs/platform" }
|
||||||
libtock_low_level_debug = { path = "../../third_party/libtock-rs/apis/low_level_debug" }
|
libtock_low_level_debug = { path = "../../third_party/libtock-rs/apis/low_level_debug" }
|
||||||
libtock_leds = { path = "../../third_party/libtock-rs/apis/leds" }
|
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" }
|
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }
|
||||||
|
|
||||||
[dependencies.linked_list_allocator]
|
[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_leds::Leds;
|
||||||
use libtock_low_level_debug::{AlertCode, LowLevelDebug};
|
use libtock_low_level_debug::{AlertCode, LowLevelDebug};
|
||||||
use libtock_platform as platform;
|
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 _ = 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() {
|
if let Ok(led_count) = Leds::<S>::count() {
|
||||||
for led in 0..led_count {
|
for led in 0..led_count {
|
||||||
let _ = Leds::<S>::off(led);
|
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() {
|
if let Ok(leds) = Leds::<S>::count() {
|
||||||
for led in 0..leds {
|
for led in 0..leds {
|
||||||
let _ = Leds::<S>::on(led);
|
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);
|
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"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
libtock_alarm = { path = "../../third_party/libtock-rs/apis/alarm" }
|
||||||
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }
|
libtock_console = { path = "../../third_party/libtock-rs/apis/console" }
|
||||||
libtock_platform = { path = "../../third_party/libtock-rs/platform" }
|
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
|
//! 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::result::{OtherError, TockResult};
|
||||||
use crate::util::Util;
|
|
||||||
use core::cell::Cell;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ops::{Add, AddAssign, Sub};
|
use core::ops::{Add, AddAssign, Sub};
|
||||||
|
use libtock_alarm::{Hz, Alarm, Milliseconds, Convert};
|
||||||
use libtock_platform as platform;
|
use libtock_platform as platform;
|
||||||
use libtock_platform::{share, DefaultConfig, ErrorCode, Syscalls};
|
use libtock_platform::{DefaultConfig, ErrorCode, Syscalls};
|
||||||
use platform::share::Handle;
|
use platform::share::Handle;
|
||||||
use platform::subscribe::OneId;
|
use platform::subscribe::OneId;
|
||||||
use platform::{Subscribe, Upcall};
|
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> {
|
pub struct Timer<S: Syscalls, C: platform::subscribe::Config = DefaultConfig> {
|
||||||
clock_frequency: Hz,
|
clock_frequency: Hz,
|
||||||
s: PhantomData<S>,
|
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>()?;
|
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.
|
// Alarm driver only returns success as only a single concurrent timer is supported.
|
||||||
|
|
||||||
let clock_frequency =
|
let clock_frequency = Alarm::<S>::get_frequency()?;
|
||||||
S::command(DRIVER_NUM, command::FREQUENCY, 0, 0).to_result::<u32, ErrorCode>()?;
|
|
||||||
|
|
||||||
if clock_frequency < 1_000 {
|
if clock_frequency.0 < 1_000 {
|
||||||
// The alarm's frequency must be at least 1 kHz.
|
// The alarm's frequency must be at least 1 kHz.
|
||||||
return Err(OtherError::TimerDriverErroneousClockFrequency.into());
|
return Err(OtherError::TimerDriverErroneousClockFrequency.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let clock_frequency = Hz(clock_frequency);
|
|
||||||
|
|
||||||
Ok(Timer {
|
Ok(Timer {
|
||||||
clock_frequency,
|
clock_frequency,
|
||||||
c: PhantomData,
|
c: PhantomData,
|
||||||
@@ -202,19 +110,8 @@ impl<S: Syscalls, C: platform::subscribe::Config> Timer<S, C> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(duration: Duration<isize>) -> TockResult<()> {
|
pub fn get_ticks() -> TockResult<u32> {
|
||||||
let expired = Cell::new(false);
|
Ok(S::command(DRIVER_NUM, command::TIME, 0, 0).to_result::<u32, ErrorCode>()?)
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the clock frequency of the timer.
|
/// 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.
|
/// Returns the current counter tick value.
|
||||||
pub fn get_current_counter_ticks(&self) -> TockResult<ClockValue> {
|
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 {
|
Ok(ClockValue {
|
||||||
num_ticks: ticks as isize,
|
num_ticks: Self::get_ticks()? as isize,
|
||||||
clock_frequency: self.clock_frequency(),
|
clock_frequency: self.clock_frequency(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user