Executor API V2.

- It's no longer possible to call run() reentrantly from within a task (soundness issue)
- it's now possible to spawn Send tasks across threads (SendSpawner, #37)
This commit is contained in:
Dario Nieuwenhuis
2021-02-02 05:14:52 +01:00
parent d098952077
commit aeaa34d7a1
25 changed files with 495 additions and 377 deletions

View File

@ -83,11 +83,8 @@ static EXECUTOR: Forever<Executor> = Forever::new();
fn main() -> ! {
info!("Hello World!");
let executor = EXECUTOR.put(Executor::new(cortex_m::asm::sev));
unwrap!(executor.spawn(run()));
loop {
executor.run();
cortex_m::asm::wfe();
}
let executor = EXECUTOR.put(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run()));
});
}

View File

@ -61,14 +61,11 @@ fn main() -> ! {
unsafe { embassy::time::set_clock(rtc) };
let alarm = ALARM.put(rtc.alarm0());
let executor = EXECUTOR.put(Executor::new_with_alarm(alarm, cortex_m::asm::sev));
unwrap!(executor.spawn(run1()));
unwrap!(executor.spawn(run2()));
unwrap!(executor.spawn(run3()));
loop {
executor.run();
cortex_m::asm::wfe();
}
let executor = EXECUTOR.put(Executor::new());
executor.set_alarm(alarm);
executor.run(|spawner| {
unwrap!(spawner.spawn(run1()));
unwrap!(spawner.spawn(run2()));
unwrap!(spawner.spawn(run3()));
});
}

View File

@ -73,11 +73,8 @@ static EXECUTOR: Forever<Executor> = Forever::new();
fn main() -> ! {
info!("Hello World!");
let executor = EXECUTOR.put(Executor::new(cortex_m::asm::sev));
unwrap!(executor.spawn(run()));
loop {
executor.run();
cortex_m::asm::wfe();
}
let executor = EXECUTOR.put(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run()));
});
}

View File

@ -52,11 +52,8 @@ static EXECUTOR: Forever<Executor> = Forever::new();
fn main() -> ! {
info!("Hello World!");
let executor = EXECUTOR.put(Executor::new(cortex_m::asm::sev));
unwrap!(executor.spawn(run()));
loop {
executor.run();
cortex_m::asm::wfe();
}
let executor = EXECUTOR.put(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run()));
});
}

View File

@ -66,9 +66,10 @@ use cortex_m_rt::entry;
use defmt::panic;
use nrf52840_hal::clocks;
use embassy::executor::{task, Executor};
use embassy::executor::{task, Executor, IrqExecutor};
use embassy::time::{Duration, Instant, Timer};
use embassy::util::Forever;
use embassy_nrf::interrupt::OwnedInterrupt;
use embassy_nrf::{interrupt, pac, rtc};
#[task]
@ -114,12 +115,12 @@ async fn run_low() {
}
static RTC: Forever<rtc::RTC<pac::RTC1>> = Forever::new();
static ALARM_HIGH: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
static EXECUTOR_HIGH: Forever<IrqExecutor<interrupt::SWI1_EGU1Interrupt>> = Forever::new();
static ALARM_MED: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
static EXECUTOR_MED: Forever<IrqExecutor<interrupt::SWI0_EGU0Interrupt>> = Forever::new();
static ALARM_LOW: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
static EXECUTOR_LOW: Forever<Executor> = Forever::new();
static ALARM_MED: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
static EXECUTOR_MED: Forever<Executor> = Forever::new();
static ALARM_HIGH: Forever<rtc::Alarm<pac::RTC1>> = Forever::new();
static EXECUTOR_HIGH: Forever<Executor> = Forever::new();
#[entry]
fn main() -> ! {
@ -136,41 +137,31 @@ fn main() -> ! {
rtc.start();
unsafe { embassy::time::set_clock(rtc) };
let alarm_low = ALARM_LOW.put(rtc.alarm0());
let executor_low = EXECUTOR_LOW.put(Executor::new_with_alarm(alarm_low, cortex_m::asm::sev));
let alarm_med = ALARM_MED.put(rtc.alarm1());
let executor_med = EXECUTOR_MED.put(Executor::new_with_alarm(alarm_med, || {
NVIC::pend(interrupt::SWI0_EGU0)
}));
let alarm_high = ALARM_HIGH.put(rtc.alarm2());
let executor_high = EXECUTOR_HIGH.put(Executor::new_with_alarm(alarm_high, || {
NVIC::pend(interrupt::SWI1_EGU1)
}));
// High-priority executor: SWI1_EGU1, priority level 6
let irq = interrupt::take!(SWI1_EGU1);
irq.set_priority(interrupt::Priority::Level6);
let alarm = ALARM_HIGH.put(rtc.alarm2());
let executor = EXECUTOR_HIGH.put(IrqExecutor::new(irq));
executor.set_alarm(alarm);
executor.start(|spawner| {
unwrap!(spawner.spawn(run_high()));
});
unsafe {
let mut nvic: NVIC = core::mem::transmute(());
nvic.set_priority(interrupt::SWI0_EGU0, 7 << 5);
nvic.set_priority(interrupt::SWI1_EGU1, 6 << 5);
NVIC::unmask(interrupt::SWI0_EGU0);
NVIC::unmask(interrupt::SWI1_EGU1);
}
// Medium-priority executor: SWI0_EGU0, priority level 7
let irq = interrupt::take!(SWI0_EGU0);
irq.set_priority(interrupt::Priority::Level7);
let alarm = ALARM_MED.put(rtc.alarm1());
let executor = EXECUTOR_MED.put(IrqExecutor::new(irq));
executor.set_alarm(alarm);
executor.start(|spawner| {
unwrap!(spawner.spawn(run_med()));
});
unwrap!(executor_low.spawn(run_low()));
unwrap!(executor_med.spawn(run_med()));
unwrap!(executor_high.spawn(run_high()));
loop {
executor_low.run();
cortex_m::asm::wfe();
}
}
#[interrupt]
unsafe fn SWI0_EGU0() {
EXECUTOR_MED.steal().run()
}
#[interrupt]
unsafe fn SWI1_EGU1() {
EXECUTOR_HIGH.steal().run()
// Low priority executor: runs in thread mode, using WFE/SEV
let alarm = ALARM_LOW.put(rtc.alarm0());
let executor = EXECUTOR_LOW.put(Executor::new());
executor.set_alarm(alarm);
executor.run(|spawner| {
unwrap!(spawner.spawn(run_low()));
});
}

View File

@ -124,11 +124,8 @@ static EXECUTOR: Forever<Executor> = Forever::new();
fn main() -> ! {
info!("Hello World!");
let executor = EXECUTOR.put(Executor::new(cortex_m::asm::sev));
unwrap!(executor.spawn(run()));
loop {
executor.run();
cortex_m::asm::wfe();
}
let executor = EXECUTOR.put(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(run()));
});
}

