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)
|
.filter(|prio| *prio > 0)
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
let need = priorities.len();
|
let need_software = priorities.len();
|
||||||
let given = app.args.dispatchers.len();
|
let given = app.args.dispatchers.len();
|
||||||
if need > given {
|
if need_software > given {
|
||||||
let s = {
|
let s = {
|
||||||
format!(
|
format!(
|
||||||
"not enough interrupts to dispatch \
|
"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 exit_stmts = interrupt_exit(app, analysis);
|
||||||
let config = handler_config(app, analysis, symbol.clone());
|
let config = handler_config(app, analysis, symbol.clone());
|
||||||
|
|
||||||
mod_app.push(quote!(
|
if let Some(trampoline) = &task.args.trampoline {
|
||||||
#[allow(non_snake_case)]
|
let trampoline_symbol = trampoline.clone();
|
||||||
#[no_mangle]
|
mod_app.push(quote!(
|
||||||
#(#attrs)*
|
|
||||||
#(#cfgs)*
|
|
||||||
#(#config)*
|
|
||||||
unsafe fn #symbol() {
|
|
||||||
#(#entry_stmts)*
|
|
||||||
|
|
||||||
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, || {
|
#[allow(non_snake_case)]
|
||||||
#name(
|
#[no_mangle]
|
||||||
#name::Context::new()
|
#(#attrs)*
|
||||||
)
|
#(#cfgs)*
|
||||||
});
|
#(#config)*
|
||||||
|
unsafe fn #trampoline_symbol() {
|
||||||
#(#exit_stmts)*
|
#(#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`
|
// `${task}Locals`
|
||||||
if !task.args.local_resources.is_empty() {
|
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);
|
local_resources_struct::codegen(Context::HardwareTask(name), app);
|
||||||
|
|
||||||
root.push(item);
|
root.push(item);
|
||||||
|
|
||||||
mod_app.push(constructor);
|
mod_app.push(constructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +96,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
|
||||||
shared_resources_struct::codegen(Context::HardwareTask(name), app);
|
shared_resources_struct::codegen(Context::HardwareTask(name), app);
|
||||||
|
|
||||||
root.push(item);
|
root.push(item);
|
||||||
|
|
||||||
mod_app.push(constructor);
|
mod_app.push(constructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,9 @@ pub struct HardwareTaskArgs {
|
||||||
/// The interrupt or exception that this task is bound to
|
/// The interrupt or exception that this task is bound to
|
||||||
pub binds: Ident,
|
pub binds: Ident,
|
||||||
|
|
||||||
|
/// if set the bind would trampoline with the given interrupt handler
|
||||||
|
pub trampoline: Option<Ident>,
|
||||||
|
|
||||||
/// The priority of this task
|
/// The priority of this task
|
||||||
pub priority: u8,
|
pub priority: u8,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut binds = None;
|
let mut binds = None;
|
||||||
|
let mut trampoline = None;
|
||||||
let mut priority = None;
|
let mut priority = None;
|
||||||
let mut shared_resources = None;
|
let mut shared_resources = None;
|
||||||
let mut local_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()?;
|
let ident = input.parse()?;
|
||||||
|
|
||||||
binds = Some(ident);
|
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" => {
|
"priority" => {
|
||||||
if priority.is_some() {
|
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)?);
|
local_resources = Some(util::parse_local_resources(input)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
a => {
|
||||||
return Err(parse::Error::new(ident.span(), "unexpected argument"));
|
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,
|
priority,
|
||||||
shared_resources,
|
shared_resources,
|
||||||
local_resources,
|
local_resources,
|
||||||
|
trampoline,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Software tasks start at idle priority
|
// Software tasks start at idle priority
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue