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}