mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-19 14:25:18 +01:00
added argument trampoline to hardware tasks to allow exception "masking"
Co-authored-by: Salon <salon64@users.noreply.github.com>
This commit is contained in:
parent
300ad99b74
commit
11d2ca9f2b
4 changed files with 79 additions and 26 deletions
|
|
@ -319,13 +319,13 @@ pub fn architecture_specific_analysis(app: &App, _: &SyntaxAnalysis) -> parse::R
|
|||
.filter(|prio| *prio > 0)
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
let need = priorities.len();
|
||||
let need_software = priorities.len();
|
||||
let given = app.args.dispatchers.len();
|
||||
if need > given {
|
||||
if need_software > given {
|
||||
let s = {
|
||||
format!(
|
||||
"not enough interrupts to dispatch \
|
||||
all software tasks (need: {need}; given: {given})"
|
||||
all software tasks (need: {need_software}; given: {given})"
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,26 +24,62 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
|||
let exit_stmts = interrupt_exit(app, analysis);
|
||||
let config = handler_config(app, analysis, symbol.clone());
|
||||
|
||||
mod_app.push(quote!(
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#(#attrs)*
|
||||
#(#cfgs)*
|
||||
#(#config)*
|
||||
unsafe fn #symbol() {
|
||||
#(#entry_stmts)*
|
||||
if let Some(trampoline) = &task.args.trampoline {
|
||||
let trampoline_symbol = trampoline.clone();
|
||||
mod_app.push(quote!(
|
||||
|
||||
const PRIORITY: u8 = #priority;
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#(#attrs)*
|
||||
#(#cfgs)*
|
||||
#(#config)*
|
||||
unsafe fn #symbol() {
|
||||
rtic::export::pend(rtic::export::Interrupt::#trampoline_symbol);
|
||||
}
|
||||
|
||||
rtic::export::run(PRIORITY, || {
|
||||
#name(
|
||||
#name::Context::new()
|
||||
)
|
||||
});
|
||||
|
||||
#(#exit_stmts)*
|
||||
}
|
||||
));
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#(#attrs)*
|
||||
#(#cfgs)*
|
||||
#(#config)*
|
||||
unsafe fn #trampoline_symbol() {
|
||||
#(#entry_stmts)*
|
||||
|
||||
const PRIORITY: u8 = #priority;
|
||||
|
||||
rtic::export::run(PRIORITY, || {
|
||||
#name(
|
||||
#name::Context::new()
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
#(#exit_stmts)*
|
||||
}
|
||||
));
|
||||
|
||||
} else {
|
||||
mod_app.push(quote!(
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#(#attrs)*
|
||||
#(#cfgs)*
|
||||
#(#config)*
|
||||
unsafe fn #symbol() {
|
||||
#(#entry_stmts)*
|
||||
|
||||
const PRIORITY: u8 = #priority;
|
||||
|
||||
rtic::export::run(PRIORITY, || {
|
||||
#name(
|
||||
#name::Context::new()
|
||||
)
|
||||
});
|
||||
|
||||
#(#exit_stmts)*
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
// `${task}Locals`
|
||||
if !task.args.local_resources.is_empty() {
|
||||
|
|
@ -51,7 +87,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
|||
local_resources_struct::codegen(Context::HardwareTask(name), app);
|
||||
|
||||
root.push(item);
|
||||
|
||||
mod_app.push(constructor);
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +96,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
|||
shared_resources_struct::codegen(Context::HardwareTask(name), app);
|
||||
|
||||
root.push(item);
|
||||
|
||||
mod_app.push(constructor);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -298,6 +298,9 @@ pub struct HardwareTaskArgs {
|
|||
/// The interrupt or exception that this task is bound to
|
||||
pub binds: Ident,
|
||||
|
||||
/// if set the bind would trampoline with the given interrupt handler
|
||||
pub trampoline: Option<Ident>,
|
||||
|
||||
/// The priority of this task
|
||||
pub priority: u8,
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
}
|
||||
|
||||
let mut binds = None;
|
||||
let mut trampoline = None;
|
||||
let mut priority = None;
|
||||
let mut shared_resources = None;
|
||||
let mut local_resources = None;
|
||||
|
|
@ -223,7 +224,21 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
let ident = input.parse()?;
|
||||
|
||||
binds = Some(ident);
|
||||
}
|
||||
},
|
||||
|
||||
"trampoline" => {
|
||||
if trampoline.is_some() {
|
||||
return Err(parse::Error::new(
|
||||
ident.span(),
|
||||
"argument appears more than once",
|
||||
));
|
||||
}
|
||||
|
||||
// Parse identifier name
|
||||
let ident: Ident = input.parse()?;
|
||||
|
||||
trampoline = Some(ident);
|
||||
},
|
||||
|
||||
"priority" => {
|
||||
if priority.is_some() {
|
||||
|
|
@ -277,8 +292,8 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
local_resources = Some(util::parse_local_resources(input)?);
|
||||
}
|
||||
|
||||
_ => {
|
||||
return Err(parse::Error::new(ident.span(), "unexpected argument"));
|
||||
a => {
|
||||
return Err(parse::Error::new(ident.span(), format!("unexpected argument {}", a)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,6 +323,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
|||
priority,
|
||||
shared_resources,
|
||||
local_resources,
|
||||
trampoline,
|
||||
})
|
||||
} else {
|
||||
// Software tasks start at idle priority
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue