aboutsummaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
authorGravatar Emil Fresk <emil.fresk@gmail.com> 2023-01-04 20:01:05 +0100
committerGravatar Henrik Tjäder <henrik@tjaders.com> 2023-03-01 00:31:05 +0100
commitd27d0fe33fdb54e6a11a1e9d09a7916f19e5c9ec (patch)
treed85e8e073721eafe4458214b8785728f7546f6d4 /macros/src
parentf8352122a301c30db7c7851ebf50ad1608ebdad3 (diff)
downloadrtic-d27d0fe33fdb54e6a11a1e9d09a7916f19e5c9ec.tar.gz
rtic-d27d0fe33fdb54e6a11a1e9d09a7916f19e5c9ec.tar.zst
rtic-d27d0fe33fdb54e6a11a1e9d09a7916f19e5c9ec.zip
Added software task codegen back
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/codegen.rs11
-rw-r--r--macros/src/codegen/software_tasks.rs101
2 files changed, 111 insertions, 1 deletions
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs
index 618d9f3a..6460afec 100644
--- a/macros/src/codegen.rs
+++ b/macros/src/codegen.rs
@@ -18,7 +18,7 @@ mod post_init;
mod pre_init;
mod shared_resources;
mod shared_resources_struct;
-// mod software_tasks;
+mod software_tasks;
// mod timer_queue;
mod util;
@@ -92,6 +92,9 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
let (mod_app_hardware_tasks, root_hardware_tasks, user_hardware_tasks) =
hardware_tasks::codegen(app, analysis);
+ let (mod_app_software_tasks, root_software_tasks, user_software_tasks) =
+ software_tasks::codegen(app, analysis);
+
let mod_app_async_dispatchers = async_dispatchers::codegen(app, analysis);
let user_imports = &app.user_imports;
let user_code = &app.user_code;
@@ -116,6 +119,8 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
#(#user_hardware_tasks)*
+ #(#user_software_tasks)*
+
#(#root)*
#mod_shared_resources
@@ -124,6 +129,8 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
#(#root_hardware_tasks)*
+ #(#root_software_tasks)*
+
/// app module
#(#mod_app)*
@@ -133,6 +140,8 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
#(#mod_app_hardware_tasks)*
+ #(#mod_app_software_tasks)*
+
#(#mod_app_async_dispatchers)*
#(#mains)*
diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs
new file mode 100644
index 00000000..b2b468ca
--- /dev/null
+++ b/macros/src/codegen/software_tasks.rs
@@ -0,0 +1,101 @@
+use crate::syntax::{ast::App, Context};
+use crate::{
+ analyze::Analysis,
+ codegen::{local_resources_struct, module, shared_resources_struct, util},
+};
+use proc_macro2::TokenStream as TokenStream2;
+use quote::quote;
+
+pub fn codegen(
+ app: &App,
+ analysis: &Analysis,
+) -> (
+ // mod_app_software_tasks -- free queues, buffers and `${task}Resources` constructors
+ Vec<TokenStream2>,
+ // root_software_tasks -- items that must be placed in the root of the crate:
+ // - `${task}Locals` structs
+ // - `${task}Resources` structs
+ // - `${task}` modules
+ Vec<TokenStream2>,
+ // user_software_tasks -- the `#[task]` functions written by the user
+ Vec<TokenStream2>,
+) {
+ let mut mod_app = vec![];
+ let mut root = vec![];
+ let mut user_tasks = vec![];
+
+ // Any task
+ for (name, task) in app.software_tasks.iter() {
+ let executor_ident = util::executor_run_ident(name);
+ mod_app.push(quote!(
+ #[allow(non_camel_case_types)]
+ #[allow(non_upper_case_globals)]
+ #[doc(hidden)]
+ static #executor_ident: core::sync::atomic::AtomicBool =
+ core::sync::atomic::AtomicBool::new(false);
+ ));
+
+ // `${task}Resources`
+ let mut shared_needs_lt = false;
+ let mut local_needs_lt = false;
+
+ // `${task}Locals`
+ if !task.args.local_resources.is_empty() {
+ let (item, constructor) = local_resources_struct::codegen(
+ Context::SoftwareTask(name),
+ &mut local_needs_lt,
+ app,
+ );
+
+ root.push(item);
+
+ mod_app.push(constructor);
+ }
+
+ if !task.args.shared_resources.is_empty() {
+ let (item, constructor) = shared_resources_struct::codegen(
+ Context::SoftwareTask(name),
+ &mut shared_needs_lt,
+ app,
+ );
+
+ root.push(item);
+
+ mod_app.push(constructor);
+ }
+
+ if !&task.is_extern {
+ let context = &task.context;
+ let attrs = &task.attrs;
+ let cfgs = &task.cfgs;
+ let stmts = &task.stmts;
+ let context_lifetime = if shared_needs_lt || local_needs_lt {
+ quote!(<'static>)
+ } else {
+ quote!()
+ };
+
+ user_tasks.push(quote!(
+ #(#attrs)*
+ #(#cfgs)*
+ #[allow(non_snake_case)]
+ async fn #name(#context: #name::Context #context_lifetime) {
+ use rtic::Mutex as _;
+ use rtic::mutex::prelude::*;
+
+ #(#stmts)*
+ }
+ ));
+ }
+
+ root.push(module::codegen(
+ Context::SoftwareTask(name),
+ shared_needs_lt,
+ local_needs_lt,
+ app,
+ analysis,
+ ));
+ }
+
+ (mod_app, root, user_tasks)
+}