Skip to content

Commit 9d79ad6

Browse files
committed
中断闭包处理
1 parent 2ba6e20 commit 9d79ad6

16 files changed

Lines changed: 88 additions & 87 deletions

File tree

examples/adc_block_interrupt_closure.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
#![no_main]
33

44
use core::cell::RefCell;
5-
65
use cortex_m::interrupt::{self, Mutex};
7-
use PY32f030xx_pac::{adc, ADC};
8-
9-
use defmt::info;
106
use hal::adc::{AdcChannel, AnyAdc, ChannelConfig, Config, SampleCycles, TrigleSignal};
117
use heapless::spsc::Queue;
128

@@ -20,6 +16,10 @@ use {defmt_rtt as _, panic_probe as _};
2016
static ADC_INSTANCE: Mutex<RefCell<Option<AnyAdc<hal::mcu::peripherals::ADC, Blocking>>>> =
2117
Mutex::new(RefCell::new(None));
2218

19+
type AdcQueue = Queue<u16, 128>;
20+
21+
static ADC_QUEUE: Mutex<RefCell<AdcQueue>> = Mutex::new(RefCell::new(AdcQueue::new()));
22+
2323
#[cortex_m_rt::entry]
2424
fn main() -> ! {
2525
let p = hal::init(Default::default());
@@ -41,26 +41,25 @@ fn main() -> ! {
4141
let _ = interrupt::free(|cs| {
4242
adc.event_config(Event::EOC, true);
4343
ADC_INSTANCE.borrow(cs).replace(Some(adc));
44-
4544
let mut adc_bind = ADC_INSTANCE.borrow(cs).borrow_mut();
4645
let adc = adc_bind.as_mut().unwrap();
47-
let _ = adc.id().bind(&|| {
48-
interrupt::free(|cs| {
49-
let mut adc_bind = ADC_INSTANCE.borrow(cs).borrow_mut();
50-
let adc = adc_bind.as_mut().unwrap();
51-
let _ = adc.read_once();
52-
})
46+
let _ = adc.id().bind(&|cs| {
47+
let mut adc = ADC_INSTANCE.borrow(cs).borrow_mut();
48+
let mut queue = ADC_QUEUE.borrow(cs).borrow_mut();
49+
let _ = queue.enqueue(adc.as_mut().unwrap().read_once());
5350
});
54-
adc.id().enable();
51+
adc.id().enable_irq();
5552
adc.start();
5653
});
5754

58-
// 使用闭包的方式在中断中调用闭包处理函数
59-
// 兼顾友好型 api
60-
static mut ADC_QUEUE: Queue<u16, 128> = Queue::new();
6155
loop {
6256
cortex_m::asm::wfi();
6357

64-
defmt::info!("adc value: {}", unsafe { ADC_QUEUE.dequeue().unwrap() });
58+
interrupt::free(|cs| {
59+
let mut queue = ADC_QUEUE.borrow(cs).borrow_mut();
60+
while let Some(v) = queue.dequeue() {
61+
defmt::info!("adc value: {}", v);
62+
}
63+
})
6564
}
6665
}

src/adc/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod pins;
77
mod types;
88

99
use crate::pac;
10-
use cortex_m::interrupt::InterruptNumber;
10+
use cortex_m::interrupt::{self, InterruptNumber};
1111

1212
#[cfg(feature = "embassy")]
1313
use core::{future::Future, task::Poll};
@@ -50,8 +50,10 @@ pub enum Id {
5050
impl BindInterrupt for Id {
5151
#[cfg(feature = "embassy")]
5252
fn bind_default(&self) -> Result<(), crate::interrupt::Error> {
53-
Self::bind(self, &|| unsafe {
54-
ChannelInputFuture::<crate::mcu::peripherals::ADC>::on_interrupt();
53+
interrupt::free(|_cs| {
54+
Self::bind(self, &|_cs| unsafe {
55+
ChannelInputFuture::<crate::mcu::peripherals::ADC>::on_interrupt();
56+
})
5557
})
5658
}
5759
}
@@ -97,7 +99,7 @@ impl<'d, T: Instance, M: Mode> AnyAdc<'d, T, M> {
9799

98100
// 异步方式需要打开外设中断
99101
if M::is_async() {
100-
T::id().enable();
102+
T::id().enable_irq();
101103
}
102104

103105
Ok(Self {
@@ -209,7 +211,7 @@ impl<'d, T: Instance, M: Mode> AnyAdc<'d, T, M> {
209211
impl<'d, T: Instance, M: Mode> Drop for AnyAdc<'d, T, M> {
210212
fn drop(&mut self) {
211213
if M::is_async() {
212-
T::id().disable();
214+
T::id().disable_irq();
213215
}
214216
}
215217
}

src/dma/future.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl<T: Instance> Unpin for EventFuture<T> {}
2626
impl<T: Instance> Drop for EventFuture<T> {
2727
fn drop(&mut self) {
2828
// 关闭通道中断
29-
self.channel.disable();
29+
self.channel.disable_irq();
3030
}
3131
}
3232

@@ -85,7 +85,7 @@ impl<T: Instance> Future for EventFuture<T> {
8585
.iter()
8686
.for_each(|event| T::event_config(self.channel, event, true));
8787
// 开启通道的中断
88-
self.channel.enable();
88+
self.channel.enable_irq();
8989
// 没有任何事件
9090
Poll::Pending
9191
}

src/dma/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::mode::Async;
1111
use crate::mode::{Blocking, Mode};
1212
use crate::syscfg::{syscfg, DmaChannelMap};
1313
use core::marker::PhantomData;
14-
use cortex_m::interrupt::InterruptNumber;
14+
use cortex_m::interrupt::{self, InterruptNumber};
1515
use embassy_hal_internal::{into_ref, Peripheral};
1616
use enumset::EnumSet;
1717
#[cfg(feature = "embassy")]
@@ -47,14 +47,14 @@ pub enum Channel {
4747

4848
impl BindInterrupt for Channel {
4949
fn bind_default(&self) -> Result<(), crate::interrupt::Error> {
50-
match self {
51-
Self::Channel1 => Self::bind(&self, &|| unsafe {
50+
interrupt::free(|_cs| match self {
51+
Self::Channel1 => Self::bind(&self, &|_cs| unsafe {
5252
EventFuture::<crate::mcu::peripherals::DMA>::on_interrupt(
5353
Channel::Channel1,
5454
EnumSet::all(),
5555
)
5656
}),
57-
Self::Channel2 | Self::Channel3 => Self::bind(&self, &|| unsafe {
57+
Self::Channel2 | Self::Channel3 => Self::bind(&self, &|_cs| unsafe {
5858
EventFuture::<crate::mcu::peripherals::DMA>::on_interrupt(
5959
Channel::Channel2,
6060
EnumSet::all(),
@@ -64,7 +64,7 @@ impl BindInterrupt for Channel {
6464
EnumSet::all(),
6565
)
6666
}),
67-
}
67+
})
6868
}
6969
}
7070

src/exti/future.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'d> Future for ExtiInputFuture<'d> {
5757
Poll::Ready(())
5858
} else {
5959
EXIT_GPIO_WAKERS[self.line as usize].register(cx.waker());
60-
self.line.enable();
60+
self.line.enable_irq();
6161
Poll::Pending
6262
}
6363
}

src/exti/types.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::future;
22
use crate::bit::*;
33
use crate::gpio::{self, GpioPort};
4-
use crate::interrupt::{self, BindInterrupt};
4+
use crate::interrupt::{BindInterrupt, Error};
55
use crate::pac;
6-
use cortex_m::interrupt::InterruptNumber;
6+
use cortex_m::interrupt::{self, InterruptNumber};
77

88
#[derive(Debug, PartialEq, Clone, Copy)]
99
pub enum Line {
@@ -52,22 +52,18 @@ pub enum Line {
5252
}
5353

5454
impl BindInterrupt for Line {
55-
fn bind_default(&self) -> Result<(), interrupt::Error> {
56-
match *self {
57-
Self::Line0 | Self::Line1 => {
58-
interrupt::bind(Self::Line0.number() as usize, &|| unsafe {
59-
future::on_gpio_line_irq(0x03);
60-
})
61-
}
62-
Self::Line2 | Self::Line3 => {
63-
interrupt::bind(Self::Line2.number() as usize, &|| unsafe {
64-
future::on_gpio_line_irq(0xc0);
65-
})
66-
}
67-
_ => interrupt::bind(Self::Line4.number() as usize, &|| unsafe {
55+
fn bind_default(&self) -> Result<(), Error> {
56+
interrupt::free(|_cs| match *self {
57+
Self::Line0 | Self::Line1 => Self::bind(&self, &|_cs| unsafe {
58+
future::on_gpio_line_irq(0x03);
59+
}),
60+
Self::Line2 | Self::Line3 => Self::bind(&self, &|_cs| unsafe {
61+
future::on_gpio_line_irq(0xc0);
62+
}),
63+
_ => Self::bind(&self, &|_cs| unsafe {
6864
future::on_gpio_line_irq(0xfff0);
6965
}),
70-
}
66+
})
7167
}
7268
}
7369

src/i2c/master.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub struct Master<'d, T: Instance, M: Mode> {
2121
impl<'d, T: Instance, M: Mode> Master<'d, T, M> {
2222
pub(super) fn new() -> Self {
2323
if M::is_async() {
24-
T::id().enable();
24+
T::id().enable_irq();
2525
}
2626
Self { _t: PhantomData }
2727
}
@@ -30,7 +30,7 @@ impl<'d, T: Instance, M: Mode> Master<'d, T, M> {
3030
impl<'d, T: Instance, M: Mode> Drop for Master<'d, T, M> {
3131
fn drop(&mut self) {
3232
if M::is_async() {
33-
T::id().disable();
33+
T::id().disable_irq();
3434
}
3535
}
3636
}

src/i2c/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::interrupt::BindInterrupt;
1111
use crate::macro_def::{impl_sealed_peripheral_id, pin_af_for_instance_def};
1212
use crate::mode::Mode;
1313
use core::marker::PhantomData;
14-
use cortex_m::interrupt::InterruptNumber;
14+
use cortex_m::interrupt::{self, InterruptNumber};
1515
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
1616
use enumset::EnumSetType;
1717
pub use master::Master;
@@ -35,11 +35,11 @@ unsafe impl InterruptNumber for Id {
3535

3636
impl BindInterrupt for Id {
3737
fn bind_default(&self) -> Result<(), crate::interrupt::Error> {
38-
match *self {
39-
Self::I2c1 => Self::bind(&self, &|| unsafe {
38+
interrupt::free(|_cs| match *self {
39+
Self::I2c1 => Self::bind(&self, &|_cs| unsafe {
4040
future::EventFuture::<crate::mcu::peripherals::I2C>::on_interrupt()
4141
}),
42-
}
42+
})
4343
}
4444
}
4545

src/interrupt.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use crate::pac::interrupt;
22
use core::cell::RefCell;
3-
use cortex_m::interrupt::{free, InterruptNumber, Mutex};
3+
use cortex_m::interrupt::{free, CriticalSection, InterruptNumber, Mutex};
44

55
pub enum Error {
66
InvalidInterruptNumber,
77
DoubleBinding,
88
}
99

10-
static mut INTERRUPT_HANDLERS: [Mutex<RefCell<Option<&'static dyn Fn()>>>; 32] = {
11-
const INIT_HANDLER: Mutex<RefCell<Option<&'static dyn Fn()>>> = Mutex::new(RefCell::new(None));
10+
type InterruptHandle = &'static dyn Fn(&CriticalSection);
11+
// type InterruptHandle = dyn Fn(&CriticalSection) + Send + 'static;
12+
13+
static mut INTERRUPT_HANDLERS: [Mutex<RefCell<Option<InterruptHandle>>>; 32] = {
14+
const INIT_HANDLER: Mutex<RefCell<Option<InterruptHandle>>> = Mutex::new(RefCell::new(None));
1215
[INIT_HANDLER; 32]
1316
};
1417

@@ -17,21 +20,21 @@ pub trait BindInterrupt: InterruptNumber + Copy + Clone {
1720
/* 绑定一个默认的中断处理函数给funtures用 */
1821
fn bind_default(&self) -> Result<(), Error>;
1922

20-
fn bind(&self, f: &'static dyn Fn()) -> Result<(), Error> {
23+
fn bind(&self, f: &'static dyn Fn(&CriticalSection)) -> Result<(), Error> {
2124
bind(self.number() as usize, f)
2225
}
2326
fn unbind(&self) {
2427
let _ = unbind(self.number() as usize);
2528
}
26-
fn enable(&self) {
29+
fn enable_irq(&self) {
2730
unsafe { cortex_m::peripheral::NVIC::unmask(*self) }
2831
}
29-
fn disable(&self) {
32+
fn disable_irq(&self) {
3033
cortex_m::peripheral::NVIC::mask(*self)
3134
}
3235
}
3336

34-
pub fn bind(irq_num: usize, f: &'static dyn Fn()) -> Result<(), Error> {
37+
pub fn bind(irq_num: usize, f: InterruptHandle) -> Result<(), Error> {
3538
if irq_num >= 32 {
3639
return Err(Error::InvalidInterruptNumber);
3740
}
@@ -77,7 +80,7 @@ macro_rules! define_interrupt_wrapper {
7780
let handler_cell = unsafe { INTERRUPT_HANDLERS[$irq_num].borrow(cs).borrow_mut() };
7881

7982
if let Some(handler) = *handler_cell {
80-
handler();
83+
handler(cs);
8184
}
8285
});
8386
}

src/rtc/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::{
99
rtc::future::WakeFuture,
1010
};
1111
use core::marker::PhantomData;
12+
use cortex_m::interrupt;
1213
use cortex_m::interrupt::InterruptNumber;
1314
use embassy_hal_internal::Peripheral;
1415
use enumset::EnumSet;
@@ -42,11 +43,11 @@ unsafe impl InterruptNumber for Id {
4243
impl BindInterrupt for Id {
4344
#[cfg(feature = "embassy")]
4445
fn bind_default(&self) -> Result<(), crate::interrupt::Error> {
45-
match *self {
46-
Self::Rtc1 => Self::bind(self, &|| {
46+
interrupt::free(|_cs| match *self {
47+
Self::Rtc1 => Self::bind(self, &|_cs| {
4748
WakeFuture::<crate::mcu::peripherals::RTC>::on_interrupt()
4849
}),
49-
}
50+
})
5051
}
5152
}
5253

@@ -161,7 +162,7 @@ impl<'d, T: Instance> AnyRtc<'d, T, Async> {
161162
T::clear_interrupt(event);
162163
T::event_config(event, true);
163164
});
164-
T::id().enable();
165+
T::id().enable_irq();
165166
future::WakeFuture::<T>::new(event).await
166167
}
167168

@@ -175,7 +176,7 @@ impl<'d, T: Instance> AnyRtc<'d, T, Async> {
175176
T::clear_interrupt(event);
176177
T::event_config(event, true);
177178
});
178-
T::id().enable();
179+
T::id().enable_irq();
179180
future::WakeFuture::<T>::new(event).await
180181
}
181182
}

0 commit comments

Comments
 (0)