mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
Allow initialization of resources in init
.
This commit is contained in:
parent
27fc7e99d2
commit
7ebba49644
4 changed files with 89 additions and 31 deletions
|
@ -14,9 +14,10 @@ version = "0.2.1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-m = "0.3.1"
|
cortex-m = "0.3.1"
|
||||||
cortex-m-rtfm-macros = "=0.2.0"
|
# TODO should this have been a `path` dep all along?
|
||||||
rtfm-core = "0.1.0"
|
cortex-m-rtfm-macros = { path = "macros" }
|
||||||
static-ref = "0.2.1"
|
# TODO revert before merging
|
||||||
|
rtfm-core = { git = "https://github.com/jonas-schievink/rtfm-core.git", branch = "init-resources" }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dev-dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dev-dependencies]
|
||||||
compiletest_rs = "0.2.8"
|
compiletest_rs = "0.2.8"
|
||||||
|
|
|
@ -12,7 +12,8 @@ version = "0.2.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
error-chain = "0.10.0"
|
error-chain = "0.10.0"
|
||||||
quote = "0.3.15"
|
quote = "0.3.15"
|
||||||
rtfm-syntax = "0.1.0"
|
# TODO undo change
|
||||||
|
rtfm-syntax = { git = "https://github.com/jonas-schievink/rtfm-syntax.git", branch = "init-resources" }
|
||||||
syn = "0.11.11"
|
syn = "0.11.11"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
|
@ -157,14 +157,23 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
||||||
|
|
||||||
let mut tys = vec![quote!(#device::Peripherals)];
|
let mut tys = vec![quote!(#device::Peripherals)];
|
||||||
let mut exprs = vec![quote!(#device::Peripherals::all())];
|
let mut exprs = vec![quote!(#device::Peripherals::all())];
|
||||||
|
let mut ret = None;
|
||||||
let mut mod_items = vec![];
|
let mut mod_items = vec![];
|
||||||
|
|
||||||
if !app.resources.is_empty() {
|
// Write resources usable by `init`, if any
|
||||||
|
|
||||||
|
|
||||||
|
// Are there any resources that have an initializer? Those can be used by `init`.
|
||||||
|
let has_initialized_resources = app.resources.iter()
|
||||||
|
.find(|&(_, res)| res.expr.is_some()).is_some();
|
||||||
|
|
||||||
|
if has_initialized_resources {
|
||||||
let mut fields = vec![];
|
let mut fields = vec![];
|
||||||
let mut lifetime = None;
|
let mut lifetime = None;
|
||||||
let mut rexprs = vec![];
|
let mut rexprs = vec![];
|
||||||
|
|
||||||
for (name, resource) in &app.resources {
|
for (name, resource) in app.resources.iter()
|
||||||
|
.filter(|&(_, res)| res.expr.is_some()) {
|
||||||
let _name = Ident::new(format!("_{}", name.as_ref()));
|
let _name = Ident::new(format!("_{}", name.as_ref()));
|
||||||
lifetime = Some(quote!('a));
|
lifetime = Some(quote!('a));
|
||||||
|
|
||||||
|
@ -204,6 +213,46 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
||||||
exprs.push(quote!(init::Resources::new()));
|
exprs.push(quote!(init::Resources::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut late_resources = vec![];
|
||||||
|
let has_late_resources = app.resources.iter()
|
||||||
|
.find(|&(_, res)| res.expr.is_none()).is_some();
|
||||||
|
|
||||||
|
if has_late_resources {
|
||||||
|
// `init` must initialize and return resources
|
||||||
|
|
||||||
|
let mut fields = vec![];
|
||||||
|
|
||||||
|
for (name, resource) in app.resources.iter()
|
||||||
|
.filter(|&(_, res)| res.expr.is_none()) {
|
||||||
|
let _name = Ident::new(format!("_{}", name.as_ref()));
|
||||||
|
|
||||||
|
let ty = &resource.ty;
|
||||||
|
|
||||||
|
fields.push(quote! {
|
||||||
|
pub #name: #ty,
|
||||||
|
});
|
||||||
|
|
||||||
|
late_resources.push(quote! {
|
||||||
|
#_name = #krate::LateResource { init: _late_resources.#name };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
root.push(quote! {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub struct _initLateResourceValues {
|
||||||
|
#(#fields)*
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mod_items.push(quote! {
|
||||||
|
pub use ::_initLateResourceValues as LateResourceValues;
|
||||||
|
});
|
||||||
|
|
||||||
|
// `init` must return the initialized resources
|
||||||
|
ret = Some(quote!( -> ::init::LateResourceValues));
|
||||||
|
}
|
||||||
|
|
||||||
root.push(quote! {
|
root.push(quote! {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
mod init {
|
mod init {
|
||||||
|
@ -263,10 +312,11 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
||||||
let init = &app.init.path;
|
let init = &app.init.path;
|
||||||
main.push(quote! {
|
main.push(quote! {
|
||||||
// type check
|
// type check
|
||||||
let init: fn(#(#tys,)*) = #init;
|
let init: fn(#(#tys,)*) #ret = #init;
|
||||||
|
|
||||||
#krate::atomic(unsafe { &mut #krate::Threshold::new(0) }, |_t| unsafe {
|
#krate::atomic(unsafe { &mut #krate::Threshold::new(0) }, |_t| unsafe {
|
||||||
init(#(#exprs,)*);
|
let _late_resources = init(#(#exprs,)*);
|
||||||
|
#(#late_resources)*
|
||||||
|
|
||||||
#(#exceptions)*
|
#(#exceptions)*
|
||||||
#(#interrupts)*
|
#(#interrupts)*
|
||||||
|
@ -281,33 +331,34 @@ fn resources(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
let mut impls = vec![];
|
let mut impls = vec![];
|
||||||
for (name, ownership) in ownerships {
|
for (name, ownership) in ownerships {
|
||||||
let mut impl_items = vec![];
|
|
||||||
|
|
||||||
let _name = Ident::new(format!("_{}", name.as_ref()));
|
let _name = Ident::new(format!("_{}", name.as_ref()));
|
||||||
match *ownership {
|
|
||||||
Ownership::Owned { .. } => {
|
|
||||||
if let Some(resource) = app.resources.get(name) {
|
if let Some(resource) = app.resources.get(name) {
|
||||||
// For owned resources we don't need claim() or borrow()
|
// Declare the static that holds the resource
|
||||||
let expr = &resource.expr;
|
let expr = &resource.expr;
|
||||||
let ty = &resource.ty;
|
let ty = &resource.ty;
|
||||||
|
|
||||||
root.push(quote! {
|
root.push(match *expr {
|
||||||
|
Some(ref expr) => quote! {
|
||||||
static mut #_name: #ty = #expr;
|
static mut #_name: #ty = #expr;
|
||||||
|
},
|
||||||
|
None => quote! {
|
||||||
|
// Resource initialized in `init`
|
||||||
|
static mut #_name: #krate::LateResource<#ty> = #krate::LateResource { uninit: () };
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// Peripheral
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut impl_items = vec![];
|
||||||
|
|
||||||
|
match *ownership {
|
||||||
|
Ownership::Owned { .. } => {
|
||||||
|
// For owned resources we don't need claim() or borrow()
|
||||||
}
|
}
|
||||||
Ownership::Shared { ceiling } => {
|
Ownership::Shared { ceiling } => {
|
||||||
if let Some(resource) = app.resources.get(name) {
|
if let Some(resource) = app.resources.get(name) {
|
||||||
let expr = &resource.expr;
|
|
||||||
let ty = &resource.ty;
|
let ty = &resource.ty;
|
||||||
|
|
||||||
root.push(quote! {
|
|
||||||
static mut #_name: #ty = #expr;
|
|
||||||
});
|
|
||||||
|
|
||||||
impl_items.push(quote! {
|
impl_items.push(quote! {
|
||||||
type Data = #ty;
|
type Data = #ty;
|
||||||
|
|
||||||
|
@ -530,8 +581,14 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
|
||||||
pub #name: &'a mut ::#krate::Static<#ty>,
|
pub #name: &'a mut ::#krate::Static<#ty>,
|
||||||
});
|
});
|
||||||
|
|
||||||
exprs.push(quote! {
|
exprs.push(if resource.expr.is_some() {
|
||||||
|
quote! {
|
||||||
#name: ::#krate::Static::ref_mut(&mut ::#_name),
|
#name: ::#krate::Static::ref_mut(&mut ::#_name),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
#name: ::#krate::Static::ref_mut(&mut ::#_name.init),
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
fields.push(quote! {
|
fields.push(quote! {
|
||||||
|
|
|
@ -80,11 +80,10 @@
|
||||||
extern crate cortex_m;
|
extern crate cortex_m;
|
||||||
extern crate cortex_m_rtfm_macros;
|
extern crate cortex_m_rtfm_macros;
|
||||||
extern crate rtfm_core;
|
extern crate rtfm_core;
|
||||||
extern crate static_ref;
|
|
||||||
|
|
||||||
use core::u8;
|
use core::u8;
|
||||||
|
|
||||||
pub use rtfm_core::{Resource, Static, Threshold};
|
pub use rtfm_core::{Resource, LateResource, Static, Threshold};
|
||||||
pub use cortex_m::asm::{bkpt, wfi};
|
pub use cortex_m::asm::{bkpt, wfi};
|
||||||
pub use cortex_m_rtfm_macros::app;
|
pub use cortex_m_rtfm_macros::app;
|
||||||
use cortex_m::interrupt::{self, Nr};
|
use cortex_m::interrupt::{self, Nr};
|
||||||
|
|
Loading…
Reference in a new issue