Skip to content

Commit 8fb038b

Browse files
Olle Ronstadsalon64
andcommitted
added argument trampoline to hardware tasks to allow exception "masking"
Co-authored-by: Salon <[email protected]>
1 parent 300ad99 commit 8fb038b

File tree

4 files changed

+110
-28
lines changed

4 files changed

+110
-28
lines changed

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,35 @@ fn is_exception(name: &Ident) -> bool {
3030
)
3131
}
3232

33+
// pub fn is_static_prio(bind: &Ident) -> bool {
34+
// // Backend-specific logic to determine if this exception/interrupt has static priority
35+
// let s = bind.to_string();
36+
// #[cfg(feature = "cortex-m0")]
37+
// return matches!(&*s,
38+
// "NonMaskableInt"
39+
// | "HardFault"
40+
// | "MemoryManagement"
41+
// | "BusFault"
42+
// | "UsageFault"
43+
// | "SecureFault"
44+
// );
45+
// #[cfg(not(any(feature = "cortex-m0")))]
46+
// compile_error!("Unsupported cpu");
47+
// }
48+
49+
// pub fn is_maskable(bind: &Ident) -> bool {
50+
// // Backend-specific logic to determine if this exception/interrupt can be masked
51+
// let s = bind.to_string();
52+
// matches!(&*s,
53+
// "NonMaskableInt"
54+
// | "HardFault"
55+
// | "MemoryManagement"
56+
// | "BusFault"
57+
// | "UsageFault"
58+
// | "SecureFault"
59+
// )
60+
// }
61+
3362
pub fn interrupt_ident() -> Ident {
3463
let span = Span::call_site();
3564
Ident::new("interrupt", span)
@@ -319,13 +348,13 @@ pub fn architecture_specific_analysis(app: &App, _: &SyntaxAnalysis) -> parse::R
319348
.filter(|prio| *prio > 0)
320349
.collect::<HashSet<_>>();
321350

322-
let need = priorities.len();
351+
let need_software = priorities.len();
323352
let given = app.args.dispatchers.len();
324-
if need > given {
353+
if need_software > given {
325354
let s = {
326355
format!(
327356
"not enough interrupts to dispatch \
328-
all software tasks (need: {need}; given: {given})"
357+
all software tasks (need: {need_software}; given: {given})"
329358
)
330359
};
331360

rtic-macros/src/codegen/hardware_tasks.rs

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,69 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
2424
let exit_stmts = interrupt_exit(app, analysis);
2525
let config = handler_config(app, analysis, symbol.clone());
2626

27-
mod_app.push(quote!(
28-
#[allow(non_snake_case)]
29-
#[no_mangle]
30-
#(#attrs)*
31-
#(#cfgs)*
32-
#(#config)*
33-
unsafe fn #symbol() {
34-
#(#entry_stmts)*
35-
36-
const PRIORITY: u8 = #priority;
37-
38-
rtic::export::run(PRIORITY, || {
39-
#name(
40-
#name::Context::new()
41-
)
42-
});
43-
44-
#(#exit_stmts)*
45-
}
46-
));
27+
if let Some(trampoline) = &task.args.trampoline {
28+
let trampoline_symbol = trampoline.clone();
29+
mod_app.push(quote!(
30+
31+
#[allow(non_snake_case)]
32+
#[no_mangle]
33+
#(#attrs)*
34+
#(#cfgs)*
35+
#(#config)*
36+
unsafe fn #symbol() {
37+
rtic::export::pend(rtic::export::Interrupt::#trampoline_symbol);
38+
}
39+
40+
#[allow(non_snake_case)]
41+
#[no_mangle]
42+
#(#attrs)*
43+
#(#cfgs)*
44+
#(#config)*
45+
unsafe fn #trampoline_symbol() {
46+
#(#entry_stmts)*
47+
48+
const PRIORITY: u8 = #priority;
49+
50+
rtic::export::run(PRIORITY, || {
51+
#name(
52+
#name::Context::new()
53+
)
54+
});
55+
56+
57+
#(#exit_stmts)*
58+
}
59+
));
60+
61+
} else {
62+
mod_app.push(quote!(
63+
#[allow(non_snake_case)]
64+
#[no_mangle]
65+
#(#attrs)*
66+
#(#cfgs)*
67+
#(#config)*
68+
unsafe fn #symbol() {
69+
#(#entry_stmts)*
70+
71+
const PRIORITY: u8 = #priority;
72+
73+
rtic::export::run(PRIORITY, || {
74+
#name(
75+
#name::Context::new()
76+
)
77+
});
78+
79+
#(#exit_stmts)*
80+
}
81+
));
82+
}
4783

4884
// `${task}Locals`
4985
if !task.args.local_resources.is_empty() {
5086
let (item, constructor) =
5187
local_resources_struct::codegen(Context::HardwareTask(name), app);
5288

5389
root.push(item);
54-
5590
mod_app.push(constructor);
5691
}
5792

@@ -61,7 +96,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
6196
shared_resources_struct::codegen(Context::HardwareTask(name), app);
6297

6398
root.push(item);
64-
6599
mod_app.push(constructor);
66100
}
67101

rtic-macros/src/syntax/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ pub struct HardwareTaskArgs {
298298
/// The interrupt or exception that this task is bound to
299299
pub binds: Ident,
300300

301+
/// if set the bind would trampoline with the given interrupt handler
302+
pub trampoline: Option<Ident>,
303+
301304
/// The priority of this task
302305
pub priority: u8,
303306

rtic-macros/src/syntax/parse.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
193193
}
194194

195195
let mut binds = None;
196+
let mut trampoline = None;
196197
let mut priority = None;
197198
let mut shared_resources = None;
198199
let mut local_resources = None;
@@ -223,7 +224,21 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
223224
let ident = input.parse()?;
224225

225226
binds = Some(ident);
226-
}
227+
},
228+
229+
"trampoline" => {
230+
if trampoline.is_some() {
231+
return Err(parse::Error::new(
232+
ident.span(),
233+
"argument appears more than once",
234+
));
235+
}
236+
237+
// Parse identifier name
238+
let ident: Ident = input.parse()?;
239+
240+
trampoline = Some(ident);
241+
},
227242

228243
"priority" => {
229244
if priority.is_some() {
@@ -277,8 +292,8 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
277292
local_resources = Some(util::parse_local_resources(input)?);
278293
}
279294

280-
_ => {
281-
return Err(parse::Error::new(ident.span(), "unexpected argument"));
295+
a => {
296+
return Err(parse::Error::new(ident.span(), format!("unexpected argument {}", a)));
282297
}
283298
}
284299

@@ -308,6 +323,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
308323
priority,
309324
shared_resources,
310325
local_resources,
326+
trampoline,
311327
})
312328
} else {
313329
// Software tasks start at idle priority

0 commit comments

Comments
 (0)