732: Docs 1 r=korken89 a=datdenkikniet

Going over all of the subprojects and trying to find stuff that may need docs

Co-authored-by: datdenkikniet <jcdra1@gmail.com>
This commit is contained in:
bors[bot] 2023-04-16 12:05:20 +00:00 committed by GitHub
commit 56bf829931
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 207 additions and 106 deletions

View file

@ -1,4 +1,4 @@
//! Crate //! Utility structs that can be useful to other subcrates.
#![no_std] #![no_std]
#![deny(missing_docs)] #![deny(missing_docs)]

View file

@ -1,4 +1,4 @@
//! ... //! A wait queue implementation using a doubly linked list.
use core::marker::PhantomPinned; use core::marker::PhantomPinned;
use core::pin::Pin; use core::pin::Pin;
@ -8,15 +8,18 @@ use core::task::Waker;
use critical_section as cs; use critical_section as cs;
/// A helper definition of a wait queue. /// A helper definition of a wait queue.
pub type WaitQueue = LinkedList<Waker>; pub type WaitQueue = DoublyLinkedList<Waker>;
/// A FIFO linked list for a wait queue. /// An atomic, doubly linked, FIFO list for a wait queue.
pub struct LinkedList<T> { ///
/// Atomicity is guaranteed by short [`critical_section`]s, so this list is _not_ lock free,
/// but it will not deadlock.
pub struct DoublyLinkedList<T> {
head: AtomicPtr<Link<T>>, // UnsafeCell<*mut Link<T>> head: AtomicPtr<Link<T>>, // UnsafeCell<*mut Link<T>>
tail: AtomicPtr<Link<T>>, tail: AtomicPtr<Link<T>>,
} }
impl<T> LinkedList<T> { impl<T> DoublyLinkedList<T> {
/// Create a new linked list. /// Create a new linked list.
pub const fn new() -> Self { pub const fn new() -> Self {
Self { Self {
@ -26,7 +29,7 @@ impl<T> LinkedList<T> {
} }
} }
impl<T: Clone> LinkedList<T> { impl<T: Clone> DoublyLinkedList<T> {
const R: Ordering = Ordering::Relaxed; const R: Ordering = Ordering::Relaxed;
/// Pop the first element in the queue. /// Pop the first element in the queue.
@ -130,7 +133,7 @@ impl<T: Clone> Link<T> {
} }
/// Remove this link from a linked list. /// Remove this link from a linked list.
pub fn remove_from_list(&self, list: &LinkedList<T>) { pub fn remove_from_list(&self, list: &DoublyLinkedList<T>) {
cs::with(|_| { cs::with(|_| {
// Make sure all previous writes are visible // Make sure all previous writes are visible
core::sync::atomic::fence(Ordering::SeqCst); core::sync::atomic::fence(Ordering::SeqCst);
@ -172,7 +175,7 @@ impl<T: Clone> Link<T> {
} }
#[cfg(test)] #[cfg(test)]
impl<T: core::fmt::Debug + Clone> LinkedList<T> { impl<T: core::fmt::Debug + Clone> DoublyLinkedList<T> {
fn print(&self) { fn print(&self) {
cs::with(|_| { cs::with(|_| {
// Make sure all previous writes are visible // Make sure all previous writes are visible
@ -232,7 +235,7 @@ mod tests {
#[test] #[test]
fn linked_list() { fn linked_list() {
let wq = LinkedList::<u32>::new(); let wq = DoublyLinkedList::<u32>::new();
let i1 = Link::new(10); let i1 = Link::new(10);
let i2 = Link::new(11); let i2 = Link::new(11);

View file

@ -1,10 +1,3 @@
#[cfg(not(any(
feature = "cortex-m-source-masking",
feature = "cortex-m-basepri",
feature = "test-template"
)))]
compile_error!("No backend selected");
#[cfg(any(feature = "cortex-m-source-masking", feature = "cortex-m-basepri"))] #[cfg(any(feature = "cortex-m-source-masking", feature = "cortex-m-basepri"))]
pub use cortex::*; pub use cortex::*;

View file

@ -43,6 +43,6 @@ pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStrea
vec![] vec![]
} }
pub fn async_prio_limit(app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> { pub fn async_prio_limit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![] vec![]
} }

View file

@ -4,87 +4,110 @@
)] )]
//deny_warnings_placeholder_for_ci //deny_warnings_placeholder_for_ci
use proc_macro::TokenStream; macro_rules! with_backend {
use std::{env, fs, path::Path}; (mod: [$($mod:tt),*]) => {
$(
with_backend!{ mod $mod; }
)*
};
($($tokens:tt)*) => {
#[cfg(any(
feature = "cortex-m-source-masking",
feature = "cortex-m-basepri",
feature = "test-template"
))]
$($tokens)*
};
}
mod analyze; with_backend! { mod: [analyze, check, codegen, syntax] }
mod check; with_backend! { use std::{fs, env, path::Path}; }
mod codegen; with_backend! { use proc_macro::TokenStream; }
mod syntax;
// Used for mocking the API in testing with_backend! {
#[doc(hidden)] // Used for mocking the API in testing
#[proc_macro_attribute] #[doc(hidden)]
pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute]
if let Err(e) = syntax::parse(args, input) { pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream {
e.to_compile_error().into() if let Err(e) = syntax::parse(args, input) {
} else { e.to_compile_error().into()
"fn main() {}".parse().unwrap() } else {
"fn main() {}".parse().unwrap()
}
} }
} }
/// Attribute used to declare a RTIC application with_backend! {
/// /// Attribute used to declare a RTIC application
/// For user documentation see the [RTIC book](https://rtic.rs) ///
/// /// For user documentation see the [RTIC book](https://rtic.rs)
/// # Panics ///
/// /// # Panics
/// Should never panic, cargo feeds a path which is later converted to a string ///
#[proc_macro_attribute] /// Should never panic, cargo feeds a path which is later converted to a string
pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { #[proc_macro_attribute]
let (app, analysis) = match syntax::parse(args, input) { pub fn app(_args: TokenStream, _input: TokenStream) -> TokenStream {
Err(e) => return e.to_compile_error().into(), let (app, analysis) = match syntax::parse(_args, _input) {
Ok(x) => x, Err(e) => return e.to_compile_error().into(),
}; Ok(x) => x,
};
if let Err(e) = check::app(&app, &analysis) { if let Err(e) = check::app(&app, &analysis) {
return e.to_compile_error().into(); return e.to_compile_error().into();
} }
let analysis = analyze::app(analysis, &app); let analysis = analyze::app(analysis, &app);
let ts = codegen::app(&app, &analysis); let ts = codegen::app(&app, &analysis);
// Default output path: <project_dir>/target/ // Default output path: <project_dir>/target/
let mut out_dir = Path::new("target"); let mut out_dir = Path::new("target");
// Get output directory from Cargo environment // Get output directory from Cargo environment
// TODO don't want to break builds if OUT_DIR is not set, is this ever the case? // TODO don't want to break builds if OUT_DIR is not set, is this ever the case?
let out_str = env::var("OUT_DIR").unwrap_or_else(|_| "".to_string()); let out_str = env::var("OUT_DIR").unwrap_or_else(|_| "".to_string());
if !out_dir.exists() { if !out_dir.exists() {
// Set out_dir to OUT_DIR // Set out_dir to OUT_DIR
out_dir = Path::new(&out_str); out_dir = Path::new(&out_str);
// Default build path, annotated below: // Default build path, annotated below:
// $(pwd)/target/thumbv7em-none-eabihf/debug/build/rtic-<HASH>/out/ // $(pwd)/target/thumbv7em-none-eabihf/debug/build/rtic-<HASH>/out/
// <project_dir>/<target-dir>/<TARGET>/debug/build/rtic-<HASH>/out/ // <project_dir>/<target-dir>/<TARGET>/debug/build/rtic-<HASH>/out/
// //
// traverse up to first occurrence of TARGET, approximated with starts_with("thumbv") // traverse up to first occurrence of TARGET, approximated with starts_with("thumbv")
// and use the parent() of this path // and use the parent() of this path
// //
// If no "target" directory is found, <project_dir>/<out_dir_root> is used // If no "target" directory is found, <project_dir>/<out_dir_root> is used
for path in out_dir.ancestors() { for path in out_dir.ancestors() {
if let Some(dir) = path.components().last() { if let Some(dir) = path.components().last() {
let dir = dir.as_os_str().to_str().unwrap(); let dir = dir.as_os_str().to_str().unwrap();
if dir.starts_with("thumbv") || dir.starts_with("riscv") { if dir.starts_with("thumbv") || dir.starts_with("riscv") {
if let Some(out) = path.parent() { if let Some(out) = path.parent() {
out_dir = out; out_dir = out;
break;
}
// If no parent, just use it
out_dir = path;
break; break;
} }
// If no parent, just use it
out_dir = path;
break;
} }
} }
} }
}
// Try to write the expanded code to disk // Try to write the expanded code to disk
if let Some(out_str) = out_dir.to_str() { if let Some(out_str) = out_dir.to_str() {
fs::write(format!("{out_str}/rtic-expansion.rs"), ts.to_string()).ok(); fs::write(format!("{out_str}/rtic-expansion.rs"), ts.to_string()).ok();
} }
ts.into() ts.into()
}
} }
#[cfg(not(any(
feature = "cortex-m-source-masking",
feature = "cortex-m-basepri",
feature = "test-template"
)))]
compile_error!("Cannot compile. No backend feature selected.");

