diff options
author | 2021-02-18 19:30:59 +0100 | |
---|---|---|
committer | 2021-02-18 19:30:59 +0100 | |
commit | ebf2f058a4d2a1fcf118144b9893dc3038939bad (patch) | |
tree | 11c7b828cc380737de36e6ab77edbd63bf42a72e /macros/src | |
parent | b57ef0bf9d836ad031e4a4f7930162003128dc74 (diff) | |
download | rtic-ebf2f058a4d2a1fcf118144b9893dc3038939bad.tar.gz rtic-ebf2f058a4d2a1fcf118144b9893dc3038939bad.tar.zst rtic-ebf2f058a4d2a1fcf118144b9893dc3038939bad.zip |
Now with new monotonic trait and crate
Diffstat (limited to 'macros/src')
-rw-r--r-- | macros/src/codegen.rs | 24 | ||||
-rw-r--r-- | macros/src/codegen/init.rs | 2 | ||||
-rw-r--r-- | macros/src/codegen/module.rs | 16 | ||||
-rw-r--r-- | macros/src/codegen/post_init.rs | 18 | ||||
-rw-r--r-- | macros/src/codegen/pre_init.rs | 20 | ||||
-rw-r--r-- | macros/src/codegen/software_tasks.rs | 2 | ||||
-rw-r--r-- | macros/src/codegen/timer_queue.rs | 21 | ||||
-rw-r--r-- | macros/src/codegen/util.rs | 10 |
8 files changed, 89 insertions, 24 deletions
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index bb8aa4e7..bdfcd36d 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -104,13 +104,35 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { )); } + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; + let monotonic_imports: Vec<_> = app .monotonics .iter() .map(|(_, monotonic)| { let name = &monotonic.ident; let ty = &monotonic.ty; - quote!(pub type #name = #ty;) + let mangled_name = util::mangle_monotonic_type(&name.to_string()); + let ident = util::monotonic_ident(&name.to_string()); + quote! { + #[doc(hidden)] + pub type #mangled_name = #ty; + + pub mod #name { + pub fn now() -> rtic::time::Instant<#app_path::#mangled_name> { + rtic::export::interrupt::free(|_| { + use rtic::Monotonic as _; + use rtic::time::Clock as _; + if let Ok(v) = unsafe{ (&*#app_path::#ident.as_ptr()).try_now() } { + v + } else { + unreachable!("Your monotonic is not infallible!") + } + }) + } + } + } }) .collect(); diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 66c3bc4e..aa9adcb0 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -69,7 +69,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let app_path = quote! {crate::#app_name}; let locals_new = locals_new.iter(); let call_init = Some( - quote!(let (late, monotonics) = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), + quote!(let (late, mut monotonics) = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), ); root_init.push(module::codegen( diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 93fbeaef..f0f403b2 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -126,7 +126,7 @@ pub fn codegen( .monotonics .iter() .map(|(_, monotonic)| { - let mono = &monotonic.ident; + let mono = util::mangle_monotonic_type(&monotonic.ident.to_string()); quote! {#app_path::#mono} }) .collect(); @@ -234,6 +234,7 @@ pub fn codegen( let tq = util::tq_ident(&monotonic.ident.to_string()); let t = util::schedule_t_ident(); let m = &monotonic.ident; + let m_mangled = util::mangle_monotonic_type(&monotonic.ident.to_string()); let m_isr = &monotonic.args.binds; let enum_ = util::interrupt_ident(); @@ -242,9 +243,10 @@ pub fn codegen( items.push(quote!(pub use #m::spawn_at;)); } - let (unmask, pend) = if &*m_isr.to_string() == "SysTick" { + let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" { ( - quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()), + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()) + .enable_interrupt()), quote!(cortex_m::peripheral::SCB::set_pendst()), ) } else { @@ -263,16 +265,16 @@ pub fn codegen( #(,#args)* ) -> Result<(), #ty> where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, - D::T: Into<<#app_path::#m as rtic::time::Clock>::T>, + D::T: Into<<#app_path::#m_mangled as rtic::time::Clock>::T>, { - let instant = <#app_path::#m as rtic::Monotonic>::now(); + let instant = #app_path::#m::now(); spawn_at(instant + duration, #(,#untupled)*) } #(#cfgs)* pub fn spawn_at( - instant: rtic::time::Instant<#app_path::#m> + instant: rtic::time::Instant<#app_path::#m_mangled> #(,#args)* ) -> Result<(), #ty> { unsafe { @@ -296,7 +298,7 @@ pub fn codegen( rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( nr, - || #unmask, + || #enable_interrupt, || #pend, )); diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 9268e040..b6cf47c3 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -1,6 +1,7 @@ -use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::quote; use rtic_syntax::ast::App; +use syn::Index; use crate::{analyze::Analysis, codegen::util}; @@ -25,12 +26,17 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> { } } - for (monotonic, _) in app.monotonics.iter() { - stmts.push(quote!(#monotonic::reset();)); - } + for (i, (monotonic, _)) in app.monotonics.iter().enumerate() { + let idx = Index { + index: i as u32, + span: Span::call_site(), + }; + stmts.push(quote!(monotonics.#idx.reset();)); - // Forget the monotonics so they won't be dropped. - stmts.push(quote!(core::mem::forget(monotonics);)); + // Store the monotonic + let name = util::monotonic_ident(&monotonic.to_string()); + stmts.push(quote!(#name.as_mut_ptr().write(monotonics.#idx);)); + } // Enable the interrupts -- this completes the `init`-ialization phase stmts.push(quote!(rtic::export::interrupt::enable();)); diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index e7b1b03b..fbfff3b5 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -77,14 +77,17 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream } // Initialize monotonic's interrupts - for (priority, name) in app + for (ident, priority, name) in app .monotonics .iter() - .map(|(_, monotonic)| (&monotonic.args.priority, &monotonic.args.binds)) + .map(|(ident, monotonic)| (ident, &monotonic.args.priority, &monotonic.args.binds)) { // Compile time assert that this priority is supported by the device stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];)); + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; + let mono_type = util::mangle_monotonic_type(&ident.to_string()); if &*name.to_string() == "SysTick" { stmts.push(quote!( @@ -92,6 +95,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream rtic::export::SystemHandler::SysTick, rtic::export::logical2hw(#priority, #nvic_prio_bits), ); + + // Always enable monotonic interrupts if they should never be off + if !#app_path::#mono_type::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { + core::mem::transmute::<_, cortex_m::peripheral::SYST>(()) + .enable_interrupt(); + } )); } else { // NOTE this also checks that the interrupt exists in the `Interrupt` enumeration @@ -101,10 +110,13 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream #rt_err::#interrupt::#name, rtic::export::logical2hw(#priority, #nvic_prio_bits), ); + + // Always enable monotonic interrupts if they should never be off + if !#app_path::#mono_type::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { + rtic::export::NVIC::unmask(#app_path::#rt_err::#interrupt::#name); + } )); } - - // NOTE we do not unmask the interrupt as this is part of the monotonic to keep track of } // If there's no user `#[idle]` then optimize returning from interrupt handlers diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index 53de50b9..a760b067 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -62,7 +62,7 @@ pub fn codegen( for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); - let m = &monotonic.ident; + let m = util::mangle_monotonic_type(&monotonic.ident.to_string()); let uninit = mk_uninit(); mod_app.push(quote!( diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 9a430a07..54b2c1f0 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -42,7 +42,10 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea let monotonic_name = monotonic.ident.to_string(); let tq = util::tq_ident(&monotonic_name); let t = util::schedule_t_ident(); - let m = &monotonic.ident; + let m = util::mangle_monotonic_type(&monotonic_name); + let m_ident = util::monotonic_ident(&monotonic_name); + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; // Static variables and resource proxy { @@ -63,6 +66,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea ) ); )); + + let mono = util::monotonic_ident(&monotonic_name); + let doc = &format!("Storage for {}", monotonic_name); + let mono_ty = quote!(core::mem::MaybeUninit<#m>); + + items.push(quote!( + #[doc = #doc] + static mut #mono: #mono_ty = core::mem::MaybeUninit::uninit(); + )); } // Timer queue handler @@ -100,8 +112,8 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea .collect::<Vec<_>>(); let bound_interrupt = &monotonic.args.binds; - let enable_isr = if &*bound_interrupt.to_string() == "SysTick" { - quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).enable_interrupt()) + let disable_isr = if &*bound_interrupt.to_string() == "SysTick" { + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()) } else { quote!(rtic::export::NVIC::mask(#rt_err::#enum_::#bound_interrupt)) }; @@ -111,7 +123,8 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea #[allow(non_snake_case)] unsafe fn #bound_interrupt() { while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue( - || #enable_isr, + || #disable_isr, + &mut *#app_path::#m_ident.as_mut_ptr(), )) { match task { diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 287ba408..7a12f23e 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -239,6 +239,16 @@ pub fn tq_ident(name: &str) -> Ident { Ident::new(&format!("TQ_{}", name), Span::call_site()) } +/// Generates an identifier for monotonic timer storage +pub fn monotonic_ident(name: &str) -> Ident { + Ident::new(&format!("MONOTONIC_STORAGE_{}", name), Span::call_site()) +} + +/// Generates an identifier for monotonic timer storage +pub fn mangle_monotonic_type(name: &str) -> Ident { + Ident::new(&format!("MonotonicMangled{}", name), Span::call_site()) +} + /// The name to get better RT flag errors pub fn rt_err_ident() -> Ident { Ident::new( |