rtfm_core/lib.rs
1//! Core abstractions of the Real Time For the Masses (RTFM) framework
2//!
3//! You can write generic *libraries* using the `Mutex` trait in this crate. If you want to write
4//! application code then you'll need an *implementation* of the RTFM framework for a particular
5//! architecture. Currently, there are implementations for these architectures and OSes:
6//!
7//! - [ARM Cortex-M](https://crates.io/crates/cortex-m-rtfm)
8// - [Linux]
9// - [MSP430]
10// - [RISC-V]
11
12#![deny(missing_docs)]
13#![deny(rust_2018_compatibility)]
14#![deny(rust_2018_idioms)]
15#![deny(warnings)]
16#![no_std]
17
18use core::ops;
19
20/// Memory safe access to shared resources
21///
22/// In RTFM, locks are implemented as critical sections that prevent other tasks from *starting*.
23/// These critical sections are implemented by temporarily increasing the dynamic priority of the
24/// current context. Entering and leaving these critical sections is always done in bounded constant
25/// time (a few instructions in bare metal contexts).
26pub trait Mutex {
27 /// Data protected by the mutex
28 type T;
29
30 /// Creates a critical section and grants temporary access to the protected data
31 fn lock<R>(&mut self, f: impl FnOnce(&mut Self::T) -> R) -> R;
32}
33
34impl<'a, M> Mutex for &'a mut M
35where
36 M: Mutex,
37{
38 type T = M::T;
39
40 fn lock<R>(&mut self, f: impl FnOnce(&mut M::T) -> R) -> R {
41 M::lock(self, f)
42 }
43}
44
45/// Newtype over `&'a mut T` that implements the `Mutex` trait
46///
47/// The `Mutex` implementation for this type is a no-op: no critical section is created
48pub struct Exclusive<'a, T>(pub &'a mut T);
49
50impl<'a, T> Mutex for Exclusive<'a, T> {
51 type T = T;
52
53 fn lock<R>(&mut self, f: impl FnOnce(&mut T) -> R) -> R {
54 f(self.0)
55 }
56}
57
58impl<'a, T> ops::Deref for Exclusive<'a, T> {
59 type Target = T;
60
61 fn deref(&self) -> &T {
62 self.0
63 }
64}
65
66impl<'a, T> ops::DerefMut for Exclusive<'a, T> {
67 fn deref_mut(&mut self) -> &mut T {
68 self.0
69 }
70}