View file

@ -11,10 +11,12 @@ authors = [
"Per Lindgren <per.lindgren@ltu.se>", "Per Lindgren <per.lindgren@ltu.se>",
] ]
categories = ["concurrency", "embedded", "no-std", "asynchronous"] categories = ["concurrency", "embedded", "no-std", "asynchronous"]
description = "rtic-monotonics lib TODO" description = "A library that provides implementations of the Monotonic trait from rtic-time"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [package.metadata.docs.rs]
features = ["cortex-m-systick", "rp2040", "nrf52840"]
rustdoc-flags = ["--cfg", "docsrs"]
[dependencies] [dependencies]
rtic-time = { version = "1.0.0-alpha.1", path = "../rtic-time" } rtic-time = { version = "1.0.0-alpha.1", path = "../rtic-time" }

View file

@ -1,10 +1,31 @@
//! Crate //! In-tree implementations of the [`rtic_time::Monotonic`] (reexported) trait for
//! timers & clocks found on commonly used microcontrollers.
//!
//! To enable the implementations, you must enable a feature for the specific MCU you're targeting.
//!
//! # Cortex-M Systick
//! The [`systick`] monotonic works on all cortex-M parts, and requires that the feature `cortex-m-systick` is enabled.
//!
//! # RP2040
//! The RP2040 monotonics require that the `rp2040` feature is enabled.
//!
//! # nRF
//! nRF monotonics require that one of the available `nrf52*` features is enabled.
//!
//! All implementations of timers for the nRF52 family are documented here. Monotonics that
//! are not available on all parts in this family will have an `Available on crate features X only`
//! tag, describing what parts _do_ support that monotonic. Monotonics without an
//! `Available on crate features X only` tag are available on any `nrf52*` feature.
//!
// To build these docs correctly:
// RUSTFLAGS="--cfg docsrs" cargo doc --featuers cortex-m-systick,rp2040,nrf52840
#![no_std] #![no_std]
#![deny(missing_docs)] #![deny(missing_docs)]
//deny_warnings_placeholder_for_ci //deny_warnings_placeholder_for_ci
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![feature(async_fn_in_trait)] #![feature(async_fn_in_trait)]
#![cfg_attr(docsrs, feature(doc_cfg))]
pub use rtic_time::{Monotonic, TimeoutError, TimerQueue}; pub use rtic_time::{Monotonic, TimeoutError, TimerQueue};

