diff options
-rw-r--r-- | .github/workflows/build.yml | 2 | ||||
-rw-r--r-- | rtic-monotonics/CHANGELOG.md | 5 | ||||
-rw-r--r-- | rtic-monotonics/src/lib.rs | 10 | ||||
-rw-r--r-- | rtic-monotonics/src/rp2040.rs | 22 | ||||
-rw-r--r-- | rtic-monotonics/src/systick.rs | 18 | ||||
-rw-r--r-- | rtic-sync/src/channel.rs | 5 | ||||
-rw-r--r-- | rtic/examples/async-delay.rs | 5 | ||||
-rw-r--r-- | rtic/examples/async-timeout.rs | 5 |
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(); |