Skip to content

Make Peripherals non-exhaustive and improve its docs #193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 1, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 27 additions & 35 deletions src/peripheral/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![allow(clippy::needless_doctest_main)]
//! Core peripherals
//! Core peripherals.
//!
//! # API
//!
Expand All @@ -9,59 +8,47 @@
//! the [`Peripherals::take`](struct.Peripherals.html#method.take) method.
//!
//! ``` no_run
//! use cortex_m::peripheral::Peripherals;
//!
//! fn main() {
//! let mut peripherals = Peripherals::take().unwrap();
//! peripherals.DWT.enable_cycle_counter();
//! }
//! # use cortex_m::peripheral::Peripherals;
//! let mut peripherals = Peripherals::take().unwrap();
//! peripherals.DWT.enable_cycle_counter();
//! ```
//!
//! This method can only be successfully called *once* -- this is why the method returns an
//! `Option`. Subsequent calls to the method will result in a `None` value being returned.
//!
//! ``` no_run
//! use cortex_m::peripheral::Peripherals;
//!
//! fn main() {
//! let ok = Peripherals::take().unwrap();
//! let panics = Peripherals::take().unwrap();
//! }
//! ``` no_run, should_panic
//! # use cortex_m::peripheral::Peripherals;
//! let ok = Peripherals::take().unwrap();
//! let panics = Peripherals::take().unwrap();
//! ```
//! A part of the peripheral API doesn't require access to a peripheral instance. This part of the
//! API is provided as static methods on the peripheral types. One example is the
//! [`DWT::get_cycle_count`](struct.DWT.html#method.get_cycle_count) method.
//!
//! ``` no_run
//! use cortex_m::peripheral::{DWT, Peripherals};
//!
//! fn main() {
//! {
//! let mut peripherals = Peripherals::take().unwrap();
//! peripherals.DWT.enable_cycle_counter();
//! } // all the peripheral singletons are destroyed here
//! # use cortex_m::peripheral::{DWT, Peripherals};
//! {
//! let mut peripherals = Peripherals::take().unwrap();
//! peripherals.DWT.enable_cycle_counter();
//! } // all the peripheral singletons are destroyed here
//!
//! // but this method can be called without a DWT instance
//! let cyccnt = DWT::get_cycle_count();
//! }
//! // but this method can be called without a DWT instance
//! let cyccnt = DWT::get_cycle_count();
//! ```
//!
//! The singleton property can be *unsafely* bypassed using the `ptr` static method which is
//! available on all the peripheral types. This method is a useful building block for implementing
//! safe higher level abstractions.
//!
//! ``` no_run
//! use cortex_m::peripheral::{DWT, Peripherals};
//!
//! fn main() {
//! {
//! let mut peripherals = Peripherals::take().unwrap();
//! peripherals.DWT.enable_cycle_counter();
//! } // all the peripheral singletons are destroyed here
//! # use cortex_m::peripheral::{DWT, Peripherals};
//! {
//! let mut peripherals = Peripherals::take().unwrap();
//! peripherals.DWT.enable_cycle_counter();
//! } // all the peripheral singletons are destroyed here
//!
//! // actually safe because this is an atomic read with no side effects
//! let cyccnt = unsafe { (*DWT::ptr()).cyccnt.read() };
//! }
//! // actually safe because this is an atomic read with no side effects
//! let cyccnt = unsafe { (*DWT::ptr()).cyccnt.read() };
//! ```
//!
//! # References
Expand Down Expand Up @@ -138,6 +125,10 @@ pub struct Peripherals {

/// Trace Port Interface Unit (not present on Cortex-M0 variants)
pub TPIU: TPIU,

// Private field making `Peripherals` non-exhaustive. We don't use `#[non_exhaustive]` so we
// can support older Rust versions.
_priv: (),
}

// NOTE `no_mangle` is used here to prevent linking different minor versions of this crate as that
Expand Down Expand Up @@ -200,6 +191,7 @@ impl Peripherals {
TPIU: TPIU {
_marker: PhantomData,
},
_priv: (),
}
}
}
Expand Down