pub struct Clock<const HZ: u32>(*mut ztimer_clock_t);
riot_module_ztimer
only.Expand description
A clock that knows about its frequency. The pulse length is not given in core::time::Duration as that’s not yet supported by const generics, and because clock rates are often easier to express in Hertz than in multiples of 10^-n seconds.
Tuple Fields§
§0: *mut ztimer_clock_t
Implementations§
Source§impl<const HZ: u32> ValueInThread<Clock<HZ>>
impl<const HZ: u32> ValueInThread<Clock<HZ>>
Sourcepub fn sleep(&self, duration: Ticks<HZ>)
pub fn sleep(&self, duration: Ticks<HZ>)
Pause the current thread for the duration of ticks in the timer’s time scale.
Wraps ztimer_sleep
Sourcepub fn spin(&self, duration: Ticks<HZ>)
pub fn spin(&self, duration: Ticks<HZ>)
Keep the current thread in a busy loop until the duration of ticks in the timer’s tim scale has passed
Quoting the original documentation, “This blocks lower priority threads. Use only for very short delays.”.
Wraps ztimer_spin
Note that this would not technically require the self to be a ValueInThread (as spinning is doable in an ISR), but it’s so discouraged that the Rust wrapper takes the position that it’s best done using a ValueInThread.
Sourcepub fn sleep_extended(&self, duration: Duration)
pub fn sleep_extended(&self, duration: Duration)
Pause the current thread for the given duration, possibly exceeding values expressible in
Ticks<HZ>
.
The duration is converted into ticks (rounding up), and overflows are caught by sleeping multiple times.
It is up to the caller to select the Clock suitable for efficiency. (Even sleeping for seconds on the microseconds timer would not overflow the timer’s interface’s u32, but the same multiple-sleeps trick may need to be employed by the implementation, and would keep the system from entering deeper sleep modes).
Sourcepub fn set_during<I: FnOnce() + Send, M: FnOnce() -> R, R>(
&self,
callback: I,
ticks: Ticks<HZ>,
in_thread: M,
) -> R
pub fn set_during<I: FnOnce() + Send, M: FnOnce() -> R, R>( &self, callback: I, ticks: Ticks<HZ>, in_thread: M, ) -> R
Set the given callback to be executed in an interrupt some ticks in the future.
Then, start the in_thread function from in the thread this is called from (as a regular function call).
After the in_thread function terminates, the callback is dropped if it has not already triggered.
Further Development:
-
This could probably be done with some sort of pinning instead, thus avoiding the nested scope – but getting the Drop right is comparatively tricky, because when done naively it needs runtime state.
-
The callback could be passed something extra that enables it to set the timer again and again. Granted, there’s ztimer_periodic for these cases (and it has better drifting properties), but for something like exponential retransmission it could be convenient.
(Might make sense to do this without an extra function variant: if the callback ignores the timer argument and always returns None, that’s all in the caller type and probebly inlined right away).
While (unless with sleep) nothing would break if this were called from an interrupt
context, it would not work either: As RIOT uses flat interrupt priorities, any code
executed in the in_thread
handler would still be run in the original interrupt, and while
the configured ZTimer would fire its interrupt during that time, the interrupt would not be
serviced, and the timer would be removed already by the time the original interrupt
completes and ZTimer is serviced (finding no actually pending callback).
Source§impl<const HZ: u32> Clock<HZ>
impl<const HZ: u32> Clock<HZ>
Sourcepub async fn sleep_async(&self, duration: Ticks<HZ>)
pub async fn sleep_async(&self, duration: Ticks<HZ>)
Similar to [.sleep()
], but this does not block but creates a future to be
.await
ed.
Note that time starts running only when this is polled, for otherwise there’s no pinned Self around.
Sourcefn now(&self) -> Timestamp<HZ>
fn now(&self) -> Timestamp<HZ>
A ztimer_now()
wrapper that is not public because there needs to be a reason why the
result makes sense, which can come for example from an acquisition.
Sourcefn set_during<I: FnOnce() + Send, M: FnOnce() -> R, R>(
&self,
callback: I,
ticks: Ticks<HZ>,
in_thread: M,
) -> R
fn set_during<I: FnOnce() + Send, M: FnOnce() -> R, R>( &self, callback: I, ticks: Ticks<HZ>, in_thread: M, ) -> R
A version of ValueInThread<Clock>::set_during
that relies on this module’s knowledge of
the circumstances to state the validity of its use even without a ValueInThread
Sourcepub fn acquire(&self) -> LockedClock<HZ>
pub fn acquire(&self) -> LockedClock<HZ>
Keep the clock being shut down or reset for low power modes
While the clock is locked, its LockedClock::now()
method is available, and its values
can be compared.
Sourcepub fn time(&self, closure: impl FnOnce()) -> Option<Ticks<HZ>>
pub fn time(&self, closure: impl FnOnce()) -> Option<Ticks<HZ>>
Run a closure and measure the time it takes.
If the time the closure took exceeded the 2³²-1 ticks (the maximum time measurable on that clock), None is returned.
Sourcepub fn time_with_result<R>(
&self,
closure: impl FnOnce() -> R,
) -> (Option<Ticks<HZ>>, R)
pub fn time_with_result<R>( &self, closure: impl FnOnce() -> R, ) -> (Option<Ticks<HZ>>, R)
Like Self::time()
, but allowing the closure to return a value.
As an implementation note, this is not using ztimer_stopwatch
because that can not detect
overflows; if overflow detection is added to ztimer_stopwatch
later, the implementation
can change.
Source§impl Clock<1>
impl Clock<1>
Sourcepub fn sec() -> ValueInThread<Self>
Available on riot_module_ztimer_sec
only.
pub fn sec() -> ValueInThread<Self>
riot_module_ztimer_sec
only.Get the global second ZTimer clock, ZTIMER_SEC.
This function verifies (at a small runtime cost) that the caller is in a thread context.
This can be avoided by calling in_thread.promote(Clock::sec_unbound())
on an existing
crate::thread::InThread token.
Sourcepub fn sec_unbound() -> Self
Available on riot_module_ztimer_sec
only.
pub fn sec_unbound() -> Self
riot_module_ztimer_sec
only.Get the global second ZTimer clock, ZTIMER_SEC.
The clock is not packed in a ValueInThread, which makes the blocking sleep methods and delay implementations unavailable, but works even in interrupts contexts.
Source§impl Clock<1000>
impl Clock<1000>
Sourcepub fn msec() -> ValueInThread<Self>
Available on riot_module_ztimer_msec
only.
pub fn msec() -> ValueInThread<Self>
riot_module_ztimer_msec
only.Get the global milliseconds ZTimer clock, ZTIMER_MSEC.
This function verifies (at a small runtime cost) that the caller is in a thread context.
This can be avoided by calling in_thread.promote(Clock::msec_unbound())
on an existing
crate::thread::InThread token.
Sourcepub fn msec_unbound() -> Self
Available on riot_module_ztimer_msec
only.
pub fn msec_unbound() -> Self
riot_module_ztimer_msec
only.Get the global milliseconds ZTimer clock, ZTIMER_MSEC.
The clock is not packed in a ValueInThread, which makes the blocking sleep methods and delay implementations unavailable, but works even in interrupts contexts.
Source§impl Clock<1000000>
impl Clock<1000000>
Sourcepub fn usec() -> ValueInThread<Self>
Available on riot_module_ztimer_usec
only.
pub fn usec() -> ValueInThread<Self>
riot_module_ztimer_usec
only.Get the global microseconds ZTimer clock, ZTIMER_USEC.
This function verifies (at a small runtime cost) that the caller is in a thread context.
This can be avoided by calling in_thread.promote(Clock::usec_unbound())
on an existing
crate::thread::InThread token.
Sourcepub fn usec_unbound() -> Self
Available on riot_module_ztimer_usec
only.
pub fn usec_unbound() -> Self
riot_module_ztimer_usec
only.Get the global microseconds ZTimer clock, ZTIMER_USEC.
The clock is not packed in a ValueInThread, which makes the blocking sleep methods and delay implementations unavailable, but works even in interrupts contexts.
Trait Implementations§
Source§impl<const F: u32> DelayNs for ValueInThread<Clock<F>>
impl<const F: u32> DelayNs for ValueInThread<Clock<F>>
Source§fn delay_ns(&mut self, ns: u32)
fn delay_ns(&mut self, ns: u32)
ns
nanoseconds. Pause can be longer
if the implementation requires it due to precision/timing issues.impl<const HZ: u32> Copy for Clock<HZ>
Auto Trait Implementations§
impl<const HZ: u32> Freeze for Clock<HZ>
impl<const HZ: u32> RefUnwindSafe for Clock<HZ>
impl<const HZ: u32> !Send for Clock<HZ>
impl<const HZ: u32> !Sync for Clock<HZ>
impl<const HZ: u32> Unpin for Clock<HZ>
impl<const HZ: u32> UnwindSafe for Clock<HZ>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoSwitch for T
impl<T> IntoSwitch for T
Source§fn into_switch<ActiveLevel>(self) -> Switch<T, ActiveLevel>
fn into_switch<ActiveLevel>(self) -> Switch<T, ActiveLevel>
Source§fn into_active_high_switch(self) -> Switch<Self, ActiveHigh>where
Self: Sized,
fn into_active_high_switch(self) -> Switch<Self, ActiveHigh>where
Self: Sized,
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 4 bytes