From 9e445b3583c15c7701f3167eaa8dfe4afd541691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Feb 2023 16:47:17 +0100 Subject: Move rtic macros to repo root, tune xtask --- rtic-macros/src/codegen/module.rs | 197 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 rtic-macros/src/codegen/module.rs (limited to 'rtic-macros/src/codegen/module.rs') diff --git a/rtic-macros/src/codegen/module.rs b/rtic-macros/src/codegen/module.rs new file mode 100644 index 0000000..8b3fca2 --- /dev/null +++ b/rtic-macros/src/codegen/module.rs @@ -0,0 +1,197 @@ +use crate::syntax::{ast::App, Context}; +use crate::{analyze::Analysis, codegen::util}; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +#[allow(clippy::too_many_lines)] +pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 { + let mut items = vec![]; + let mut module_items = vec![]; + let mut fields = vec![]; + let mut values = vec![]; + // Used to copy task cfgs to the whole module + let mut task_cfgs = vec![]; + + let name = ctxt.ident(app); + + match ctxt { + Context::Init => { + fields.push(quote!( + /// Core (Cortex-M) peripherals + pub core: rtic::export::Peripherals + )); + + if app.args.peripherals { + let device = &app.args.device; + + fields.push(quote!( + /// Device peripherals + pub device: #device::Peripherals + )); + + values.push(quote!(device: #device::Peripherals::steal())); + } + + fields.push(quote!( + /// Critical section token for init + pub cs: rtic::export::CriticalSection<'a> + )); + + values.push(quote!(cs: rtic::export::CriticalSection::new())); + + values.push(quote!(core)); + } + + Context::Idle | Context::HardwareTask(_) | Context::SoftwareTask(_) => {} + } + + if ctxt.has_local_resources(app) { + let ident = util::local_resources_ident(ctxt, app); + + module_items.push(quote!( + #[doc(inline)] + pub use super::#ident as LocalResources; + )); + + fields.push(quote!( + /// Local Resources this task has access to + pub local: #name::LocalResources<'a> + )); + + values.push(quote!(local: #name::LocalResources::new())); + } + + if ctxt.has_shared_resources(app) { + let ident = util::shared_resources_ident(ctxt, app); + + module_items.push(quote!( + #[doc(inline)] + pub use super::#ident as SharedResources; + )); + + fields.push(quote!( + /// Shared Resources this task has access to + pub shared: #name::SharedResources<'a> + )); + + values.push(quote!(shared: #name::SharedResources::new())); + } + + let doc = match ctxt { + Context::Idle => "Idle loop", + Context::Init => "Initialization function", + Context::HardwareTask(_) => "Hardware task", + Context::SoftwareTask(_) => "Software task", + }; + + let v = Vec::new(); + let cfgs = match ctxt { + Context::HardwareTask(t) => &app.hardware_tasks[t].cfgs, + Context::SoftwareTask(t) => &app.software_tasks[t].cfgs, + _ => &v, + }; + + let core = if ctxt.is_init() { + Some(quote!(core: rtic::export::Peripherals,)) + } else { + None + }; + + let internal_context_name = util::internal_task_ident(name, "Context"); + let exec_name = util::internal_task_ident(name, "EXEC"); + + items.push(quote!( + #(#cfgs)* + /// Execution context + #[allow(non_snake_case)] + #[allow(non_camel_case_types)] + pub struct #internal_context_name<'a> { + #[doc(hidden)] + __rtic_internal_p: ::core::marker::PhantomData<&'a ()>, + #(#fields,)* + } + + #(#cfgs)* + impl<'a> #internal_context_name<'a> { + #[inline(always)] + #[allow(missing_docs)] + pub unsafe fn new(#core) -> Self { + #internal_context_name { + __rtic_internal_p: ::core::marker::PhantomData, + #(#values,)* + } + } + } + )); + + module_items.push(quote!( + #(#cfgs)* + #[doc(inline)] + pub use super::#internal_context_name as Context; + )); + + if let Context::SoftwareTask(..) = ctxt { + let spawnee = &app.software_tasks[name]; + let priority = spawnee.args.priority; + let cfgs = &spawnee.cfgs; + // Store a copy of the task cfgs + task_cfgs = cfgs.clone(); + + let pend_interrupt = if priority > 0 { + let device = &app.args.device; + let enum_ = util::interrupt_ident(); + let interrupt = &analysis.interrupts.get(&priority).expect("UREACHABLE").0; + quote!(rtic::pend(#device::#enum_::#interrupt);) + } else { + quote!() + }; + + let internal_spawn_ident = util::internal_task_ident(name, "spawn"); + let (input_args, input_tupled, input_untupled, input_ty) = + util::regroup_inputs(&spawnee.inputs); + + // Spawn caller + items.push(quote!( + #(#cfgs)* + /// Spawns the task directly + #[allow(non_snake_case)] + #[doc(hidden)] + pub fn #internal_spawn_ident(#(#input_args,)*) -> Result<(), #input_ty> { + // SAFETY: If `try_allocate` suceeds one must call `spawn`, which we do. + unsafe { + if #exec_name.try_allocate() { + let f = #name(unsafe { #name::Context::new() } #(,#input_untupled)*); + #exec_name.spawn(f); + #pend_interrupt + + Ok(()) + } else { + Err(#input_tupled) + } + } + + } + )); + + module_items.push(quote!( + #(#cfgs)* + #[doc(inline)] + pub use super::#internal_spawn_ident as spawn; + )); + } + + if items.is_empty() { + quote!() + } else { + quote!( + #(#items)* + + #[allow(non_snake_case)] + #(#task_cfgs)* + #[doc = #doc] + pub mod #name { + #(#module_items)* + } + ) + } +} -- cgit v1.2.3 From 60f0342b697cdddbab9c0e8c6d772bc7aab9de38 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 11 Feb 2023 08:55:19 +0100 Subject: Break out core specific codegen to bindings --- rtic-macros/src/codegen/module.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rtic-macros/src/codegen/module.rs') diff --git a/rtic-macros/src/codegen/module.rs b/rtic-macros/src/codegen/module.rs index 8b3fca2..af4e034 100644 --- a/rtic-macros/src/codegen/module.rs +++ b/rtic-macros/src/codegen/module.rs @@ -17,7 +17,7 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 { match ctxt { Context::Init => { fields.push(quote!( - /// Core (Cortex-M) peripherals + /// Core peripherals pub core: rtic::export::Peripherals )); @@ -25,7 +25,7 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 { let device = &app.args.device; fields.push(quote!( - /// Device peripherals + /// Device peripherals (PAC) pub device: #device::Peripherals )); -- cgit v1.2.3