Skip to content

Commit 2c8f338

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

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
@@ -131,7 +131,20 @@ mod source_masking {
131131
} else {
132132
None
133133
}
134-
})) {
134+
})
135+
// Add trampoline tasks if present and not exceptions
136+
.chain(app.hardware_tasks.values().filter_map(|task| {
137+
if let Some(trampoline) = &task.args.trampoline {
138+
if !is_exception(trampoline) {
139+
Some((&task.args.priority, trampoline))
140+
} else {
141+
None
142+
}
143+
} else {
144+
None
145+
}
146+
}))
147+
) {
135148
let v: &mut Vec<_> = prio_to_masks.entry(priority - 1).or_default();
136149
v.push(quote!(#device::Interrupt::#name as u32));
137150
mask_ids.push(quote!(#device::Interrupt::#name as u32));
@@ -274,7 +287,7 @@ pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<
274287
if let Some(trampoline) = &task.args.trampoline {
275288
if is_exception(trampoline) {
276289
// We do exceptions in another pass
277-
return None;
290+
None
278291
} else {
279292
// If there's a trampoline, we need to unmask and set priority for it too
280293
Some((&task.args.priority, trampoline))
@@ -391,6 +404,27 @@ pub fn architecture_specific_analysis(app: &App, _: &SyntaxAnalysis) -> parse::R
391404
}
392405
}
393406

407+
// Check that a exception is not used with shared resources
408+
// TODO provide warning when a exception is used with source masking since it then ignores locks in priority ceilings
409+
#[cfg(feature = "cortex-m-source-masking")]
410+
for (name, task) in &app.hardware_tasks {
411+
if is_exception(name) && !app.shared_resources.is_empty(){
412+
if let Some(trampoline) = task.args.trampoline.as_ref() {
413+
if is_exception(trampoline) {
414+
return Err(parse::Error::new(
415+
trampoline.span(),
416+
"cannot use exceptions as trampoline tasks when using source masking",
417+
));
418+
}
419+
} else {
420+
return Err(parse::Error::new(
421+
name.span(),
422+
"cannot use exceptions with shared resources as hardware tasks when using source masking, consider adding the trampoline attribute",
423+
));
424+
}
425+
}
426+
}
427+
394428
Ok(())
395429
}
396430

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)