Shared
A macro for safely sharing data between application and interrupt context on cortex-m systems
NOTE: This code is still an early work in progress!
What it looks like now
use nrf52832_pac::Interrupt;
use bare_metal;
use cortex_m;
shared!(
(RADIO_PKTS, usize, Interrupt::RADIO),
(WALL_CLOCK, usize, Interrupt::RTC0),
);
#[entry]
fn main() {
let mut token = RADIO_PKTS::set_initial(27).unwrap();
token.modify_app_context(|y| {
*y -= 1;
y
}).unwrap();
}
#[interrupt]
fn RADIO() {
RADIO_PKTS::modify_int_context(|x| {
*x += 1;
x
}).unwrap();
}
#[interrupt]
fn RTC0() {
BAZ::modify_int_context(|x| {
*x += 1;
x
}).unwrap();
}
The original idea
The following is the desired end goal of this project. We're not there yet.
Stage 1 - Moving data to interrupts
use nrf52832_pac::Interrupt;
use something::Queue;
cmim!(
Interrupt::RADIO: bool,
Interrupt::TIMER0: u128,
Interrupt::UARTE0_UARTE: Queue::Producer,
);
fn main() {
let (prod, cons) = Queue::new().split();
cmim_set!(
Interrupt::UARTE0_UARTE,
prod
).unwrap();
NVIC::enable(Interrupt::UARTE0_UARTE);
loop {
let _ = cons.pop();
}
}
#[interrupt]
fn UARTE0_UARTE() {
let data: &mut Producer = cmim_get!(Interrupt::UARTE0_UARTE).unwrap();
data.push(0x00);
}
Stage 2 - Sharing data with a single interrupt
use nrf52832_pac::Interrupt;
cmim!(
Interrupt::RADIO: bool,
Interrupt::TIMER0: u128,
Interrupt::UARTE0_UARTE: bbqueue::Producer,
);
fn main() {
cmim_set!(
Interrupt::RADIO,
false
).unwrap();
NVIC::enable(Interrupt::RADIO);
loop {
let data_copy = cmim_borrow!(
Interrupt::RADIO,
|data: &mut bool| {
*data = true;
}
).unwrap();
}
}
#[interrupt]
fn RADIO() {
let data: &mut bool = cmim_get!(Interrupt::RADIO).unwrap();
if *data {
}
}
Stage 3 - Sharing data between interrupts
I have no idea how to do this without the possibility of deadlock. Maybe specify multiple interrupts in cmim!()
, and critical section all of them at once? Maybe do priority elevation like RTFM?