diff options
Diffstat (limited to 'macros/src/codegen.rs')
-rw-r--r-- | macros/src/codegen.rs | 86 |
1 files changed, 62 insertions, 24 deletions
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 3cddf570..c5d95687 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -27,13 +27,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let mut user = vec![]; // Generate the `main` function - let assertion_stmts = assertions::codegen(analysis); + let assertion_stmts = assertions::codegen(app, analysis); - let pre_init_stmts = pre_init::codegen(&app, analysis, extra); + let pre_init_stmts = pre_init::codegen(app, analysis, extra); let (mod_app_init, root_init, user_init, call_init) = init::codegen(app, analysis, extra); - let post_init_stmts = post_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, extra); @@ -57,12 +57,11 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let main = util::suffixed("main"); mains.push(quote!( + #[doc(hidden)] mod rtic_ext { use super::*; #[no_mangle] unsafe extern "C" fn #main() -> ! { - let _TODO: () = (); - #(#assertion_stmts)* #(#pre_init_stmts)* @@ -90,27 +89,69 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let user_code = &app.user_code; let name = &app.name; let device = &extra.device; - - // Get the list of all tasks - // Currently unused, might be useful - let task_list = analysis.tasks.clone(); - - let mut tasks = vec![]; - - if !task_list.is_empty() { - tasks.push(quote!( - #[allow(non_camel_case_types)] - pub enum Tasks { - #(#task_list),* + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; + + let monotonic_parts: Vec<_> = app + .monotonics + .iter() + .map(|(_, monotonic)| { + let name = &monotonic.ident; + let name_str = &name.to_string(); + let ty = &monotonic.ty; + let ident = util::monotonic_ident(&name_str); + let ident = util::mark_internal_ident(&ident); + let panic_str = &format!( + "Use of monotonic '{}' before it was passed to the runtime", + name_str + ); + let doc = &format!( + "This module holds the static implementation for `{}::now()`", + name_str + ); + let user_imports = &app.user_imports; + + quote! { + pub use rtic::Monotonic as _; + + #[doc = #doc] + #[allow(non_snake_case)] + pub mod #name { + #( + #[allow(unused_imports)] + #user_imports + )* + + /// Read the current time from this monotonic + pub fn now() -> rtic::time::Instant<#ty> { + rtic::export::interrupt::free(|_| { + use rtic::Monotonic as _; + use rtic::time::Clock as _; + if let Some(m) = unsafe{ #app_path::#ident.as_ref() } { + if let Ok(v) = m.try_now() { + v + } else { + unreachable!("Your monotonic is not infallible!") + } + } else { + panic!(#panic_str); + } + }) + } + } } - )); - } + }) + .collect(); + + let rt_err = util::rt_err_ident(); quote!( - /// Implementation details + /// The RTIC application module pub mod #name { /// Always include the device crate which contains the vector table - use #device as you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml; + use #device as #rt_err; + + #(#monotonic_parts)* #(#user_imports)* @@ -132,9 +173,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #(#root_software_tasks)* - /// Unused - #(#tasks)* - /// app module #(#mod_app)* |