aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml2
-rw-r--r--rtic-monotonics/CHANGELOG.md5
-rw-r--r--rtic-monotonics/src/lib.rs10
-rw-r--r--rtic-monotonics/src/rp2040.rs22
-rw-r--r--rtic-monotonics/src/systick.rs18
-rw-r--r--rtic-sync/src/channel.rs5
-rw-r--r--rtic/examples/async-delay.rs5
-rw-r--r--rtic/examples/async-timeout.rs5
8 files changed, 55 insertions, 17 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d4c78cf8..aadb0a97 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -32,7 +32,7 @@ jobs:
uses: Swatinem/rust-cache@v2
- name: cargo xtask format-check
- run: cargo xtask format-check
+ run: cargo xtask --verbose format-check
# Compilation check
check:
diff --git a/rtic-monotonics/CHANGELOG.md b/rtic-monotonics/CHANGELOG.md
index d3a9d846..816bc247 100644
--- a/rtic-monotonics/CHANGELOG.md
+++ b/rtic-monotonics/CHANGELOG.md
@@ -9,8 +9,13 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
### Added
+- Interrupt tokens for `Systick` and `rp2040` to make sure an interrupt handler exists
+
### Changed
### Fixed
+- Unmask the `rp2040` interrupt
+- Use `$crate` and fully qualified paths in macros
+
## [v1.0.0] - 2023-xx-xx
diff --git a/rtic-monotonics/src/lib.rs b/rtic-monotonics/src/lib.rs
index a4a1f428..6143fd0e 100644
--- a/rtic-monotonics/src/lib.rs
+++ b/rtic-monotonics/src/lib.rs
@@ -13,3 +13,13 @@ pub mod systick;
#[cfg(feature = "rp2040")]
pub mod rp2040;
+
+/// This marker is implemented on an interrupt token to enforce that the right tokens
+/// are given to the correct monotonic implementation.
+///
+/// This trait is implemented by this crate and not intended for user implementation.
+///
+/// # Safety
+///
+/// This is only safely implemented by this crate.
+pub unsafe trait InterruptToken<Periperhal> {}
diff --git a/rtic-monotonics/src/rp2040.rs b/rtic-monotonics/src/rp2040.rs
index e42c148e..6aa66ce0 100644
--- a/rtic-monotonics/src/rp2040.rs
+++ b/rtic-monotonics/src/rp2040.rs
@@ -4,19 +4,25 @@ use super::Monotonic;
pub use super::{TimeoutError, TimerQueue};
use core::future::Future;
pub use fugit::ExtU64;
-use rp2040_pac::{timer, Interrupt, RESETS, TIMER};
+use rp2040_pac::{timer, Interrupt, NVIC, RESETS, TIMER};
/// Timer implementing `rtic_monotonic::Monotonic` which runs at 1 MHz.
pub struct Timer;
impl Timer {
/// Start a `Monotonic` based on RP2040's Timer.
- pub fn start(timer: TIMER, resets: &mut RESETS) {
+ pub fn start(
+ timer: TIMER,
+ resets: &mut RESETS,
+ _interrupt_token: impl crate::InterruptToken<Self>,
+ ) {
resets.reset.modify(|_, w| w.timer().clear_bit());
while resets.reset_done.read().timer().bit_is_clear() {}
timer.inte.modify(|_, w| w.alarm_0().set_bit());
TIMER_QUEUE.initialize(Self {});
+
+ unsafe { NVIC::unmask(Interrupt::TIMER_IRQ_0) };
}
fn timer() -> &'static timer::RegisterBlock {
@@ -133,11 +139,17 @@ impl embedded_hal_async::delay::DelayUs for Timer {
/// Register the Timer interrupt for the monotonic.
#[macro_export]
macro_rules! make_rp2040_monotonic_handler {
- () => {
+ () => {{
#[no_mangle]
#[allow(non_snake_case)]
unsafe extern "C" fn TIMER_IRQ_0() {
- rtic_monotonics::rp2040::Timer::__tq().on_monotonic_interrupt();
+ $crate::rp2040::Timer::__tq().on_monotonic_interrupt();
}
- };
+
+ pub struct Rp2040Token;
+
+ unsafe impl $crate::InterruptToken<$crate::rp2040::Timer> for Rp2040Token {}
+
+ Rp2040Token
+ }};
}
diff --git a/rtic-monotonics/src/systick.rs b/rtic-monotonics/src/systick.rs
index 691d7c76..b228e204 100644
--- a/rtic-monotonics/src/systick.rs
+++ b/rtic-monotonics/src/systick.rs
@@ -36,7 +36,11 @@ impl Systick {
/// `sysclk` and `TIMER_HZ`.
///
/// Note: Give the return value to `TimerQueue::initialize()` to initialize the timer queue.
- pub fn start(mut systick: cortex_m::peripheral::SYST, sysclk: u32) {
+ pub fn start(
+ mut systick: cortex_m::peripheral::SYST,
+ sysclk: u32,
+ _interrupt_token: impl crate::InterruptToken<Self>,
+ ) {
// + TIMER_HZ / 2 provides round to nearest instead of round to 0.
// - 1 as the counter range is inclusive [0, reload]
let reload = (sysclk + TIMER_HZ / 2) / TIMER_HZ - 1;
@@ -153,11 +157,17 @@ impl embedded_hal_async::delay::DelayUs for Systick {
/// Register the Systick interrupt for the monotonic.
#[macro_export]
macro_rules! make_systick_handler {
- () => {
+ () => {{
#[no_mangle]
#[allow(non_snake_case)]
unsafe extern "C" fn SysTick() {
- rtic_monotonics::systick::Systick::__tq().on_monotonic_interrupt();
+ $crate::systick::Systick::__tq().on_monotonic_interrupt();
}
- };
+
+ pub struct SystickToken;
+
+ unsafe impl $crate::InterruptToken<$crate::systick::Systick> for SystickToken {}
+
+ SystickToken
+ }};
}
diff --git a/rtic-sync/src/channel.rs b/rtic-sync/src/channel.rs
index 8a817c81..b7b5a485 100644
--- a/rtic-sync/src/channel.rs
+++ b/rtic-sync/src/channel.rs
@@ -38,6 +38,7 @@ pub struct Channel<T, const N: usize> {
}
unsafe impl<T, const N: usize> Send for Channel<T, N> {}
+
unsafe impl<T, const N: usize> Sync for Channel<T, N> {}
struct UnsafeAccess<'a, const N: usize> {
@@ -102,7 +103,8 @@ impl<T, const N: usize> Channel<T, N> {
#[macro_export]
macro_rules! make_channel {
($type:path, $size:expr) => {{
- static mut CHANNEL: Channel<$type, $size> = Channel::new();
+ static mut CHANNEL: $crate::channel::Channel<$type, $size> =
+ $crate::channel::Channel::new();
// SAFETY: This is safe as we hide the static mut from others to access it.
// Only this point is where the mutable access happens.
@@ -176,6 +178,7 @@ impl LinkPtr {
}
unsafe impl Send for LinkPtr {}
+
unsafe impl Sync for LinkPtr {}
impl<'a, T, const N: usize> core::fmt::Debug for Sender<'a, T, N> {
diff --git a/rtic/examples/async-delay.rs b/rtic/examples/async-delay.rs
index c163a3e6..7b3667b0 100644
--- a/rtic/examples/async-delay.rs
+++ b/rtic/examples/async-delay.rs
@@ -14,8 +14,6 @@ mod app {
use cortex_m_semihosting::{debug, hprintln};
use rtic_monotonics::systick::*;
- rtic_monotonics::make_systick_handler!();
-
#[shared]
struct Shared {}
@@ -26,7 +24,8 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init");
- Systick::start(cx.core.SYST, 12_000_000);
+ let systick_token = rtic_monotonics::make_systick_handler!();
+ Systick::start(cx.core.SYST, 12_000_000, systick_token);
foo::spawn().ok();
bar::spawn().ok();
diff --git a/rtic/examples/async-timeout.rs b/rtic/examples/async-timeout.rs
index 384c8886..e07e9c6f 100644
--- a/rtic/examples/async-timeout.rs
+++ b/rtic/examples/async-timeout.rs
@@ -17,8 +17,6 @@ mod app {
use futures::{future::FutureExt, select_biased};
use rtic_monotonics::Monotonic;
- rtic_monotonics::make_systick_handler!();
-
#[shared]
struct Shared {}
@@ -29,7 +27,8 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init");
- Systick::start(cx.core.SYST, 12_000_000);
+ let systick_token = rtic_monotonics::make_systick_handler!();
+ Systick::start(cx.core.SYST, 12_000_000, systick_token);
foo::spawn().ok();