rtfm/
lib.rs

1//! Real Time For the Masses (RTFM) framework for ARM Cortex-M microcontrollers
2//!
3//! **HEADS UP** This is an **beta** pre-release; there may be breaking changes in the API and
4//! semantics before a proper release is made.
5//!
6//! **IMPORTANT**: This crate is published as [`cortex-m-rtfm`] on crates.io but the name of the
7//! library is `rtfm`.
8//!
9//! [`cortex-m-rtfm`]: https://crates.io/crates/cortex-m-rtfm
10//!
11//! The user level documentation can be found [here].
12//!
13//! [here]: https://rtfm.rs
14//!
15//! Don't forget to check the documentation of the `#[app]` attribute (listed under the reexports
16//! section), which is the main component of the framework.
17//!
18//! # Minimum Supported Rust Version (MSRV)
19//!
20//! This crate is guaranteed to compile on stable Rust 1.36 (2018 edition) and up. It *might*
21//! compile on older versions but that may change in any new patch release.
22//!
23//! # Semantic Versioning
24//!
25//! Like the Rust project, this crate adheres to [SemVer]: breaking changes in the API and semantics
26//! require a *semver bump* (a new minor version release), with the exception of breaking changes
27//! that fix soundness issues -- those are considered bug fixes and can be landed in a new patch
28//! release.
29//!
30//! [SemVer]: https://semver.org/spec/v2.0.0.html
31//!
32//! # Cargo features
33//!
34//! - `heterogeneous`. This opt-in feature enables the *experimental* heterogeneous multi-core
35//! support. This feature depends on unstable feature and requires the use of the nightly channel.
36//!
37//! - `homogeneous`. This opt-in feature enables the *experimental* homogeneous multi-core support.
38
39#![deny(missing_docs)]
40#![deny(rust_2018_compatibility)]
41#![deny(rust_2018_idioms)]
42#![deny(warnings)]
43#![no_std]
44
45use core::ops::Sub;
46
47use cortex_m::{
48    interrupt::Nr,
49    peripheral::{CBP, CPUID, DCB, DWT, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU},
50};
51#[cfg(all(not(feature = "heterogeneous"), not(feature = "homogeneous")))]
52use cortex_m_rt as _; // vector table
53pub use cortex_m_rtfm_macros::app;
54pub use rtfm_core::{Exclusive, Mutex};
55
56#[cfg(armv7m)]
57pub mod cyccnt;
58#[doc(hidden)]
59pub mod export;
60#[doc(hidden)]
61mod tq;
62
63/// `cortex_m::Peripherals` minus `SYST`
64#[allow(non_snake_case)]
65pub struct Peripherals {
66    /// Cache and branch predictor maintenance operations (not present on Cortex-M0 variants)
67    pub CBP: CBP,
68
69    /// CPUID
70    pub CPUID: CPUID,
71
72    /// Debug Control Block
73    pub DCB: DCB,
74
75    /// Data Watchpoint and Trace unit
76    pub DWT: DWT,
77
78    /// Flash Patch and Breakpoint unit (not present on Cortex-M0 variants)
79    pub FPB: FPB,
80
81    /// Floating Point Unit (only present on `thumbv7em-none-eabihf`)
82    pub FPU: FPU,
83
84    /// Instrumentation Trace Macrocell (not present on Cortex-M0 variants)
85    pub ITM: ITM,
86
87    /// Memory Protection Unit
88    pub MPU: MPU,
89
90    /// Nested Vector Interrupt Controller
91    pub NVIC: NVIC,
92
93    /// System Control Block
94    pub SCB: SCB,
95
96    // SysTick: System Timer
97    // pub SYST: SYST,
98    /// Trace Port Interface Unit (not present on Cortex-M0 variants)
99    pub TPIU: TPIU,
100}
101
102impl From<cortex_m::Peripherals> for Peripherals {
103    fn from(p: cortex_m::Peripherals) -> Self {
104        Self {
105            CBP: p.CBP,
106            CPUID: p.CPUID,
107            DCB: p.DCB,
108            DWT: p.DWT,
109            FPB: p.FPB,
110            FPU: p.FPU,
111            ITM: p.ITM,
112            MPU: p.MPU,
113            NVIC: p.NVIC,
114            SCB: p.SCB,
115            TPIU: p.TPIU,
116        }
117    }
118}
119
120/// A fraction
121pub struct Fraction {
122    /// The numerator
123    pub numerator: u32,
124
125    /// The denominator
126    pub denominator: u32,
127}
128
129/// A monotonic clock / counter
130pub trait Monotonic {
131    /// A measurement of this clock, use `CYCCNT` as a reference implementation for `Instant`.
132    /// Note that the Instant must be a signed value such as `i32`.
133    type Instant: Copy + Ord + Sub;
134
135    /// The ratio between the system timer (SysTick) frequency and this clock frequency, i.e.
136    /// `Monotonic clock * Fraction = System clock`
137    ///
138    /// The ratio must be expressed in *reduced* `Fraction` form to prevent overflows. That is
139    /// `2 / 3` instead of `4 / 6`
140    fn ratio() -> Fraction;
141
142    /// Returns the current time
143    ///
144    /// # Correctness
145    ///
146    /// This function is *allowed* to return nonsensical values if called before `reset` is invoked
147    /// by the runtime. Therefore application authors should *not* call this function during the
148    /// `#[init]` phase.
149    fn now() -> Self::Instant;
150
151    /// Resets the counter to *zero*
152    ///
153    /// # Safety
154    ///
155    /// This function will be called *exactly once* by the RTFM runtime after `#[init]` returns and
156    /// before tasks can start; this is also the case in multi-core applications. User code must
157    /// *never* call this function.
158    unsafe fn reset();
159
160    /// A `Self::Instant` that represents a count of *zero*
161    fn zero() -> Self::Instant;
162}
163
164/// A marker trait that indicates that it is correct to use this type in multi-core context
165pub trait MultiCore {}
166
167/// Sets the given `interrupt` as pending
168///
169/// This is a convenience function around
170/// [`NVIC::pend`](../cortex_m/peripheral/struct.NVIC.html#method.pend)
171pub fn pend<I>(interrupt: I)
172where
173    I: Nr,
174{
175    NVIC::pend(interrupt)
176}