Skip to content

Commit ccddee6

Browse files
Olle Ronstadsalon64
andcommitted
continued work on rtic trampoline
Co-authored-by: Salon <[email protected]>
1 parent 936dfc5 commit ccddee6

File tree

4 files changed

+107
-4
lines changed

4 files changed

+107
-4
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
gpioa lock
2+
gpioa unlock
3+
SysTick start
4+
idle
5+
SysTick start
6+
idle end
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//! examples/bouncy_trampoline.rs
2+
3+
#![no_std]
4+
#![no_main]
5+
#![deny(warnings)]
6+
#![deny(unsafe_code)]
7+
#![deny(missing_docs)]
8+
9+
use panic_semihosting as _;
10+
11+
// `examples/bouncy_trampoline.rs` testing trampoline feature
12+
#[rtic::app(device = lm3s6965)]
13+
mod app {
14+
use cortex_m_semihosting::{debug, hprintln};
15+
use lm3s6965::Interrupt;
16+
17+
#[shared]
18+
struct Shared {
19+
h_priority: u8,
20+
}
21+
22+
#[local]
23+
struct Local {}
24+
25+
#[init]
26+
fn init(_: init::Context) -> (Shared, Local) {
27+
// Trigger SW0 interrupt to test NMI preemption
28+
rtic::pend(Interrupt::GPIOA);
29+
(Shared { h_priority: 0 }, Local {})
30+
}
31+
32+
#[idle]
33+
fn idle(_: idle::Context) -> ! {
34+
hprintln!("idle");
35+
36+
// pend another interrupt to test trampoline
37+
cortex_m::peripheral::SCB::set_pendst();
38+
hprintln!("idle end");
39+
40+
debug::exit(debug::EXIT_SUCCESS);
41+
loop {
42+
cortex_m::asm::wfi();
43+
}
44+
}
45+
46+
#[task(binds = SysTick, trampoline = GPIOC, priority = 2, shared = [h_priority])]
47+
fn sys_tick(_: sys_tick::Context) {
48+
hprintln!("SysTick start");
49+
}
50+
51+
#[task(binds = GPIOA, priority = 1, shared = [h_priority])]
52+
fn gpioa(mut ctx: gpioa::Context) {
53+
ctx.shared.h_priority.lock(|_| {
54+
hprintln!("gpioa lock");
55+
cortex_m::peripheral::SCB::set_pendst();
56+
cortex_m::asm::delay(100_000_000);
57+
hprintln!("gpioa unlock");
58+
});
59+
}
60+
61+
#[task(binds = GPIOB, priority = 3, shared = [h_priority])]
62+
fn high_priority_task(_: high_priority_task::Context) {
63+
hprintln!("High priority task");
64+
}
65+
}

rtic-macros/src/codegen/bindings/cortex.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,20 @@ mod source_masking {
102102
} else {
103103
None
104104
}
105-
})) {
105+
})
106+
// Add trampoline tasks if present and not exceptions
107+
.chain(app.hardware_tasks.values().filter_map(|task| {
108+
if let Some(trampoline) = &task.args.trampoline {
109+
if !is_exception(trampoline) {
110+
Some((&task.args.priority, trampoline))
111+
} else {
112+
None
113+
}
114+
} else {
115+
None
116+
}
117+
}))
118+
) {
106119
let v: &mut Vec<_> = prio_to_masks.entry(priority - 1).or_default();
107120
v.push(quote!(#device::Interrupt::#name as u32));
108121
mask_ids.push(quote!(#device::Interrupt::#name as u32));
@@ -245,7 +258,7 @@ pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<
245258
if let Some(trampoline) = &task.args.trampoline {
246259
if is_exception(trampoline) {
247260
// We do exceptions in another pass
248-
return None;
261+
None
249262
} else {
250263
// If there's a trampoline, we need to unmask and set priority for it too
251264
Some((&task.args.priority, trampoline))
@@ -362,6 +375,27 @@ pub fn architecture_specific_analysis(app: &App, _: &SyntaxAnalysis) -> parse::R
362375
}
363376
}
364377

378+
// Check that a exception is not used with shared resources
379+
// TODO provide warning when a exception is used with source masking since it then ignores locks in priority ceilings
380+
#[cfg(feature = "cortex-m-source-masking")]
381+
for (name, task) in &app.hardware_tasks {
382+
if is_exception(name) && !app.shared_resources.is_empty(){
383+
if let Some(trampoline) = task.args.trampoline.as_ref() {
384+
if is_exception(trampoline) {
385+
return Err(parse::Error::new(
386+
trampoline.span(),
387+
"cannot use exceptions as trampoline tasks when using source masking",
388+
));
389+
}
390+
} else {
391+
return Err(parse::Error::new(
392+
name.span(),
393+
"cannot use exceptions with shared resources as hardware tasks when using source masking, consider adding the trampoline attribute",
394+
));
395+
}
396+
}
397+
}
398+
365399
Ok(())
366400
}
367401

rtic-macros/src/codegen/hardware_tasks.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
3838
#(#cfgs)*
3939
#(#config)*
4040
unsafe fn #symbol() {
41-
info!("Pend trampoline");
4241
use #rt_err::Interrupt;
4342
rtic::pend(Interrupt::#trampoline_symbol);
44-
info!("Exit trampoline handler");
4543
}
4644

4745
#[allow(non_snake_case)]

0 commit comments

Comments
 (0)