mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-26 05:29:38 +01:00
task! is not needed if tasks.$T.path is specified
This commit is contained in:
parent
74daa77fe0
commit
fb4542818b
3 changed files with 120 additions and 54 deletions
|
@ -18,6 +18,7 @@ pub type Tasks = HashMap<Ident, Task>;
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub enabled: Option<bool>,
|
pub enabled: Option<bool>,
|
||||||
|
pub path: Option<Path>,
|
||||||
pub priority: u8,
|
pub priority: u8,
|
||||||
pub resources: Idents,
|
pub resources: Idents,
|
||||||
}
|
}
|
||||||
|
@ -71,6 +72,7 @@ fn task(task: syntax::check::Task) -> Result<Task> {
|
||||||
if let Some(priority) = task.priority {
|
if let Some(priority) = task.priority {
|
||||||
Ok(Task {
|
Ok(Task {
|
||||||
enabled: task.enabled,
|
enabled: task.enabled,
|
||||||
|
path: task.path,
|
||||||
priority,
|
priority,
|
||||||
resources: task.resources,
|
resources: task.resources,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use quote::{Ident, Tokens};
|
use quote::{Ident, Tokens};
|
||||||
|
use syn::{Lit, StrStyle};
|
||||||
|
|
||||||
use analyze::{Ownership, Ownerships};
|
use analyze::{Ownership, Ownerships};
|
||||||
use check::App;
|
use check::App;
|
||||||
|
@ -497,89 +498,148 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
|
||||||
|
|
||||||
let mut lifetime = None;
|
let mut lifetime = None;
|
||||||
let mut needs_reexport = false;
|
let mut needs_reexport = false;
|
||||||
for name in &task.resources {
|
let mut needs_threshold = false;
|
||||||
match ownerships[name] {
|
let has_resources = !task.resources.is_empty();
|
||||||
Ownership::Shared { ceiling } if ceiling > task.priority => {
|
|
||||||
fields.push(quote! {
|
|
||||||
pub #name: super::_resource::#name,
|
|
||||||
});
|
|
||||||
|
|
||||||
exprs.push(quote! {
|
if has_resources {
|
||||||
#name: {
|
for name in &task.resources {
|
||||||
super::_resource::#name::new()
|
match ownerships[name] {
|
||||||
},
|
Ownership::Shared { ceiling }
|
||||||
});
|
if ceiling > task.priority =>
|
||||||
}
|
{
|
||||||
_ => {
|
needs_threshold = true;
|
||||||
lifetime = Some(quote!('a));
|
|
||||||
if let Some(resource) = app.resources.get(name) {
|
|
||||||
needs_reexport = true;
|
|
||||||
let ty = &resource.ty;
|
|
||||||
|
|
||||||
fields.push(quote! {
|
fields.push(quote! {
|
||||||
pub #name: &'a mut ::#krate::Static<#ty>,
|
pub #name: super::_resource::#name,
|
||||||
});
|
});
|
||||||
|
|
||||||
exprs.push(quote! {
|
exprs.push(quote! {
|
||||||
#name: ::#krate::Static::ref_mut(&mut super::#name),
|
#name: {
|
||||||
|
super::_resource::#name::new()
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
fields.push(quote! {
|
_ => {
|
||||||
pub #name:
|
lifetime = Some(quote!('a));
|
||||||
|
if let Some(resource) = app.resources.get(name) {
|
||||||
|
needs_reexport = true;
|
||||||
|
let ty = &resource.ty;
|
||||||
|
|
||||||
|
fields.push(quote! {
|
||||||
|
pub #name: &'a mut ::#krate::Static<#ty>,
|
||||||
|
});
|
||||||
|
|
||||||
|
exprs.push(quote! {
|
||||||
|
#name: ::#krate::Static::ref_mut(&mut super::#name),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fields.push(quote! {
|
||||||
|
pub #name:
|
||||||
&'a mut ::#krate::Static<::#device::#name>,
|
&'a mut ::#krate::Static<::#device::#name>,
|
||||||
});
|
});
|
||||||
|
|
||||||
exprs.push(quote! {
|
exprs.push(quote! {
|
||||||
#name: ::#krate::Static::ref_mut(
|
#name: ::#krate::Static::ref_mut(
|
||||||
&mut *::#device::#name.get(),
|
&mut *::#device::#name.get(),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if needs_reexport {
|
||||||
|
let rname = Ident::new(format!("_{}Resources", name));
|
||||||
|
root.push(quote! {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub struct #rname<#lifetime> {
|
||||||
|
#(#fields)*
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
items.push(quote! {
|
||||||
|
pub use ::#rname as Resources;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
items.push(quote! {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub struct Resources<#lifetime> {
|
||||||
|
#(#fields)*
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
items.push(quote! {
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
impl<#lifetime> Resources<#lifetime> {
|
||||||
|
pub unsafe fn new() -> Self {
|
||||||
|
Resources {
|
||||||
|
#(#exprs)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if needs_reexport {
|
if let Some(path) = task.path.as_ref() {
|
||||||
let rname = Ident::new(format!("_{}Resources", name));
|
let mut tys = vec![];
|
||||||
|
let mut exprs = vec![];
|
||||||
|
|
||||||
|
let priority = task.priority;
|
||||||
|
if needs_threshold {
|
||||||
|
tys.push(quote!(&mut Threshold));
|
||||||
|
exprs.push(quote!(&mut Threshold::new(#priority)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if has_resources {
|
||||||
|
tys.push(quote!(#name::Resources));
|
||||||
|
exprs.push(quote!(#name::Resources::new()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let _name = Ident::new(format!("_{}", name));
|
||||||
|
let export_name = Lit::Str(name.as_ref().to_owned(), StrStyle::Cooked);
|
||||||
root.push(quote! {
|
root.push(quote! {
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub struct #rname<#lifetime> {
|
#[allow(unsafe_code)]
|
||||||
#(#fields)*
|
#[export_name = #export_name]
|
||||||
|
pub unsafe extern "C" fn #_name() {
|
||||||
|
let f: fn(#(#tys,)*) = #path;
|
||||||
|
|
||||||
|
f(#(#exprs,)*)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if !has_resources {
|
||||||
items.push(quote! {
|
items.push(quote! {
|
||||||
pub use ::#rname as Resources;
|
pub struct Resources {
|
||||||
});
|
_0: (),
|
||||||
} else {
|
|
||||||
items.push(quote! {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub struct Resources<#lifetime> {
|
|
||||||
#(#fields)*
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
items.push(quote! {
|
impl Resources {
|
||||||
#[allow(unsafe_code)]
|
pub unsafe fn new() -> Self {
|
||||||
impl<#lifetime> Resources<#lifetime> {
|
Resources { _0: () }
|
||||||
pub unsafe fn new() -> Self {
|
|
||||||
Resources {
|
|
||||||
#(#exprs)*
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
// the `task!` macro will be used so the `#NAME::Resources` type
|
||||||
|
// must exist
|
||||||
|
}
|
||||||
|
|
||||||
let priority = task.priority;
|
let priority = task.priority;
|
||||||
|
if task.path.is_none() {
|
||||||
|
// This `const`ant is mainly used to make sure the user doesn't
|
||||||
|
// forget to set a task handler using the `task!` macro. They'll get
|
||||||
|
// an error if they do.
|
||||||
|
items.push(quote! {
|
||||||
|
#[deny(dead_code)]
|
||||||
|
pub const #name: u8 = #priority;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
root.push(quote!{
|
root.push(quote!{
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
mod #name {
|
mod #name {
|
||||||
#[deny(dead_code)]
|
|
||||||
pub const #name: u8 = #priority;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[deny(const_err)]
|
#[deny(const_err)]
|
||||||
const CHECK_PRIORITY: (u8, u8) = (
|
const CHECK_PRIORITY: (u8, u8) = (
|
||||||
|
|
|
@ -191,6 +191,10 @@ impl Threshold {
|
||||||
impl !Send for Threshold {}
|
impl !Send for Threshold {}
|
||||||
|
|
||||||
/// Sets an interrupt as pending
|
/// Sets an interrupt as pending
|
||||||
|
///
|
||||||
|
/// If the interrupt priority is high enough the interrupt will be serviced
|
||||||
|
/// immediately, otherwise it will be serviced at some point after the current
|
||||||
|
/// task ends.
|
||||||
pub fn set_pending<I>(interrupt: I)
|
pub fn set_pending<I>(interrupt: I)
|
||||||
where
|
where
|
||||||
I: Nr,
|
I: Nr,
|
||||||
|
|
Loading…
Reference in a new issue