diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index b490d7a501..839b1cd401 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -19,6 +19,8 @@ mod shared_resources_struct; mod software_tasks; mod util; +mod main; + // TODO: organize codegen to actual parts of code // so `main::codegen` generates ALL the code for `fn main`, // `software_tasks::codegen` generates ALL the code for software tasks etc... @@ -26,20 +28,15 @@ mod util; #[allow(clippy::too_many_lines)] pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 { let mut mod_app = vec![]; - let mut mains = vec![]; let mut root = vec![]; let mut user = vec![]; // Generate the `main` function - let assertion_stmts = assertions::codegen(app, analysis); + let main = main::codegen(app, analysis); - let pre_init_stmts = pre_init::codegen(app, analysis); + let (mod_app_init, root_init, user_init) = init::codegen(app, analysis); - let (mod_app_init, root_init, user_init, call_init) = init::codegen(app, analysis); - - let post_init_stmts = post_init::codegen(app, analysis); - - let (mod_app_idle, root_idle, user_idle, call_idle) = idle::codegen(app, analysis); + let (mod_app_idle, root_idle, user_idle) = idle::codegen(app, analysis); user.push(quote!( #user_init @@ -59,34 +56,6 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 { #(#mod_app_idle)* )); - let main = util::suffixed("main"); - mains.push(quote!( - #[doc(hidden)] - mod rtic_ext { - use super::*; - #[no_mangle] - unsafe extern "C" fn #main() -> ! { - #(#assertion_stmts)* - - #(#pre_init_stmts)* - - #[inline(never)] - fn __rtic_init_resources(f: F) where F: FnOnce() { - f(); - } - - // Wrap late_init_stmts in a function to ensure that stack space is reclaimed. - __rtic_init_resources(||{ - #call_init - - #(#post_init_stmts)* - }); - - #call_idle - } - } - )); - let (mod_app_shared_resources, mod_shared_resources) = shared_resources::codegen(app, analysis); let (mod_app_local_resources, mod_local_resources) = local_resources::codegen(app, analysis); @@ -145,7 +114,7 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 { #(#mod_app_async_dispatchers)* - #(#mains)* + #main } ) } diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs index c0eecbcabb..1f05d12901 100644 --- a/macros/src/codegen/idle.rs +++ b/macros/src/codegen/idle.rs @@ -20,8 +20,6 @@ pub fn codegen( Vec, // user_idle Option, - // call_idle - TokenStream2, ) { if let Some(idle) = &app.idle { let mut mod_app = vec![]; @@ -60,22 +58,10 @@ pub fn codegen( } )); - let call_idle = quote!(#name( - #name::Context::new() - )); - - (mod_app, root_idle, user_idle, call_idle) + (mod_app, root_idle, user_idle) } else { // TODO: No idle defined, check for 0-priority tasks and generate an executor if needed - unimplemented!(); - // ( - // vec![], - // vec![], - // None, - // quote!(loop { - // rtic::export::nop() - // }), - // ) + (vec![], vec![], None) } } diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 2aa8fb31fb..3b2bcd471b 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -18,8 +18,6 @@ type CodegenResult = ( Vec, // user_init -- the `#[init]` function written by the user TokenStream2, - // call_init -- the call to the user `#[init]` - TokenStream2, ); /// Generates support code for `#[init]` functions @@ -63,6 +61,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> CodegenResult { ) }) .collect(); + root_init.push(quote! { struct #shared { #(#shared_resources)* @@ -97,11 +96,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> CodegenResult { mod_app = Some(constructor); } - let call_init = quote! { - let (shared_resources, local_resources) = #name(#name::Context::new(core.into())); - }; - root_init.push(module::codegen(Context::Init, app, analysis)); - (mod_app, root_init, user_init, call_init) + (mod_app, root_init, user_init) } diff --git a/macros/src/codegen/main.rs b/macros/src/codegen/main.rs new file mode 100644 index 0000000000..90f09ae0d8 --- /dev/null +++ b/macros/src/codegen/main.rs @@ -0,0 +1,51 @@ +use crate::{analyze::Analysis, codegen::util, syntax::ast::App}; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +use super::{assertions, post_init, pre_init}; + +/// Generates code for `fn main` +pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { + let assertion_stmts = assertions::codegen(app, analysis); + + let pre_init_stmts = pre_init::codegen(app, analysis); + + let post_init_stmts = post_init::codegen(app, analysis); + + let call_idle = if let Some(idle) = &app.idle { + let name = &idle.name; + quote!(#name(#name::Context::new())) + } else { + // TODO: No idle defined, check for 0-priority tasks and generate an executor if needed + + quote!(loop { + rtic::export::nop() + }) + }; + + let main = util::suffixed("main"); + let init_name = &app.init.name; + quote!( + #[doc(hidden)] + #[no_mangle] + unsafe extern "C" fn #main() -> ! { + #(#assertion_stmts)* + + #(#pre_init_stmts)* + + #[inline(never)] + fn __rtic_init_resources(f: F) where F: FnOnce() { + f(); + } + + // Wrap late_init_stmts in a function to ensure that stack space is reclaimed. + __rtic_init_resources(||{ + let (shared_resources, local_resources) = #init_name(#init_name::Context::new(core.into())); + + #(#post_init_stmts)* + }); + + #call_idle + } + ) +} diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index e8183b9368..c4e5383718 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -1,9 +1,7 @@ -use crate::syntax::ast::App; +use crate::{analyze::Analysis, codegen::util, syntax::ast::App}; use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use crate::{analyze::Analysis, codegen::util}; - /// Generates code that runs after `#[init]` returns pub fn codegen(app: &App, analysis: &Analysis) -> Vec { let mut stmts = vec![];