2020-06-11 19:18:29 +02:00
|
|
|
//! Real-Time Interrupt-driven Concurrency (RTIC) framework for ARM Cortex-M microcontrollers
|
2017-07-21 05:53:44 +02:00
|
|
|
//!
|
2019-08-21 12:19:38 +02:00
|
|
|
//! **HEADS UP** This is an **beta** pre-release; there may be breaking changes in the API and
|
2019-04-21 20:02:59 +02:00
|
|
|
//! semantics before a proper release is made.
|
|
|
|
//!
|
2020-06-11 19:18:29 +02:00
|
|
|
//! **IMPORTANT**: This crate is published as [`cortex-m-rtic`] on crates.io but the name of the
|
|
|
|
//! library is `rtic`.
|
2017-07-21 05:53:44 +02:00
|
|
|
//!
|
2020-06-11 19:18:29 +02:00
|
|
|
//! [`cortex-m-rtic`]: https://crates.io/crates/cortex-m-rtic
|
2017-07-21 05:53:44 +02:00
|
|
|
//!
|
2018-11-03 17:02:41 +01:00
|
|
|
//! The user level documentation can be found [here].
|
2017-07-21 05:53:44 +02:00
|
|
|
//!
|
2020-06-11 19:18:29 +02:00
|
|
|
//! [here]: https://rtic.rs
|
2017-07-21 05:53:44 +02:00
|
|
|
//!
|
2019-08-21 12:19:38 +02:00
|
|
|
//! Don't forget to check the documentation of the `#[app]` attribute (listed under the reexports
|
|
|
|
//! section), which is the main component of the framework.
|
2017-07-21 05:53:44 +02:00
|
|
|
//!
|
2019-02-12 11:08:39 +01:00
|
|
|
//! # Minimum Supported Rust Version (MSRV)
|
|
|
|
//!
|
2019-04-21 20:02:59 +02:00
|
|
|
//! This crate is guaranteed to compile on stable Rust 1.36 (2018 edition) and up. It *might*
|
2019-02-12 11:08:39 +01:00
|
|
|
//! compile on older versions but that may change in any new patch release.
|
|
|
|
//!
|
|
|
|
//! # Semantic Versioning
|
|
|
|
//!
|
|
|
|
//! Like the Rust project, this crate adheres to [SemVer]: breaking changes in the API and semantics
|
|
|
|
//! require a *semver bump* (a new minor version release), with the exception of breaking changes
|
|
|
|
//! that fix soundness issues -- those are considered bug fixes and can be landed in a new patch
|
|
|
|
//! release.
|
|
|
|
//!
|
|
|
|
//! [SemVer]: https://semver.org/spec/v2.0.0.html
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2017-07-21 05:53:44 +02:00
|
|
|
#![deny(missing_docs)]
|
2019-06-13 23:56:59 +02:00
|
|
|
#![deny(rust_2018_compatibility)]
|
|
|
|
#![deny(rust_2018_idioms)]
|
2017-07-21 05:53:44 +02:00
|
|
|
#![deny(warnings)]
|
2017-03-05 06:26:14 +01:00
|
|
|
#![no_std]
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
use core::ops::Sub;
|
2017-03-05 06:26:14 +01:00
|
|
|
|
2018-11-03 17:02:41 +01:00
|
|
|
use cortex_m::{
|
2018-11-04 18:50:42 +01:00
|
|
|
interrupt::Nr,
|
2018-11-03 17:02:41 +01:00
|
|
|
peripheral::{CBP, CPUID, DCB, DWT, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU},
|
|
|
|
};
|
2020-06-11 19:18:29 +02:00
|
|
|
pub use cortex_m_rtic_macros::app;
|
2020-11-14 16:09:20 +01:00
|
|
|
pub use rtic_core::{prelude as mutex_prelude, Exclusive, Mutex};
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#[cfg(armv7m)]
|
|
|
|
pub mod cyccnt;
|
2018-11-03 17:02:41 +01:00
|
|
|
#[doc(hidden)]
|
|
|
|
pub mod export;
|
2017-09-22 13:45:28 +02:00
|
|
|
#[doc(hidden)]
|
2018-11-03 17:02:41 +01:00
|
|
|
mod tq;
|
2017-09-22 13:45:28 +02:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// `cortex_m::Peripherals` minus `SYST`
|
2018-11-03 17:02:41 +01:00
|
|
|
#[allow(non_snake_case)]
|
2019-06-13 23:56:59 +02:00
|
|
|
pub struct Peripherals {
|
2018-11-03 17:02:41 +01:00
|
|
|
/// Cache and branch predictor maintenance operations (not present on Cortex-M0 variants)
|
|
|
|
pub CBP: CBP,
|
|
|
|
|
|
|
|
/// CPUID
|
|
|
|
pub CPUID: CPUID,
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Debug Control Block
|
2018-11-03 17:02:41 +01:00
|
|
|
pub DCB: DCB,
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Data Watchpoint and Trace unit
|
2018-11-03 17:02:41 +01:00
|
|
|
pub DWT: DWT,
|
2017-07-21 05:53:44 +02:00
|
|
|
|
2018-11-03 17:02:41 +01:00
|
|
|
/// Flash Patch and Breakpoint unit (not present on Cortex-M0 variants)
|
|
|
|
pub FPB: FPB,
|
2017-07-21 05:53:44 +02:00
|
|
|
|
2018-11-03 17:02:41 +01:00
|
|
|
/// Floating Point Unit (only present on `thumbv7em-none-eabihf`)
|
|
|
|
pub FPU: FPU,
|
|
|
|
|
|
|
|
/// Instrumentation Trace Macrocell (not present on Cortex-M0 variants)
|
|
|
|
pub ITM: ITM,
|
|
|
|
|
|
|
|
/// Memory Protection Unit
|
|
|
|
pub MPU: MPU,
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Nested Vector Interrupt Controller
|
|
|
|
pub NVIC: NVIC,
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// System Control Block
|
|
|
|
pub SCB: SCB,
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
// SysTick: System Timer
|
|
|
|
// pub SYST: SYST,
|
2018-11-03 17:02:41 +01:00
|
|
|
/// Trace Port Interface Unit (not present on Cortex-M0 variants)
|
|
|
|
pub TPIU: TPIU,
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
impl From<cortex_m::Peripherals> for Peripherals {
|
|
|
|
fn from(p: cortex_m::Peripherals) -> Self {
|
|
|
|
Self {
|
|
|
|
CBP: p.CBP,
|
|
|
|
CPUID: p.CPUID,
|
|
|
|
DCB: p.DCB,
|
|
|
|
DWT: p.DWT,
|
|
|
|
FPB: p.FPB,
|
|
|
|
FPU: p.FPU,
|
|
|
|
ITM: p.ITM,
|
|
|
|
MPU: p.MPU,
|
|
|
|
NVIC: p.NVIC,
|
|
|
|
SCB: p.SCB,
|
|
|
|
TPIU: p.TPIU,
|
|
|
|
}
|
2018-11-03 17:02:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-11 13:28:25 +02:00
|
|
|
/// A fraction
|
|
|
|
pub struct Fraction {
|
|
|
|
/// The numerator
|
|
|
|
pub numerator: u32,
|
|
|
|
|
|
|
|
/// The denominator
|
|
|
|
pub denominator: u32,
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// A monotonic clock / counter
|
2019-06-24 14:09:12 +02:00
|
|
|
pub trait Monotonic {
|
2019-11-13 20:56:31 +01:00
|
|
|
/// A measurement of this clock, use `CYCCNT` as a reference implementation for `Instant`.
|
|
|
|
/// Note that the Instant must be a signed value such as `i32`.
|
2019-06-13 23:56:59 +02:00
|
|
|
type Instant: Copy + Ord + Sub;
|
2017-07-27 18:37:58 +02:00
|
|
|
|
2019-11-13 20:56:31 +01:00
|
|
|
/// The ratio between the system timer (SysTick) frequency and this clock frequency, i.e.
|
|
|
|
/// `Monotonic clock * Fraction = System clock`
|
2019-07-11 13:28:25 +02:00
|
|
|
///
|
|
|
|
/// The ratio must be expressed in *reduced* `Fraction` form to prevent overflows. That is
|
|
|
|
/// `2 / 3` instead of `4 / 6`
|
|
|
|
fn ratio() -> Fraction;
|
2017-07-27 21:59:31 +02:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Returns the current time
|
2019-10-16 01:44:49 +02:00
|
|
|
///
|
|
|
|
/// # 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.
|
2019-06-13 23:56:59 +02:00
|
|
|
fn now() -> Self::Instant;
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Resets the counter to *zero*
|
2019-10-16 01:44:49 +02:00
|
|
|
///
|
|
|
|
/// # Safety
|
|
|
|
///
|
2020-06-11 19:18:29 +02:00
|
|
|
/// This function will be called *exactly once* by the RTIC runtime after `#[init]` returns and
|
2019-10-16 01:44:49 +02:00
|
|
|
/// before tasks can start; this is also the case in multi-core applications. User code must
|
|
|
|
/// *never* call this function.
|
2019-06-13 23:56:59 +02:00
|
|
|
unsafe fn reset();
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// A `Self::Instant` that represents a count of *zero*
|
|
|
|
fn zero() -> Self::Instant;
|
2017-03-10 05:59:50 +01:00
|
|
|
}
|
2017-03-05 06:26:14 +01:00
|
|
|
|
2018-11-03 17:02:41 +01:00
|
|
|
/// Sets the given `interrupt` as pending
|
2017-07-25 05:46:29 +02:00
|
|
|
///
|
2018-11-03 17:02:41 +01:00
|
|
|
/// This is a convenience function around
|
|
|
|
/// [`NVIC::pend`](../cortex_m/peripheral/struct.NVIC.html#method.pend)
|
|
|
|
pub fn pend<I>(interrupt: I)
|
2017-07-07 06:25:29 +02:00
|
|
|
where
|
|
|
|
I: Nr,
|
|
|
|
{
|
2018-11-03 17:02:41 +01:00
|
|
|
NVIC::pend(interrupt)
|
2017-07-07 06:25:29 +02:00
|
|
|
}
|