aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rtic-common/src/lib.rs2
-rw-r--r--rtic-common/src/wait_queue.rs21
-rw-r--r--rtic-macros/src/codegen/bindings.rs7
-rw-r--r--rtic-macros/src/codegen/bindings/template.rs2
-rw-r--r--rtic-macros/src/lib.rs149
-rw-r--r--rtic-monotonics/Cargo.toml6
-rw-r--r--rtic-monotonics/src/lib.rs23
-rw-r--r--rtic-monotonics/src/nrf.rs2
-rw-r--r--rtic-monotonics/src/nrf/rtc.rs13
-rw-r--r--rtic-monotonics/src/nrf/timer.rs22
-rw-r--r--rtic-monotonics/src/rp2040.rs2
-rw-r--r--rtic-monotonics/src/systick.rs12
-rw-r--r--rtic-sync/src/arbiter.rs29
-rw-r--r--rtic-sync/src/channel.rs2
-rw-r--r--rtic-time/src/lib.rs5
-rw-r--r--rtic-time/src/linked_list.rs7
-rw-r--r--rtic-time/src/monotonic.rs2
-rw-r--r--rtic/Cargo.toml3
-rw-r--r--rtic/src/lib.rs4
19 files changed, 207 insertions, 106 deletions
diff --git a/rtic-common/src/lib.rs b/rtic-common/src/lib.rs
index e8f5af7..93c8187 100644
--- a/rtic-common/src/lib.rs
+++ b/rtic-common/src/lib.rs
@@ -1,4 +1,4 @@
-//! Crate
+//! Utility structs that can be useful to other subcrates.
#![no_std]
#![deny(missing_docs)]
diff --git a/rtic-common/src/wait_queue.rs b/rtic-common/src/wait_queue.rs
index b1aa775..4b1b0f3 100644
--- a/rtic-common/src/wait_queue.rs
+++ b/rtic-common/src/wait_queue.rs
@@ -1,4 +1,4 @@
-//! ...
+//! A wait queue implementation using a doubly linked list.
use core::marker::PhantomPinned;
use core::pin::Pin;
@@ -8,15 +8,18 @@ use core::task::Waker;
use critical_section as cs;
/// 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.
-pub struct LinkedList<T> {
+/// An atomic, doubly linked, FIFO list for a wait queue.
+///
+/// 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>>
tail: AtomicPtr<Link<T>>,
}
-impl<T> LinkedList<T> {
+impl<T> DoublyLinkedList<T> {
/// Create a new linked list.
pub const fn new() -> 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;
/// Pop the first element in the queue.
@@ -130,7 +133,7 @@ impl<T: Clone> Link<T> {
}
/// 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(|_| {
// Make sure all previous writes are visible
core::sync::atomic::fence(Ordering::SeqCst);
@@ -172,7 +175,7 @@ impl<T: Clone> Link<T> {
}
#[cfg(test)]
-impl<T: core::fmt::Debug + Clone> LinkedList<T> {
+impl<T: core::fmt::Debug + Clone> DoublyLinkedList<T> {
fn print(&self) {
cs::with(|_| {
// Make sure all previous writes are visible
@@ -232,7 +235,7 @@ mod tests {
#[test]
fn linked_list() {
- let wq = LinkedList::<u32>::new();
+ let wq = DoublyLinkedList::<u32>::new();
let i1 = Link::new(10);
let i2 = Link::new(11);
diff --git a/rtic-macros/src/codegen/bindings.rs b/rtic-macros/src/codegen/bindings.rs
index 6c214cd..c328ee0 100644
--- a/rtic-macros/src/codegen/bindings.rs
+++ b/rtic-macros/src/codegen/bindings.rs
@@ -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"))]
pub use cortex::*;
diff --git a/rtic-macros/src/codegen/bindings/template.rs b/rtic-macros/src/codegen/bindings/template.rs
index a33bae8..690dfb0 100644
--- a/rtic-macros/src/codegen/bindings/template.rs
+++ b/rtic-macros/src/codegen/bindings/template.rs
@@ -43,6 +43,6 @@ pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStrea
vec![]
}
-pub fn async_prio_limit(app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+pub fn async_prio_limit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![]
}
diff --git a/rtic-macros/src/lib.rs b/rtic-macros/src/lib.rs
index e0043d9..de67e3d 100644
--- a/rtic-macros/src/lib.rs
+++ b/rtic-macros/src/lib.rs
@@ -3,87 +3,110 @@
html_favicon_url = "https://raw.githubusercontent.com/rtic-rs/rtic/master/book/en/src/RTIC.svg"
)]
-use proc_macro::TokenStream;
-use std::{env, fs, path::Path};
+macro_rules! with_backend {
+ (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;
-mod check;
-mod codegen;
-mod syntax;
+with_backend! { mod: [analyze, check, codegen, syntax] }
+with_backend! { use std::{fs, env, path::Path}; }
+with_backend! { use proc_macro::TokenStream; }
-// Used for mocking the API in testing
-#[doc(hidden)]
-#[proc_macro_attribute]
-pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream {
- if let Err(e) = syntax::parse(args, input) {
- e.to_compile_error().into()
- } else {
- "fn main() {}".parse().unwrap()
+with_backend! {
+ // Used for mocking the API in testing
+ #[doc(hidden)]
+ #[proc_macro_attribute]
+ pub fn mock_app(args: TokenStream, input: TokenStream) -> TokenStream {
+ if let Err(e) = syntax::parse(args, input) {
+ e.to_compile_error().into()
+ } else {
+ "fn main() {}".parse().unwrap()
+ }
}
}
-/// Attribute used to declare a RTIC application
-///
-/// For user documentation see the [RTIC book](https://rtic.rs)
-///
-/// # Panics
-///
-/// Should never panic, cargo feeds a path which is later converted to a string
-#[proc_macro_attribute]
-pub fn app(args: TokenStream, input: TokenStream) -> TokenStream {
- let (app, analysis) = match syntax::parse(args, input) {
- Err(e) => return e.to_compile_error().into(),
- Ok(x) => x,
- };
+with_backend! {
+ /// Attribute used to declare a RTIC application
+ ///
+ /// For user documentation see the [RTIC book](https://rtic.rs)
+ ///
+ /// # Panics
+ ///
+ /// Should never panic, cargo feeds a path which is later converted to a string
+ #[proc_macro_attribute]
+ pub fn app(_args: TokenStream, _input: TokenStream) -> TokenStream {
+ let (app, analysis) = match syntax::parse(_args, _input) {
+ Err(e) => return e.to_compile_error().into(),
+ Ok(x) => x,
+ };
- if let Err(e) = check::app(&app, &analysis) {
- return e.to_compile_error().into();
- }
+ if let Err(e) = check::app(&app, &analysis) {
+ 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/
- let mut out_dir = Path::new("target");
+ // Default output path: <project_dir>/target/
+ let mut out_dir = Path::new("target");
- // Get output directory from Cargo environment
- // 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());
+ // Get output directory from Cargo environment
+ // 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());
- if !out_dir.exists() {
- // Set out_dir to OUT_DIR
- out_dir = Path::new(&out_str);
+ if !out_dir.exists() {
+ // Set out_dir to OUT_DIR
+ out_dir = Path::new(&out_str);
- // Default build path, annotated below:
- // $(pwd)/target/thumbv7em-none-eabihf/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")
- // and use the parent() of this path
- //
- // If no "target" directory is found, <project_dir>/<out_dir_root> is used
- for path in out_dir.ancestors() {
- if let Some(dir) = path.components().last() {
- let dir = dir.as_os_str().to_str().unwrap();
+ // Default build path, annotated below:
+ // $(pwd)/target/thumbv7em-none-eabihf/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")
+ // and use the parent() of this path
+ //
+ // If no "target" directory is found, <project_dir>/<out_dir_root> is used
+ for path in out_dir.ancestors() {
+ if let Some(dir) = path.components().last() {
+ let dir = dir.as_os_str().to_str().unwrap();
- if dir.starts_with("thumbv") || dir.starts_with("riscv") {
- if let Some(out) = path.parent() {
- out_dir = out;
+ if dir.starts_with("thumbv") || dir.starts_with("riscv") {
+ if let Some(out) = path.parent() {
+ out_dir = out;
+ break;
+ }
+ // If no parent, just use it
+ out_dir = path;
break;
}
- // If no parent, just use it
- out_dir = path;
- break;
}
}
}
- }
- // Try to write the expanded code to disk
- if let Some(out_str) = out_dir.to_str() {
- fs::write(format!("{out_str}/rtic-expansion.rs"), ts.to_string()).ok();
- }
+ // Try to write the expanded code to disk
+ if let Some(out_str) = out_dir.to_str() {
+ 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.");
diff --git a/rtic-monotonics/Cargo.toml b/rtic-monotonics/Cargo.toml
index b9145a2..3c294ea 100644
--- a/rtic-monotonics/Cargo.toml
+++ b/rtic-monotonics/Cargo.toml
@@ -11,10 +11,12 @@ authors = [
"Per Lindgren <per.lindgren@ltu.se>",
]
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"
-# 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]
rtic-time = { version = "1.0.0-alpha.1", path = "../rtic-time" }
diff --git a/rtic-monotonics/src/lib.rs b/rtic-monotonics/src/lib.rs
index 714200a..82e22a5 100644
--- a/rtic-monotonics/src/lib.rs
+++ b/rtic-monotonics/src/lib.rs
@@ -1,9 +1,30 @@
-//! 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]
#![deny(missing_docs)]
#![allow(incomplete_features)]
#![feature(async_fn_in_trait)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
pub use rtic_time::{Monotonic, TimeoutError, TimerQueue};
diff --git a/rtic-monotonics/src/nrf.rs b/rtic-monotonics/src/nrf.rs
index 0f6b973..f2fd3f6 100644
--- a/rtic-monotonics/src/nrf.rs
+++ b/rtic-monotonics/src/nrf.rs
@@ -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 timer;
diff --git a/rtic-monotonics/src/nrf/rtc.rs b/rtic-monotonics/src/nrf/rtc.rs
index 2e23389..50087ab 100644
--- a/rtic-monotonics/src/nrf/rtc.rs
+++ b/rtic-monotonics/src/nrf/rtc.rs
@@ -1,4 +1,4 @@
-//! RTIC Monotonic impl for the nRF RTCs.
+//! [`Monotonic`] implementation for the nRF Real Time Clocks (RTC).
//!
//! # Example
//!
@@ -82,6 +82,10 @@ macro_rules! create_nrf_rtc1_monotonic_token {
/// Register the Rtc2 interrupt for the monotonic.
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")))
+)]
#[macro_export]
macro_rules! create_nrf_rtc2_monotonic_token {
() => {{
@@ -90,8 +94,11 @@ macro_rules! create_nrf_rtc2_monotonic_token {
}
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.
+ $(
+ #[cfg_attr(docsrs, doc(cfg($($doc)*)))]
+ )?
pub struct $mono_name;
static $overflow: AtomicU32 = AtomicU32::new(0);
@@ -243,4 +250,4 @@ macro_rules! make_rtc {
make_rtc!(Rtc0, RTC0, RTC0_OVERFLOWS, RTC0_TQ);
make_rtc!(Rtc1, RTC1, RTC1_OVERFLOWS, RTC1_TQ);
#[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")));
diff --git a/rtic-monotonics/src/nrf/timer.rs b/rtic-monotonics/src/nrf/timer.rs
index 5e8fe93..6b7ade6 100644
--- a/rtic-monotonics/src/nrf/timer.rs
+++ b/rtic-monotonics/src/nrf/timer.rs
@@ -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
//!
@@ -95,6 +98,10 @@ macro_rules! create_nrf_timer2_monotonic_token {
}
/// 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"))]
#[macro_export]
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.
+#[cfg_attr(
+ docsrs,
+ doc(cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")))
+)]
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
#[macro_export]
macro_rules! create_nrf_timer4_monotonic_token {
@@ -113,8 +124,11 @@ macro_rules! create_nrf_timer4_monotonic_token {
}
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.
+ $(
+ #[cfg_attr(docsrs, doc(cfg($($doc)*)))]
+ )?
pub struct $mono_name;
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!(Timer2, TIMER2, TIMER2_OVERFLOWS, TIMER2_TQ);
#[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"))]
-make_timer!(Timer4, TIMER4, TIMER4_OVERFLOWS, TIMER4_TQ);
+make_timer!(Timer4, TIMER4, TIMER4_OVERFLOWS, TIMER4_TQ, doc: (any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840")));
diff --git a/rtic-monotonics/src/rp2040.rs b/rtic-monotonics/src/rp2040.rs
index 8c248f9..ac1fc1a 100644
--- a/rtic-monotonics/src/rp2040.rs
+++ b/rtic-monotonics/src/rp2040.rs
@@ -1,4 +1,4 @@
-//! A monotonic implementation for RP2040's Timer peripheral.
+//! [`Monotonic`] implementation for RP2040's Timer peripheral.
//!
//! # Example
//!
diff --git a/rtic-monotonics/src/systick.rs b/rtic-monotonics/src/systick.rs
index cba9aa2..0f215a7 100644
--- a/rtic-monotonics/src/systick.rs
+++ b/rtic-monotonics/src/systick.rs
@@ -1,6 +1,14 @@
-//! A monotonics based on Cortex-M SysTick. Note that this implementation is inefficient as it
-//! ticks, and generates interrupts, at a constant rate.
+//! [`Monotonic`] based on Cortex-M SysTick. Note: this implementation is inefficient as it
+//! 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
//!
//! ```
diff --git a/rtic-sync/src/arbiter.rs b/rtic-sync/src/arbiter.rs
index d50b1ea..deb0a4f 100644
--- a/rtic-sync/src/arbiter.rs
+++ b/rtic-sync/src/arbiter.rs
@@ -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::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`.
pub async fn access(&self) -> ExclusiveAccess<'_, T> {
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> {
arbiter: &'a Arbiter<T>,
inner: &'a mut T,
diff --git a/rtic-sync/src/channel.rs b/rtic-sync/src/channel.rs
index b7b5a48..8c9f861 100644
--- a/rtic-sync/src/channel.rs
+++ b/rtic-sync/src/channel.rs
@@ -1,4 +1,4 @@
-//! Crate
+//! An async aware MPSC channel that can be used on no-alloc systems.
use core::{
cell::UnsafeCell,
diff --git a/rtic-time/src/lib.rs b/rtic-time/src/lib.rs
index 7c0c764..05c5026 100644
--- a/rtic-time/src/lib.rs
+++ b/rtic-time/src/lib.rs
@@ -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]
#![deny(missing_docs)]
diff --git a/rtic-time/src/linked_list.rs b/rtic-time/src/linked_list.rs
index c2a9967..b84b92d 100644
--- a/rtic-time/src/linked_list.rs
+++ b/rtic-time/src/linked_list.rs
@@ -1,11 +1,12 @@
-//! ...
-
use core::marker::PhantomPinned;
use core::pin::Pin;
use core::sync::atomic::{AtomicPtr, Ordering};
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> {
head: AtomicPtr<Link<T>>,
}
diff --git a/rtic-time/src/monotonic.rs b/rtic-time/src/monotonic.rs
index 513cc07..ad79bf2 100644
--- a/rtic-time/src/monotonic.rs
+++ b/rtic-time/src/monotonic.rs
@@ -1,4 +1,4 @@
-//! ...
+//! A monotonic clock / counter definition.
/// # A monotonic clock / counter definition.
///
diff --git a/rtic/Cargo.toml b/rtic/Cargo.toml
index 9a05b75..f28c9a7 100644
--- a/rtic/Cargo.toml
+++ b/rtic/Cargo.toml
@@ -24,6 +24,9 @@ repository = "https://github.com/rtic-rs/rtic"
version = "2.0.0-alpha.1"
+[package.metadata.docs.rs]
+features = ["rtic-macros/test-template"]
+
[lib]
name = "rtic"
diff --git a/rtic/src/lib.rs b/rtic/src/lib.rs
index 53fe287..e394ea3 100644
--- a/rtic/src/lib.rs
+++ b/rtic/src/lib.rs
@@ -9,8 +9,8 @@
//!
//! # Minimum Supported Rust Version (MSRV)
//!
-//! This crate is compiled and tested with the latest toolchain (rolling) as of the release date.
-//! If you run into compilation errors, try the latest stable release of the rust toolchain.
+//! This crate is compiled and tested with the latest nightly toolchain (rolling).
+//! If you run into compilation errors, try the latest nightly release of the rust toolchain.
//!
//! # Semantic Versioning
//!