mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-24 02:49:34 +01:00
more monotonic timer docs
covers - initialization and configuration of the timer; this is now a responsibility of the application author - correctness of `Monotonic::now()` in `#[init]` - safety of `Monotonic::reset()` closes #251
This commit is contained in:
parent
6196984d6d
commit
eef4e7bf79
6 changed files with 33 additions and 5 deletions
|
@ -5,7 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## v0.5.0 - 2019-09-?? (currently in beta pre-release)
|
||||
## v0.5.0 - 2019-??-?? (currently in beta pre-release)
|
||||
|
||||
### Added
|
||||
|
||||
|
@ -45,7 +45,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
Cargo features are enabled.
|
||||
|
||||
- [breaking-change][] the monotonic timer used to implement the `schedule` API
|
||||
is now user configurable via the `#[app(monotonic = ..)]` argument.
|
||||
is now user configurable via the `#[app(monotonic = ..)]` argument. IMPORTANT:
|
||||
it is now the responsibility of the application author to configure and
|
||||
initialize the chosen `monotonic` timer during the `#[init]` phase.
|
||||
|
||||
- [breaking-change][] the `peripherals` field is not include in `init::Context`
|
||||
by default. One must opt-in using the `#[app(peripherals = ..)]` argument.
|
||||
|
|
|
@ -34,6 +34,10 @@ first appear in the `schedule` argument of the context attribute. When
|
|||
scheduling a task the (user-defined) `Instant` at which the task should be
|
||||
executed must be passed as the first argument of the `schedule` invocation.
|
||||
|
||||
Additionally, the chosen `monotonic` timer must be configured and initialized
|
||||
during the `#[init]** phase. Note that this is *also* the case if you choose to
|
||||
use the `CYCCNT` provided by the `cortex-m-rtfm` crate.
|
||||
|
||||
The example below schedules two tasks from `init`: `foo` and `bar`. `foo` is
|
||||
scheduled to run 8 million clock cycles in the future. Next, `bar` is scheduled
|
||||
to run 4 million clock cycles in the future. Thus `bar` runs before `foo` since
|
||||
|
|
|
@ -14,6 +14,8 @@ use panic_semihosting as _;
|
|||
const APP: () = {
|
||||
#[init(spawn = [foo])]
|
||||
fn init(cx: init::Context) {
|
||||
// omitted: initialization of `CYCCNT`
|
||||
|
||||
hprintln!("init(baseline = {:?})", cx.start).unwrap();
|
||||
|
||||
// `foo` inherits the baseline of `init`: `Instant(0)`
|
||||
|
|
|
@ -16,6 +16,8 @@ const PERIOD: u32 = 8_000_000;
|
|||
const APP: () = {
|
||||
#[init(schedule = [foo])]
|
||||
fn init(cx: init::Context) {
|
||||
// omitted: initialization of `CYCCNT`
|
||||
|
||||
cx.schedule.foo(Instant::now() + PERIOD.cycles()).unwrap();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! examples/schedule.rs
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![deny(warnings)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
@ -13,8 +12,15 @@ use rtfm::cyccnt::{Instant, U32Ext as _};
|
|||
#[rtfm::app(device = lm3s6965, monotonic = rtfm::cyccnt::CYCCNT)]
|
||||
const APP: () = {
|
||||
#[init(schedule = [foo, bar])]
|
||||
fn init(cx: init::Context) {
|
||||
let now = Instant::now();
|
||||
fn init(mut cx: init::Context) {
|
||||
// Initialize (enable) the monotonic timer (CYCCNT)
|
||||
cx.core.DCB.enable_trace();
|
||||
// required on devices that software lock the DWT (e.g. STM32F7)
|
||||
unsafe { cx.core.DWT.lar.write(0xC5ACCE55) }
|
||||
cx.core.DWT.enable_cycle_counter();
|
||||
|
||||
// semantically, the monotonic timer is frozen at time "zero" during `init`
|
||||
let now = cx.start; // the start time of the system
|
||||
|
||||
hprintln!("init @ {:?}", now).unwrap();
|
||||
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -138,9 +138,21 @@ pub trait Monotonic {
|
|||
fn ratio() -> Fraction;
|
||||
|
||||
/// Returns the current time
|
||||
///
|
||||
/// # Correctness
|
||||
///
|
||||
/// This function is *allowed* to return nonsensical values if called before `reset` is invoked
|
||||
/// by the runtime. Therefore application authors should *not* call this function during the
|
||||
/// `#[init]` phase.
|
||||
fn now() -> Self::Instant;
|
||||
|
||||
/// Resets the counter to *zero*
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function will be called *exactly once* by the RTFM runtime after `#[init]` returns and
|
||||
/// before tasks can start; this is also the case in multi-core applications. User code must
|
||||
/// *never* call this function.
|
||||
unsafe fn reset();
|
||||
|
||||
/// A `Self::Instant` that represents a count of *zero*
|
||||
|
|
Loading…
Reference in a new issue