View File

@ -53,13 +53,10 @@ fn main() -> ! {
unsafe { embassy::time::set_clock(rtc) };
let alarm = ALARM.put(rtc.alarm0());
let executor = EXECUTOR.put(Executor::new_with_alarm(alarm, cortex_m::asm::sev));
unwrap!(executor.spawn(run1()));
unwrap!(executor.spawn(run2()));
loop {
executor.run();
cortex_m::asm::wfe();
}
let executor = EXECUTOR.put(Executor::new());
executor.set_alarm(alarm);
executor.run(|spawner| {
unwrap!(spawner.spawn(run1()));
unwrap!(spawner.spawn(run2()));
});
}

View File

@ -38,7 +38,7 @@ fn main() -> ! {
rtc.start();
alarm.set_callback(|| info!("ALARM TRIGGERED"));
alarm.set_callback(|_| info!("ALARM TRIGGERED"), core::ptr::null_mut());
alarm.set(53719);
info!("initialized!");

View File

@ -18,7 +18,31 @@ use nrf52840_hal::clocks;
use nrf52840_hal::gpio;
#[task]
async fn run(mut uart: uarte::Uarte<pac::UARTE0>) {
async fn run(uart: pac::UARTE0, port: pac::P0) {
// Init UART
let port0 = gpio::p0::Parts::new(port);
let pins = uarte::Pins {
rxd: port0.p0_08.into_floating_input().degrade(),
txd: port0
.p0_06
.into_push_pull_output(gpio::Level::Low)
.degrade(),
cts: None,
rts: None,
};
// NOTE(unsafe): Safe becasue we do not use `mem::forget` anywhere.
let mut uart = unsafe {
uarte::Uarte::new(
uart,
interrupt::take!(UARTE0_UART0),
pins,
uarte::Parity::EXCLUDED,
uarte::Baudrate::BAUD115200,
)
};
info!("uarte initialized!");
// Message must be in SRAM
@ -81,36 +105,12 @@ fn main() -> ! {
unsafe { embassy::time::set_clock(rtc) };
let alarm = ALARM.put(rtc.alarm0());
let executor = EXECUTOR.put(Executor::new_with_alarm(alarm, cortex_m::asm::sev));
let executor = EXECUTOR.put(Executor::new());
executor.set_alarm(alarm);
// Init UART
let port0 = gpio::p0::Parts::new(p.P0);
let pins = uarte::Pins {
rxd: port0.p0_08.into_floating_input().degrade(),
txd: port0
.p0_06
.into_push_pull_output(gpio::Level::Low)
.degrade(),
cts: None,
rts: None,
};
// NOTE(unsafe): Safe becasue we do not use `mem::forget` anywhere.
let uart = unsafe {
uarte::Uarte::new(
p.UARTE0,
interrupt::take!(UARTE0_UART0),
pins,
uarte::Parity::EXCLUDED,
uarte::Baudrate::BAUD115200,
)
};
unwrap!(executor.spawn(run(uart)));
loop {
executor.run();
cortex_m::asm::wfe();
}
let uarte0 = p.UARTE0;
let p0 = p.P0;
executor.run(|spawner| {
unwrap!(spawner.spawn(run(uarte0, p0)));
});
}