View file

@ -1,4 +1,4 @@
//! Monotonic implementations for the nRF series of MCUs. //! [`Monotonic`](super::Monotonic) implementations for the nRF series of MCUs.
pub mod rtc; pub mod rtc;
pub mod timer; pub mod timer;

View file

@ -1,4 +1,4 @@
//! RTIC Monotonic impl for the nRF RTCs. //! [`Monotonic`] implementation for the nRF Real Time Clocks (RTC).
//! //!
//! # Example //! # Example
//! //!
@ -82,6 +82,10 @@ macro_rules! create_nrf_rtc1_monotonic_token {
/// Register the Rtc2 interrupt for the monotonic. /// Register the Rtc2 interrupt for the monotonic.
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")))
)]
#[macro_export] #[macro_export]
macro_rules! create_nrf_rtc2_monotonic_token { macro_rules! create_nrf_rtc2_monotonic_token {
() => {{ () => {{
@ -90,8 +94,11 @@ macro_rules! create_nrf_rtc2_monotonic_token {
} }
macro_rules! make_rtc { macro_rules! make_rtc {
($mono_name:ident, $rtc:ident, $overflow:ident, $tq:ident) => { ($mono_name:ident, $rtc:ident, $overflow:ident, $tq:ident$(, doc: ($($doc:tt)*))?) => {
/// Monotonic timer queue implementation. /// Monotonic timer queue implementation.
$(
#[cfg_attr(docsrs, doc(cfg($($doc)*)))]
)?
pub struct $mono_name; pub struct $mono_name;
static $overflow: AtomicU32 = AtomicU32::new(0); static $overflow: AtomicU32 = AtomicU32::new(0);
@ -243,4 +250,4 @@ macro_rules! make_rtc {
make_rtc!(Rtc0, RTC0, RTC0_OVERFLOWS, RTC0_TQ); make_rtc!(Rtc0, RTC0, RTC0_OVERFLOWS, RTC0_TQ);
make_rtc!(Rtc1, RTC1, RTC1_OVERFLOWS, RTC1_TQ); make_rtc!(Rtc1, RTC1, RTC1_OVERFLOWS, RTC1_TQ);
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
make_rtc!(Rtc2, RTC2, RTC2_OVERFLOWS, RTC2_TQ); make_rtc!(Rtc2, RTC2, RTC2_OVERFLOWS, RTC2_TQ, doc: (any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")));

View file

@ -1,4 +1,7 @@
//! Monotonic impl for the 32-bit timers of the nRF series. //! [`Monotonic`] impl for the 32-bit timers of the nRF series.
//!
//! Not all timers are available on all parts. Ensure that only the available
//! timers are exposed by having the correct `nrf52*` feature enabled for `rtic-monotonic`.
//! //!
//! # Example //! # Example
//! //!
@ -95,6 +98,10 @@ macro_rules! create_nrf_timer2_monotonic_token {
} }
/// Register the Timer3 interrupt for the monotonic. /// Register the Timer3 interrupt for the monotonic.
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")))
)]
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
#[macro_export] #[macro_export]
macro_rules! create_nrf_timer3_monotonic_token { macro_rules! create_nrf_timer3_monotonic_token {
@ -104,6 +111,10 @@ macro_rules! create_nrf_timer3_monotonic_token {
} }
/// Register the Timer4 interrupt for the monotonic. /// Register the Timer4 interrupt for the monotonic.
#[cfg_attr(
docsrs,
doc(cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")))
)]
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
#[macro_export] #[macro_export]
macro_rules! create_nrf_timer4_monotonic_token { macro_rules! create_nrf_timer4_monotonic_token {
@ -113,8 +124,11 @@ macro_rules! create_nrf_timer4_monotonic_token {
} }
macro_rules! make_timer { macro_rules! make_timer {
($mono_name:ident, $timer:ident, $overflow:ident, $tq:ident) => { ($mono_name:ident, $timer:ident, $overflow:ident, $tq:ident$(, doc: ($($doc:tt)*))?) => {
/// Monotonic timer queue implementation. /// Monotonic timer queue implementation.
$(
#[cfg_attr(docsrs, doc(cfg($($doc)*)))]
)?
pub struct $mono_name; pub struct $mono_name;
static $overflow: AtomicU32 = AtomicU32::new(0); static $overflow: AtomicU32 = AtomicU32::new(0);
@ -274,6 +288,6 @@ make_timer!(Timer0, TIMER0, TIMER0_OVERFLOWS, TIMER0_TQ);
make_timer!(Timer1, TIMER1, TIMER1_OVERFLOWS, TIMER1_TQ); make_timer!(Timer1, TIMER1, TIMER1_OVERFLOWS, TIMER1_TQ);
make_timer!(Timer2, TIMER2, TIMER2_OVERFLOWS, TIMER2_TQ); make_timer!(Timer2, TIMER2, TIMER2_OVERFLOWS, TIMER2_TQ);
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
make_timer!(Timer3, TIMER3, TIMER3_OVERFLOWS, TIMER3_TQ); make_timer!(Timer3, TIMER3, TIMER3_OVERFLOWS, TIMER3_TQ, doc: (any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")));
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
make_timer!(Timer4, TIMER4, TIMER4_OVERFLOWS, TIMER4_TQ); make_timer!(Timer4, TIMER4, TIMER4_OVERFLOWS, TIMER4_TQ, doc: (any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")));

View file

@ -1,4 +1,4 @@
//! A monotonic implementation for RP2040's Timer peripheral. //! [`Monotonic`] implementation for RP2040's Timer peripheral.
//! //!
//! # Example //! # Example
//! //!

View file

@ -1,6 +1,14 @@
//! A monotonics based on Cortex-M SysTick. Note that this implementation is inefficient as it //! [`Monotonic`] based on Cortex-M SysTick. Note: this implementation is inefficient as it
//! ticks, and generates interrupts, at a constant rate. //! ticks and generates interrupts at a constant rate.
//! //!
//! Currently, the following tick rates are supported:
//!
//! | Feature | Tick rate | Precision |
//! |:----------------:|----------:|----------:|
//! | (none / default) | 1 Hz | 1 ms |
//! | systick-100hz | 100 Hz | 10 ms |
//! | systick-10khz | 10 KHz | 0.1 ms |
//! # Example //! # Example
//! //!
//! ``` //! ```

View file

@ -1,4 +1,27 @@
//! Crate //! A Mutex-like FIFO with unlimited-waiter for embedded systems.
//!
//! Example usage:
//!
//! ```rust
//! # async fn select<F1, F2>(f1: F1, f2: F2) {}
//! use rtic_sync::arbiter::Arbiter;
//!
//! // Instantiate an Arbiter with a static lifetime.
//! static ARBITER: Arbiter<u32> = Arbiter::new(32);
//!
//! async fn run(){
//! let write_42 = async move {
//! *ARBITER.access().await = 42;
//! };
//!
//! let write_1337 = async move {
//! *ARBITER.access().await = 1337;
//! };
//!
//! // Attempt to access the Arbiter concurrently.
//! select(write_42, write_1337).await;
//! }
//! ```
use core::cell::UnsafeCell; use core::cell::UnsafeCell;
use core::future::poll_fn; use core::future::poll_fn;
@ -45,7 +68,7 @@ impl<T> Arbiter<T> {
} }
} }
/// Get access to the inner value in the `Arbiter`. This will wait until access is granted, /// Get access to the inner value in the [`Arbiter`]. This will wait until access is granted,
/// for non-blocking access use `try_access`. /// for non-blocking access use `try_access`.
pub async fn access(&self) -> ExclusiveAccess<'_, T> { pub async fn access(&self) -> ExclusiveAccess<'_, T> {
let mut link_ptr: Option<Link<Waker>> = None; let mut link_ptr: Option<Link<Waker>> = None;
@ -132,7 +155,7 @@ impl<T> Arbiter<T> {
} }
} }
/// This token represents exclusive access to the value protected by the `Arbiter`. /// This token represents exclusive access to the value protected by the [`Arbiter`].
pub struct ExclusiveAccess<'a, T> { pub struct ExclusiveAccess<'a, T> {
arbiter: &'a Arbiter<T>, arbiter: &'a Arbiter<T>,
inner: &'a mut T, inner: &'a mut T,

View file

@ -1,4 +1,4 @@
//! Crate //! An async aware MPSC channel that can be used on no-alloc systems.
use core::{ use core::{
cell::UnsafeCell, cell::UnsafeCell,

View file

@ -1,4 +1,7 @@
//! Crate //! Time-related traits & structs.
//!
//! This crate contains basic definitions and utilities that can be used
//! to keep track of time.
#![no_std] #![no_std]
#![deny(missing_docs)] #![deny(missing_docs)]

View file

@ -1,11 +1,12 @@
//! ...
use core::marker::PhantomPinned; use core::marker::PhantomPinned;
use core::pin::Pin; use core::pin::Pin;
use core::sync::atomic::{AtomicPtr, Ordering}; use core::sync::atomic::{AtomicPtr, Ordering};
use critical_section as cs; use critical_section as cs;
/// A sorted linked list for the timer queue. /// An atomic sorted linked list for the timer queue.
///
/// Atomicity is guaranteed using very short [`critical_section`]s, so this list is _not_
/// lock free, but it will not deadlock.
pub(crate) struct LinkedList<T> { pub(crate) struct LinkedList<T> {
head: AtomicPtr<Link<T>>, head: AtomicPtr<Link<T>>,
} }

View file

@ -1,4 +1,4 @@
//! ... //! A monotonic clock / counter definition.
/// # A monotonic clock / counter definition. /// # A monotonic clock / counter definition.
/// ///

View file

@ -24,6 +24,9 @@ repository = "https://github.com/rtic-rs/rtic"
version = "2.0.0-alpha.1" version = "2.0.0-alpha.1"
[package.metadata.docs.rs]
features = ["rtic-macros/test-template"]
[lib] [lib]
name = "rtic" name = "rtic"

View file

@ -9,8 +9,8 @@
//! //!
//! # Minimum Supported Rust Version (MSRV) //! # Minimum Supported Rust Version (MSRV)
//! //!
//! This crate is compiled and tested with the latest toolchain (rolling) as of the release date. //! This crate is compiled and tested with the latest nightly toolchain (rolling).
//! If you run into compilation errors, try the latest stable release of the rust toolchain. //! If you run into compilation errors, try the latest nightly release of the rust toolchain.
//! //!
//! # Semantic Versioning //! # Semantic Versioning
//! //!