mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
properly handle #[cfg]
(conditional compilation) on tasks
This commit is contained in:
parent
4345c10596
commit
8e9a91d0b0
4 changed files with 72 additions and 20 deletions
|
@ -73,7 +73,8 @@ pub fn app(app: &App) -> parse::Result<()> {
|
||||||
app.tasks
|
app.tasks
|
||||||
.values()
|
.values()
|
||||||
.flat_map(|t| t.args.schedule.iter().chain(&t.args.spawn)),
|
.flat_map(|t| t.args.schedule.iter().chain(&t.args.spawn)),
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
if !app.tasks.contains_key(task) {
|
if !app.tasks.contains_key(task) {
|
||||||
return Err(parse::Error::new(
|
return Err(parse::Error::new(
|
||||||
task.span(),
|
task.span(),
|
||||||
|
|
|
@ -1210,7 +1210,6 @@ fn tasks(ctxt: &mut Context, app: &App, analysis: &Analysis) -> proc_macro2::Tok
|
||||||
|
|
||||||
// second pass to generate the actual task function
|
// second pass to generate the actual task function
|
||||||
for (name, task) in &app.tasks {
|
for (name, task) in &app.tasks {
|
||||||
let attrs = &task.attrs;
|
|
||||||
let inputs = &task.inputs;
|
let inputs = &task.inputs;
|
||||||
let locals = mk_locals(&task.statics, false);
|
let locals = mk_locals(&task.statics, false);
|
||||||
let stmts = &task.stmts;
|
let stmts = &task.stmts;
|
||||||
|
@ -1245,6 +1244,8 @@ fn tasks(ctxt: &mut Context, app: &App, analysis: &Analysis) -> proc_macro2::Tok
|
||||||
app,
|
app,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let attrs = &task.attrs;
|
||||||
|
let cfgs = &task.cfgs;
|
||||||
let task_alias = &ctxt.tasks[name].alias;
|
let task_alias = &ctxt.tasks[name].alias;
|
||||||
let baseline_arg = match () {
|
let baseline_arg = match () {
|
||||||
#[cfg(feature = "timer-queue")]
|
#[cfg(feature = "timer-queue")]
|
||||||
|
@ -1257,6 +1258,7 @@ fn tasks(ctxt: &mut Context, app: &App, analysis: &Analysis) -> proc_macro2::Tok
|
||||||
};
|
};
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#(#attrs)*
|
#(#attrs)*
|
||||||
|
#(#cfgs)*
|
||||||
#unsafety fn #task_alias(#baseline_arg #(#inputs,)*) {
|
#unsafety fn #task_alias(#baseline_arg #(#inputs,)*) {
|
||||||
#(#locals)*
|
#(#locals)*
|
||||||
|
|
||||||
|
@ -1284,9 +1286,21 @@ fn dispatchers(
|
||||||
for (level, dispatcher) in &analysis.dispatchers {
|
for (level, dispatcher) in &analysis.dispatchers {
|
||||||
let ready_alias = mk_ident(None);
|
let ready_alias = mk_ident(None);
|
||||||
let enum_alias = mk_ident(None);
|
let enum_alias = mk_ident(None);
|
||||||
let tasks = &dispatcher.tasks;
|
|
||||||
let capacity = mk_typenum_capacity(dispatcher.capacity, true);
|
let capacity = mk_typenum_capacity(dispatcher.capacity, true);
|
||||||
|
|
||||||
|
let variants = dispatcher
|
||||||
|
.tasks
|
||||||
|
.iter()
|
||||||
|
.map(|task| {
|
||||||
|
let task_ = &app.tasks[task];
|
||||||
|
let cfgs = &task_.cfgs;
|
||||||
|
|
||||||
|
quote!(
|
||||||
|
#(#cfgs)*
|
||||||
|
#task
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let symbol = format!("P{}::READY_QUEUE::{}", level, ready_alias);
|
let symbol = format!("P{}::READY_QUEUE::{}", level, ready_alias);
|
||||||
let e = quote!(rtfm::export);
|
let e = quote!(rtfm::export);
|
||||||
let ty = quote!(#e::ReadyQueue<#enum_alias, #capacity>);
|
let ty = quote!(#e::ReadyQueue<#enum_alias, #capacity>);
|
||||||
|
@ -1304,7 +1318,7 @@ fn dispatchers(
|
||||||
data.push(quote!(
|
data.push(quote!(
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
enum #enum_alias { #(#tasks,)* }
|
enum #enum_alias { #(#variants,)* }
|
||||||
|
|
||||||
#[doc = #symbol]
|
#[doc = #symbol]
|
||||||
static mut #ready_alias: #e::MaybeUninit<#ty> = #e::MaybeUninit::uninitialized();
|
static mut #ready_alias: #e::MaybeUninit<#ty> = #e::MaybeUninit::uninitialized();
|
||||||
|
@ -1319,9 +1333,12 @@ fn dispatchers(
|
||||||
let task_ = &ctxt.tasks[task];
|
let task_ = &ctxt.tasks[task];
|
||||||
let inputs = &task_.inputs;
|
let inputs = &task_.inputs;
|
||||||
let free = &task_.free_queue;
|
let free = &task_.free_queue;
|
||||||
let pats = tuple_pat(&app.tasks[task].inputs);
|
|
||||||
let alias = &task_.alias;
|
let alias = &task_.alias;
|
||||||
|
|
||||||
|
let task__ = &app.tasks[task];
|
||||||
|
let pats = tuple_pat(&task__.inputs);
|
||||||
|
let cfgs = &task__.cfgs;
|
||||||
|
|
||||||
let baseline_let;
|
let baseline_let;
|
||||||
let call;
|
let call;
|
||||||
match () {
|
match () {
|
||||||
|
@ -1341,13 +1358,16 @@ fn dispatchers(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
quote!(#enum_alias::#task => {
|
quote!(
|
||||||
#baseline_let
|
#(#cfgs)*
|
||||||
let input = ptr::read(#inputs.get_ref().get_unchecked(usize::from(index)));
|
#enum_alias::#task => {
|
||||||
#free.get_mut().split().0.enqueue_unchecked(index);
|
#baseline_let
|
||||||
let (#pats) = input;
|
let input = ptr::read(#inputs.get_ref().get_unchecked(usize::from(index)));
|
||||||
#call
|
#free.get_mut().split().0.enqueue_unchecked(index);
|
||||||
})
|
let (#pats) = input;
|
||||||
|
#call
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -1397,6 +1417,7 @@ fn spawn(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::TokenSt
|
||||||
for (name, task) in &ctxt.tasks {
|
for (name, task) in &ctxt.tasks {
|
||||||
let alias = &task.spawn_fn;
|
let alias = &task.spawn_fn;
|
||||||
let task_ = &app.tasks[name];
|
let task_ = &app.tasks[name];
|
||||||
|
let cfgs = &task_.cfgs;
|
||||||
let free = &task.free_queue;
|
let free = &task.free_queue;
|
||||||
let level = task_.args.priority;
|
let level = task_.args.priority;
|
||||||
let dispatcher = &ctxt.dispatchers[&level];
|
let dispatcher = &ctxt.dispatchers[&level];
|
||||||
|
@ -1432,6 +1453,7 @@ fn spawn(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::TokenSt
|
||||||
|
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#(#cfgs)*
|
||||||
unsafe fn #alias(
|
unsafe fn #alias(
|
||||||
#baseline_arg
|
#baseline_arg
|
||||||
#priority: &core::cell::Cell<u8>,
|
#priority: &core::cell::Cell<u8>,
|
||||||
|
@ -1470,8 +1492,10 @@ fn spawn(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::TokenSt
|
||||||
|
|
||||||
let mut methods = vec![];
|
let mut methods = vec![];
|
||||||
for task in spawn {
|
for task in spawn {
|
||||||
|
let task_ = &app.tasks[task];
|
||||||
let alias = &ctxt.tasks[task].spawn_fn;
|
let alias = &ctxt.tasks[task].spawn_fn;
|
||||||
let inputs = &app.tasks[task].inputs;
|
let inputs = &task_.inputs;
|
||||||
|
let cfgs = &task_.cfgs;
|
||||||
let ty = tuple_ty(inputs);
|
let ty = tuple_ty(inputs);
|
||||||
let pats = tuple_pat(inputs);
|
let pats = tuple_pat(inputs);
|
||||||
|
|
||||||
|
@ -1490,6 +1514,7 @@ fn spawn(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::TokenSt
|
||||||
methods.push(quote!(
|
methods.push(quote!(
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#(#cfgs)*
|
||||||
pub fn #task(&self, #(#inputs,)*) -> Result<(), #ty> {
|
pub fn #task(&self, #(#inputs,)*) -> Result<(), #ty> {
|
||||||
unsafe { #alias(#instant &self.#priority, #pats) }
|
unsafe { #alias(#instant &self.#priority, #pats) }
|
||||||
}
|
}
|
||||||
|
@ -1519,12 +1544,15 @@ fn schedule(ctxt: &Context, app: &App) -> proc_macro2::TokenStream {
|
||||||
let enum_ = &ctxt.schedule_enum;
|
let enum_ = &ctxt.schedule_enum;
|
||||||
let inputs = &task_.inputs;
|
let inputs = &task_.inputs;
|
||||||
let scheduleds = &task_.scheduleds;
|
let scheduleds = &task_.scheduleds;
|
||||||
let args = &app.tasks[task].inputs;
|
let task__ = &app.tasks[task];
|
||||||
|
let args = &task__.inputs;
|
||||||
|
let cfgs = &task__.cfgs;
|
||||||
let ty = tuple_ty(args);
|
let ty = tuple_ty(args);
|
||||||
let pats = tuple_pat(args);
|
let pats = tuple_pat(args);
|
||||||
|
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#(#cfgs)*
|
||||||
unsafe fn #alias(
|
unsafe fn #alias(
|
||||||
#priority: &core::cell::Cell<u8>,
|
#priority: &core::cell::Cell<u8>,
|
||||||
instant: rtfm::Instant,
|
instant: rtfm::Instant,
|
||||||
|
@ -1568,12 +1596,15 @@ fn schedule(ctxt: &Context, app: &App) -> proc_macro2::TokenStream {
|
||||||
let mut methods = vec![];
|
let mut methods = vec![];
|
||||||
for task in schedule {
|
for task in schedule {
|
||||||
let alias = &ctxt.schedule_fn[task];
|
let alias = &ctxt.schedule_fn[task];
|
||||||
let inputs = &app.tasks[task].inputs;
|
let task_ = &app.tasks[task];
|
||||||
|
let inputs = &task_.inputs;
|
||||||
|
let cfgs = &task_.cfgs;
|
||||||
let ty = tuple_ty(inputs);
|
let ty = tuple_ty(inputs);
|
||||||
let pats = tuple_pat(inputs);
|
let pats = tuple_pat(inputs);
|
||||||
|
|
||||||
methods.push(quote!(
|
methods.push(quote!(
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#(#cfgs)*
|
||||||
pub fn #task(
|
pub fn #task(
|
||||||
&self,
|
&self,
|
||||||
instant: rtfm::Instant,
|
instant: rtfm::Instant,
|
||||||
|
@ -1603,12 +1634,22 @@ fn timer_queue(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::T
|
||||||
|
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
|
|
||||||
|
let variants = tasks
|
||||||
|
.iter()
|
||||||
|
.map(|task| {
|
||||||
|
let cfgs = &app.tasks[task].cfgs;
|
||||||
|
quote!(
|
||||||
|
#(#cfgs)*
|
||||||
|
#task
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let enum_ = &ctxt.schedule_enum;
|
let enum_ = &ctxt.schedule_enum;
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum #enum_ { #(#tasks,)* }
|
enum #enum_ { #(#variants,)* }
|
||||||
));
|
));
|
||||||
|
|
||||||
let cap = mk_typenum_capacity(analysis.timer_queue.capacity, false);
|
let cap = mk_typenum_capacity(analysis.timer_queue.capacity, false);
|
||||||
|
@ -1637,13 +1678,16 @@ fn timer_queue(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::T
|
||||||
let arms = tasks
|
let arms = tasks
|
||||||
.iter()
|
.iter()
|
||||||
.map(|task| {
|
.map(|task| {
|
||||||
let level = app.tasks[task].args.priority;
|
let task_ = &app.tasks[task];
|
||||||
|
let level = task_.args.priority;
|
||||||
|
let cfgs = &task_.cfgs;
|
||||||
let dispatcher_ = &ctxt.dispatchers[&level];
|
let dispatcher_ = &ctxt.dispatchers[&level];
|
||||||
let tenum = &dispatcher_.enum_;
|
let tenum = &dispatcher_.enum_;
|
||||||
let ready = &dispatcher_.ready_queue;
|
let ready = &dispatcher_.ready_queue;
|
||||||
let dispatcher = &analysis.dispatchers[&level].interrupt;
|
let dispatcher = &analysis.dispatchers[&level].interrupt;
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
|
#(#cfgs)*
|
||||||
#enum_::#task => {
|
#enum_::#task => {
|
||||||
(#ready { #priority }).lock(|rq| {
|
(#ready { #priority }).lock(|rq| {
|
||||||
rq.split().0.enqueue_unchecked((#tenum::#task, index))
|
rq.split().0.enqueue_unchecked((#tenum::#task, index))
|
||||||
|
|
|
@ -1047,6 +1047,7 @@ impl Static {
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub args: TaskArgs,
|
pub args: TaskArgs,
|
||||||
|
pub cfgs: Vec<Attribute>,
|
||||||
pub attrs: Vec<Attribute>,
|
pub attrs: Vec<Attribute>,
|
||||||
pub unsafety: Option<Token![unsafe]>,
|
pub unsafety: Option<Token![unsafe]>,
|
||||||
pub inputs: Vec<ArgCaptured>,
|
pub inputs: Vec<ArgCaptured>,
|
||||||
|
@ -1098,9 +1099,11 @@ impl Task {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (cfgs, attrs) = extract_cfgs(item.attrs);
|
||||||
Ok(Task {
|
Ok(Task {
|
||||||
args,
|
args,
|
||||||
attrs: item.attrs,
|
cfgs,
|
||||||
|
attrs,
|
||||||
unsafety: item.unsafety,
|
unsafety: item.unsafety,
|
||||||
inputs,
|
inputs,
|
||||||
statics: Static::parse(statics)?,
|
statics: Static::parse(statics)?,
|
||||||
|
|
|
@ -30,18 +30,22 @@ const APP: () = {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(resources = [FOO])]
|
#[task(resources = [FOO], schedule = [quux], spawn = [quux])]
|
||||||
fn foo() {
|
fn foo() {
|
||||||
#[cfg(never)]
|
#[cfg(never)]
|
||||||
static mut BAR: u32 = 0;
|
static mut BAR: u32 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(priority = 3, resources = [FOO])]
|
#[task(priority = 3, resources = [FOO], schedule = [quux], spawn = [quux])]
|
||||||
fn bar() {
|
fn bar() {
|
||||||
#[cfg(never)]
|
#[cfg(never)]
|
||||||
static mut BAR: u32 = 0;
|
static mut BAR: u32 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(never)]
|
||||||
|
#[task]
|
||||||
|
fn quux() {}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn UART0();
|
fn UART0();
|
||||||
fn UART1();
|
fn UART1();
|
||||||
|
|
Loading…
Reference in a new issue