* fix included examples and markdown(book) fixes: #911 * fix footnote pre_init * more example link updates * Restore pool example name * Example: pool: Upgrade to heapless v0.8 * Example: pool: thumbv6 unsupported: wild cfg-if Experiment with multi-backend example contained in the example * Example: lm3s6965: Updated cargo.lock * Book: Use cargo xtask for by-example * Docs: Contributing: cargo xtask --------- Co-authored-by: Henrik Tjäder <henrik@tjaders.com>
2.8 KiB
Monotonic & spawn_{at/after}
The understanding of time is an important concept in embedded systems, and to be able to run tasks
based on time is essential. The framework provides the static methods
task::spawn_after(/* duration */)
and task::spawn_at(/* specific time instant */)
.
spawn_after
is more commonly used, but in cases where it's needed to have spawns happen
without drift or to a fixed baseline spawn_at
is available.
The #[monotonic]
attribute, applied to a type alias definition, exists to support this.
This type alias must point to a type which implements the rtic_monotonic::Monotonic
trait.
This is generally some timer which handles the timing of the system.
One or more monotonics can coexist in the same system, for example a slow timer that wakes the
system from sleep and another which purpose is for fine grained scheduling while the
system is awake.
The attribute has one required parameter and two optional parameters, binds
, default
and
priority
respectively.
The required parameter, binds = InterruptName
, associates an interrupt vector to the timer's
interrupt, while default = true
enables a shorthand API when spawning and accessing
time (monotonics::now()
vs monotonics::MyMono::now()
), and priority
sets the priority
of the interrupt vector.
The default
priority
is the maximum priority of the system. If your system has a high priority task with tight scheduling requirements, it might be desirable to demote themonotonic
task to a lower priority to reduce scheduling jitter for the high priority task. This however might introduce jitter and delays into scheduling via themonotonic
, making it a trade-off.
The monotonics are initialized in #[init]
and returned within the init::Monotonic( ... )
tuple.
This activates the monotonics making it possible to use them.
See the following example:
{{#include ../../../../examples/schedule.rs}}
$ cargo xtask qemu --verbose --example schedule
{{#include ../../../../ci/expected/schedule.run}}
A key requirement of a Monotonic is that it must deal gracefully with hardware timer overruns.
Canceling or rescheduling a scheduled task
Tasks spawned using task::spawn_after
and task::spawn_at
returns a SpawnHandle
,
which allows canceling or rescheduling of the task scheduled to run in the future.
If cancel
or reschedule_at
/reschedule_after
returns an Err
it means that the operation was
too late and that the task is already sent for execution. The following example shows this in action:
{{#include ../../../../examples/cancel-reschedule.rs}}
$ cargo xtask qemu --verbose --example cancel-reschedule
{{#include ../../../../ci/expected/cancel-reschedule.run}}