aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/module.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/module.rs')
-rw-r--r--macros/src/codegen/module.rs69
1 files changed, 66 insertions, 3 deletions
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index 2e51e7db..526bf491 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -2,9 +2,15 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use rtic_syntax::{ast::App, Context};
-use crate::{check::Extra, codegen::util};
-
-pub fn codegen(ctxt: Context, resources_tick: bool, app: &App, extra: &Extra) -> TokenStream2 {
+use crate::{analyze::Analysis, check::Extra, codegen::util};
+
+pub fn codegen(
+ ctxt: Context,
+ resources_tick: bool,
+ app: &App,
+ analysis: &Analysis,
+ extra: &Extra,
+) -> TokenStream2 {
let mut items = vec![];
let mut fields = vec![];
let mut values = vec![];
@@ -316,6 +322,63 @@ pub fn codegen(ctxt: Context, resources_tick: bool, app: &App, extra: &Extra) ->
}
));
+ // not sure if this is the right way, maybe its backwards,
+ // that spawn_module should put in in root
+
+ if let Context::SoftwareTask(..) = ctxt {
+ let spawnee = &app.software_tasks[name];
+ let priority = spawnee.args.priority;
+ let t = util::spawn_t_ident(priority);
+ let cfgs = &spawnee.cfgs;
+ let (args, tupled, _untupled, ty) = util::regroup_inputs(&spawnee.inputs);
+ let args = &args;
+ let tupled = &tupled;
+ let fq = util::fq_ident(name);
+ let rq = util::rq_ident(priority);
+ let inputs = util::inputs_ident(name);
+
+ eprintln!("app name: {}", app.name);
+ eprintln!("inputs {}", &inputs);
+ eprintln!("task name: {}", name);
+ eprintln!("fq {}", fq);
+ eprintln!("rq {}", rq);
+ let app_name = &app.name;
+ let app_path = quote! {crate::#app_name};
+
+ let device = extra.device;
+ let enum_ = util::interrupt_ident();
+ let interrupt = &analysis.interrupts.get(&priority);
+
+ items.push(quote!(
+ #(#cfgs)*
+ pub fn spawn(#(#args,)*) -> Result<(), #ty> {
+ // #let_instant // do we need it?
+ use rtic::Mutex as _;
+
+ let input = #tupled;
+
+ if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
+ unsafe {
+ #app_path::#inputs
+ .get_unchecked_mut(usize::from(index))
+ .as_mut_ptr()
+ .write(input);
+ }
+
+ rtic::export::interrupt::free(|_| {
+ #app_path::#rq.enqueue_unchecked((#app_path::#t::#name, index));
+ });
+
+ rtic::pend(#device::#enum_::#interrupt);
+
+ Ok(())
+ } else {
+ Err(input)
+ }
+
+ }));
+ }
+
if !items.is_empty() {
quote!(
#[allow(non_snake_case)]