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?