aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/main.rs')
-rw-r--r--macros/src/codegen/main.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/macros/src/codegen/main.rs b/macros/src/codegen/main.rs
new file mode 100644
index 00000000..90f09ae0
--- /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: 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
+ }
+ )
+}