Use critical_section crate

This commit is contained in:
Dario Nieuwenhuis
2021-05-11 00:57:52 +02:00
parent f817f374b6
commit 7fa0e57172
17 changed files with 41 additions and 157 deletions

View File

@ -44,7 +44,7 @@ pub struct ExtiPin<T: Instance> {
impl<T: Instance> ExtiPin<T> {
pub fn new(mut pin: T, interrupt: T::Interrupt, syscfg: &mut SysCfg) -> Self {
cortex_m::interrupt::free(|_| {
critical_section::with(|_| {
pin.make_source(syscfg);
});
@ -99,7 +99,7 @@ impl<T: Instance + digital::InputPin + 'static> ExtiPin<T> {
async move {
let fut = InterruptFuture::new(&mut self.interrupt);
let pin = &mut self.pin;
cortex_m::interrupt::free(|_| {
critical_section::with(|_| {
pin.trigger_edge(if state {
EdgeOption::Rising
} else {
@ -126,7 +126,7 @@ impl<T: Instance + 'static> ExtiPin<T> {
async move {
let fut = InterruptFuture::new(&mut self.interrupt);
let pin = &mut self.pin;
cortex_m::interrupt::free(|_| {
critical_section::with(|_| {
pin.trigger_edge(state);
});

View File

@ -3,12 +3,13 @@ use crate::hal::rcc::Clocks;
use core::cell::Cell;
use core::convert::TryInto;
use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
use critical_section::CriticalSection;
use embassy::interrupt::InterruptExt;
use embassy::time::{Clock, TICKS_PER_SECOND};
use embassy::util::CriticalSectionMutex as Mutex;
use crate::interrupt;
use crate::interrupt::{CriticalSection, Interrupt, Mutex};
use crate::interrupt::Interrupt;
// RTC timekeeping works with something we call "periods", which are time intervals
// of 2^15 ticks. The RTC counter value is 16 bits, so one "overflow cycle" is 2 periods.
@ -119,13 +120,13 @@ impl<T: Instance> RTC<T> {
for n in 1..=ALARM_COUNT {
if self.rtc.compare_interrupt_status(n) {
self.rtc.compare_clear_flag(n);
interrupt::free(|cs| self.trigger_alarm(n, cs));
critical_section::with(|cs| self.trigger_alarm(n, cs));
}
}
}
fn next_period(&self) {
interrupt::free(|cs| {
critical_section::with(|cs| {
let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
let t = (period as u64) << 15;
@ -142,7 +143,7 @@ impl<T: Instance> RTC<T> {
})
}
fn trigger_alarm(&self, n: usize, cs: &CriticalSection) {
fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
self.rtc.set_compare_interrupt(n, false);
let alarm = &self.alarms.borrow(cs)[n - 1];
@ -155,14 +156,14 @@ impl<T: Instance> RTC<T> {
}
fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
interrupt::free(|cs| {
critical_section::with(|cs| {
let alarm = &self.alarms.borrow(cs)[n - 1];
alarm.callback.set(Some((callback, ctx)));
})
}
fn set_alarm(&self, n: usize, timestamp: u64) {
interrupt::free(|cs| {
critical_section::with(|cs| {
let alarm = &self.alarms.borrow(cs)[n - 1];
alarm.timestamp.set(timestamp);

View File

@ -8,7 +8,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
use crate::pac::NVIC_PRIO_BITS;
// Re-exports
pub use cortex_m::interrupt::{CriticalSection, Mutex};
pub use embassy::interrupt::{declare, take, Interrupt};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
@ -63,35 +62,6 @@ impl From<Priority> for u8 {
}
}
#[inline]
pub fn free<F, R>(f: F) -> R
where
F: FnOnce(&CriticalSection) -> R,
{
unsafe {
// TODO: assert that we're in privileged level
// Needed because disabling irqs in non-privileged level is a noop, which would break safety.
let primask: u32;
asm!("mrs {}, PRIMASK", out(reg) primask);
asm!("cpsid i");
// Prevent compiler from reordering operations inside/outside the critical section.
compiler_fence(Ordering::SeqCst);
let r = f(&CriticalSection::new());
compiler_fence(Ordering::SeqCst);
if primask & 1 == 0 {
asm!("cpsie i");
}
r
}
}
#[cfg(feature = "stm32f401")]
mod irqs {
use super::*;

View File

@ -2,12 +2,13 @@ use crate::hal::rcc::Clocks;
use atomic_polyfill::{compiler_fence, AtomicU32, Ordering};
use core::cell::Cell;
use core::convert::TryInto;
use critical_section::CriticalSection;
use embassy::interrupt::InterruptExt;
use embassy::time::{Clock, TICKS_PER_SECOND};
use embassy::util::CriticalSectionMutex as Mutex;
use crate::interrupt;
use crate::interrupt::{CriticalSection, Interrupt, Mutex};
use crate::interrupt::Interrupt;
// RTC timekeeping works with something we call "periods", which are time intervals
// of 2^15 ticks. The RTC counter value is 16 bits, so one "overflow cycle" is 2 periods.
@ -117,13 +118,13 @@ impl<T: Instance> RTC<T> {
for n in 1..=ALARM_COUNT {
if self.rtc.compare_interrupt_status(n) {
self.rtc.compare_clear_flag(n);
interrupt::free(|cs| self.trigger_alarm(n, cs));
critical_section::with(|cs| self.trigger_alarm(n, cs));
}
}
}
fn next_period(&self) {
interrupt::free(|cs| {
critical_section::with(|cs| {
let period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
let t = (period as u64) << 15;
@ -140,7 +141,7 @@ impl<T: Instance> RTC<T> {
})
}
fn trigger_alarm(&self, n: usize, cs: &CriticalSection) {
fn trigger_alarm(&self, n: usize, cs: CriticalSection) {
self.rtc.set_compare_interrupt(n, false);
let alarm = &self.alarms.borrow(cs)[n - 1];
@ -153,14 +154,14 @@ impl<T: Instance> RTC<T> {
}
fn set_alarm_callback(&self, n: usize, callback: fn(*mut ()), ctx: *mut ()) {
interrupt::free(|cs| {
critical_section::with(|cs| {
let alarm = &self.alarms.borrow(cs)[n - 1];
alarm.callback.set(Some((callback, ctx)));
})
}
fn set_alarm(&self, n: usize, timestamp: u64) {
interrupt::free(|cs| {
critical_section::with(|cs| {
let alarm = &self.alarms.borrow(cs)[n - 1];
alarm.timestamp.set(timestamp);