mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-19 14:25:18 +01:00
continued work on rtic trampoline
Co-authored-by: Salon <salon64@users.noreply.github.com>
This commit is contained in:
parent
936dfc51e9
commit
ccddee6198
4 changed files with 107 additions and 4 deletions
6
ci/expected/lm3s6965/trampoline.run
Normal file
6
ci/expected/lm3s6965/trampoline.run
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
gpioa lock
|
||||
gpioa unlock
|
||||
SysTick start
|
||||
idle
|
||||
SysTick start
|
||||
idle end
|
||||
65
examples/lm3s6965/examples/trampoline.rs
Normal file
65
examples/lm3s6965/examples/trampoline.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//! examples/bouncy_trampoline.rs
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![deny(warnings)]
|
||||
#![deny(unsafe_code)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use panic_semihosting as _;
|
||||
|
||||
// `examples/bouncy_trampoline.rs` testing trampoline feature
|
||||
#[rtic::app(device = lm3s6965)]
|
||||
mod app {
|
||||
use cortex_m_semihosting::{debug, hprintln};
|
||||
use lm3s6965::Interrupt;
|
||||
|
||||
#[shared]
|
||||
struct Shared {
|
||||
h_priority: u8,
|
||||
}
|
||||
|
||||
#[local]
|
||||
struct Local {}
|
||||
|
||||
#[init]
|
||||
fn init(_: init::Context) -> (Shared, Local) {
|
||||
// Trigger SW0 interrupt to test NMI preemption
|
||||
rtic::pend(Interrupt::GPIOA);
|
||||
(Shared { h_priority: 0 }, Local {})
|
||||
}
|
||||
|
||||
#[idle]
|
||||
fn idle(_: idle::Context) -> ! {
|
||||
hprintln!("idle");
|
||||
|
||||
// pend another interrupt to test trampoline
|
||||
cortex_m::peripheral::SCB::set_pendst();
|
||||
hprintln!("idle end");
|
||||
|
||||
debug::exit(debug::EXIT_SUCCESS);
|
||||
loop {
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
|
||||
#[task(binds = SysTick, trampoline = GPIOC, priority = 2, shared = [h_priority])]
|
||||
fn sys_tick(_: sys_tick::Context) {
|
||||
hprintln!("SysTick start");
|
||||
}
|
||||
|
||||
#[task(binds = GPIOA, priority = 1, shared = [h_priority])]
|
||||
fn gpioa(mut ctx: gpioa::Context) {
|
||||
ctx.shared.h_priority.lock(|_| {
|
||||
hprintln!("gpioa lock");
|
||||
cortex_m::peripheral::SCB::set_pendst();
|
||||
cortex_m::asm::delay(100_000_000);
|
||||
hprintln!("gpioa unlock");
|
||||
});
|
||||
}
|
||||
|
||||
#[task(binds = GPIOB, priority = 3, shared = [h_priority])]
|
||||
fn high_priority_task(_: high_priority_task::Context) {
|
||||
hprintln!("High priority task");
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +102,20 @@ mod source_masking {
|
|||
} else {
|
||||
None
|
||||
}
|
||||
})) {
|
||||
})
|
||||
// Add trampoline tasks if present and not exceptions
|
||||
.chain(app.hardware_tasks.values().filter_map(|task| {
|
||||
if let Some(trampoline) = &task.args.trampoline {
|
||||
if !is_exception(trampoline) {
|
||||
Some((&task.args.priority, trampoline))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}))
|
||||
) {
|
||||
let v: &mut Vec<_> = prio_to_masks.entry(priority - 1).or_default();
|
||||
v.push(quote!(#device::Interrupt::#name as u32));
|
||||
mask_ids.push(quote!(#device::Interrupt::#name as u32));
|
||||
|
|
@ -245,7 +258,7 @@ pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<
|
|||
if let Some(trampoline) = &task.args.trampoline {
|
||||
if is_exception(trampoline) {
|
||||
// We do exceptions in another pass
|
||||
return None;
|
||||
None
|
||||
} else {
|
||||
// If there's a trampoline, we need to unmask and set priority for it too
|
||||
Some((&task.args.priority, trampoline))
|
||||
|
|
@ -362,6 +375,27 @@ pub fn architecture_specific_analysis(app: &App, _: &SyntaxAnalysis) -> parse::R
|
|||
}
|
||||
}
|
||||
|
||||
// Check that a exception is not used with shared resources
|
||||
// TODO provide warning when a exception is used with source masking since it then ignores locks in priority ceilings
|
||||
#[cfg(feature = "cortex-m-source-masking")]
|
||||
for (name, task) in &app.hardware_tasks {
|
||||
if is_exception(name) && !app.shared_resources.is_empty(){
|
||||
if let Some(trampoline) = task.args.trampoline.as_ref() {
|
||||
if is_exception(trampoline) {
|
||||
return Err(parse::Error::new(
|
||||
trampoline.span(),
|
||||
"cannot use exceptions as trampoline tasks when using source masking",
|
||||
));
|
||||
}
|
||||
} else {
|
||||
return Err(parse::Error::new(
|
||||
name.span(),
|
||||
"cannot use exceptions with shared resources as hardware tasks when using source masking, consider adding the trampoline attribute",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,10 +38,8 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
|||
#(#cfgs)*
|
||||
#(#config)*
|
||||
unsafe fn #symbol() {
|
||||
info!("Pend trampoline");
|
||||
use #rt_err::Interrupt;
|
||||
rtic::pend(Interrupt::#trampoline_symbol);
|
||||
info!("Exit trampoline handler");
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue