From ef50aeb2e8245b69843280fabb62589c0716ffdd Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 3 Dec 2020 21:04:06 +0100 Subject: Save, init generation fixed --- macros/src/codegen/init.rs | 28 ++++++++++++++++++++++++++-- macros/src/codegen/module.rs | 6 ++++++ macros/src/codegen/post_init.rs | 3 +++ macros/src/codegen/util.rs | 8 ++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 6376ce3..6b57add 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -58,6 +58,24 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { } )); + let monotonic_types: Vec<_> = app + .monotonics + .iter() + .map(|(_, monotonic)| { + let mono = &monotonic.ty; + quote! {#mono} + }) + .collect(); + let monotonics = util::monotonics_ident(&name); + + root_init.push(quote!( + /// Monotonics used by the system + #[allow(non_snake_case)] + pub struct #monotonics( + #(#monotonic_types),* + ); + )); + let mut locals_pat = None; let mut locals_new = None; if !init.locals.is_empty() { @@ -72,10 +90,16 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let attrs = &init.attrs; let stmts = &init.stmts; let locals_pat = locals_pat.iter(); + + let mut user_init_return = vec![quote! {#name::LateResources}]; + if !app.monotonics.is_empty() { + user_init_return.push(quote! {#name::Monotonics}); + } + let user_init = Some(quote!( #(#attrs)* #[allow(non_snake_case)] - fn #name(#(#locals_pat,)* #context: #name::Context) -> #name::LateResources { + fn #name(#(#locals_pat,)* #context: #name::Context) -> (#(#user_init_return,)*) { #(#stmts)* } )); @@ -92,7 +116,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 = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), + quote!(let (late, 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 2ff4801..d398a1a 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -131,11 +131,17 @@ pub fn codegen( if let Context::Init = ctxt { let init = &app.inits.first().unwrap(); let late_resources = util::late_resources_ident(&init.name); + let monotonics = util::monotonics_ident(&init.name); items.push(quote!( #[doc(inline)] pub use super::#late_resources as LateResources; )); + + items.push(quote!( + #[doc(inline)] + pub use super::#monotonics as Monotonics; + )); } let doc = match ctxt { diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 5545944..9174dae 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -25,6 +25,9 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { } } + // Forget the monotonics so they won't be dropped. + stmts.push(quote!(core::mem::forget(monotonics);)); + // Enable the interrupts -- this completes the `init`-ialization phase stmts.push(quote!(rtic::export::interrupt::enable();)); diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index fb8f1a8..4273ee2 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -111,6 +111,14 @@ pub fn late_resources_ident(init: &Ident) -> Ident { ) } +/// Generates a pre-reexport identifier for the "monotonics" struct +pub fn monotonics_ident(init: &Ident) -> Ident { + Ident::new( + &format!("{}Monotonics", init.to_string()), + Span::call_site(), + ) +} + /// Mangle an ident pub fn mangle_ident(ident: &Ident) -> Ident { Ident::new( -- cgit v1.2.3 From b23bb1192c8dc1f2e8f157db2147b1737abc1033 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 8 Dec 2020 20:49:13 +0100 Subject: TQ handlers being generated --- macros/src/codegen/dispatchers.rs | 28 +++--- macros/src/codegen/hardware_tasks.rs | 17 ++-- macros/src/codegen/module.rs | 180 ++++++++++++++++++----------------- macros/src/codegen/pre_init.rs | 37 +++---- macros/src/codegen/software_tasks.rs | 25 ++--- macros/src/codegen/timer_queue.rs | 20 ++-- macros/src/codegen/util.rs | 6 +- 7 files changed, 163 insertions(+), 150 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index a6c695f..d0a3ba0 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -70,19 +70,21 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec::now();)), - Some(quote!(, instant)), - ) - } else { - (None, None) - }; + // let (let_instant, instant) = if let Some(ref m) = extra.monotonic { + // ( + // Some(quote!(let instant = <#m as rtic::Monotonic>::now();)), + // Some(quote!(, instant)), + // ) + // } else { + // (None, None) + // }; + let (let_instant, instant) = (quote!(), quote!()); let locals_new = if task.locals.is_empty() { quote!() diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index d398a1a..2c42adc 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -23,24 +23,25 @@ pub fn codegen( let mut lt = None; match ctxt { Context::Init => { - if let Some(m) = &extra.monotonic { - fields.push(quote!( - /// System start time = `Instant(0 /* cycles */)` - pub start: <#m as rtic::Monotonic>::Instant - )); - - values.push(quote!(start: <#m as rtic::Monotonic>::zero())); - - fields.push(quote!( - /// Core (Cortex-M) peripherals minus the SysTick - pub core: rtic::Peripherals - )); - } else { - fields.push(quote!( - /// Core (Cortex-M) peripherals - pub core: rtic::export::Peripherals - )); - } + // TODO: What fields are needed? + // if let Some(m) = &extra.monotonic { + // fields.push(quote!( + // /// System start time = `Instant(0 /* cycles */)` + // pub start: <#m as rtic::Monotonic>::Instant + // )); + + // values.push(quote!(start: <#m as rtic::Monotonic>::zero())); + + // fields.push(quote!( + // /// Core (Cortex-M) peripherals minus the SysTick + // pub core: rtic::Peripherals + // )); + // } else { + // fields.push(quote!( + // /// Core (Cortex-M) peripherals + // pub core: rtic::export::Peripherals + // )); + // } if extra.peripherals { let device = &extra.device; @@ -67,29 +68,31 @@ pub fn codegen( Context::Idle => {} Context::HardwareTask(..) => { - if let Some(m) = &extra.monotonic { - fields.push(quote!( - /// Time at which this handler started executing - pub start: <#m as rtic::Monotonic>::Instant - )); + // TODO: What fields are needed for monotonic? + // if let Some(m) = &extra.monotonic { + // fields.push(quote!( + // /// Time at which this handler started executing + // pub start: <#m as rtic::Monotonic>::Instant + // )); - values.push(quote!(start: instant)); + // values.push(quote!(start: instant)); - needs_instant = true; - } + // needs_instant = true; + // } } Context::SoftwareTask(..) => { - if let Some(m) = &extra.monotonic { - fields.push(quote!( - /// The time at which this task was scheduled to run - pub scheduled: <#m as rtic::Monotonic>::Instant - )); + // TODO: What fields are needed for monotonic? + // if let Some(m) = &extra.monotonic { + // fields.push(quote!( + // /// The time at which this task was scheduled to run + // pub scheduled: <#m as rtic::Monotonic>::Instant + // )); - values.push(quote!(scheduled: instant)); + // values.push(quote!(scheduled: instant)); - needs_instant = true; - } + // needs_instant = true; + // } } } @@ -152,11 +155,7 @@ pub fn codegen( }; let core = if ctxt.is_init() { - if extra.monotonic.is_some() { - Some(quote!(core: rtic::Peripherals,)) - } else { - Some(quote!(core: rtic::export::Peripherals,)) - } + Some(quote!(core: rtic::export::Peripherals,)) } else { None }; @@ -167,13 +166,15 @@ pub fn codegen( Some(quote!(priority: &#lt rtic::export::Priority)) }; - let instant = if needs_instant { - let m = extra.monotonic.clone().expect("RTIC-ICE: UNREACHABLE"); + // TODO: What is needed for the new monotonic? + // let instant = if needs_instant { + // let m = extra.monotonic.clone().expect("RTIC-ICE: UNREACHABLE"); - Some(quote!(, instant: <#m as rtic::Monotonic>::Instant)) - } else { - None - }; + // Some(quote!(, instant: <#m as rtic::Monotonic>::Instant)) + // } else { + // None + // }; + let instant = quote!(); items.push(quote!( /// Execution context @@ -250,50 +251,51 @@ pub fn codegen( })); - // Schedule caller - if let Some(m) = &extra.monotonic { - let instants = util::instants_ident(name); - - let tq = util::tq_ident(); - let t = util::schedule_t_ident(); - - items.push(quote!( - #(#cfgs)* - pub fn schedule( - instant: <#m as rtic::Monotonic>::Instant - #(,#args)* - ) -> Result<(), #ty> { - unsafe { - use rtic::Mutex as _; - use rtic::mutex_prelude::*; - - let input = #tupled; - if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { - #app_path::#inputs - .get_unchecked_mut(usize::from(index)) - .as_mut_ptr() - .write(input); - - #app_path::#instants - .get_unchecked_mut(usize::from(index)) - .as_mut_ptr() - .write(instant); - - let nr = rtic::export::NotReady { - instant, - index, - task: #app_path::#t::#name, - }; - - rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr)); - - Ok(()) - } else { - Err(input) - } - } - })); - } + // TODO: Needs updating for new monotonic. + // // Schedule caller + // if let Some(m) = &extra.monotonic { + // let instants = util::instants_ident(name); + + // let tq = util::tq_ident(); + // let t = util::schedule_t_ident(); + + // items.push(quote!( + // #(#cfgs)* + // pub fn schedule( + // instant: <#m as rtic::Monotonic>::Instant + // #(,#args)* + // ) -> Result<(), #ty> { + // unsafe { + // use rtic::Mutex as _; + // use rtic::mutex_prelude::*; + + // let input = #tupled; + // if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { + // #app_path::#inputs + // .get_unchecked_mut(usize::from(index)) + // .as_mut_ptr() + // .write(input); + + // #app_path::#instants + // .get_unchecked_mut(usize::from(index)) + // .as_mut_ptr() + // .write(instant); + + // let nr = rtic::export::NotReady { + // instant, + // index, + // task: #app_path::#t::#name, + // }; + + // rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr)); + + // Ok(()) + // } else { + // Err(input) + // } + // } + // })); + // } } if !items.is_empty() { diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index 969de84..dfdb30a 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -74,24 +74,25 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec>(); - if let Some(m) = &extra.monotonic { - let instants = util::instants_ident(name); - - let uninit = mk_uninit(); - mod_app.push(quote!( - #uninit - /// Buffer that holds the instants associated to the inputs of a task - static mut #instants: - [core::mem::MaybeUninit<<#m as rtic::Monotonic>::Instant>; #cap_lit] = - [#(#elems,)*]; - )); - } + // TODO: Update for new monotonic + // if let Some(m) = &extra.monotonic { + // let instants = util::instants_ident(name); + + // let uninit = mk_uninit(); + // mod_app.push(quote!( + // #uninit + // /// Buffer that holds the instants associated to the inputs of a task + // static mut #instants: + // [core::mem::MaybeUninit<<#m as rtic::Monotonic>::Instant>; #cap_lit] = + // [#(#elems,)*]; + // )); + // } let uninit = mk_uninit(); let inputs_ident = util::inputs_ident(name); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index fa2c7b3..ccde957 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -8,7 +8,7 @@ use crate::{analyze::Analysis, check::Extra, codegen::util}; pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { let mut items = vec![]; - if let Some(m) = &extra.monotonic { + if !app.monotonics.is_empty() { let t = util::schedule_t_ident(); // Enumeration of `schedule`-able tasks @@ -36,12 +36,17 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec Vec>(); - let sys_tick = util::suffixed("SysTick"); + let bound_interrupt = &monotonic.args.binds; items.push(quote!( #[no_mangle] - unsafe fn #sys_tick() { + unsafe fn #bound_interrupt() { use rtic::Mutex as _; while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue()) @@ -106,5 +113,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Ident { } /// Generates an identifier for a timer queue -/// -/// At most there is one timer queue -pub fn tq_ident() -> Ident { - Ident::new(&"TQ".to_string(), Span::call_site()) +pub fn tq_ident(name: &str) -> Ident { + Ident::new(&format!("TQ_{}", name), Span::call_site()) } -- cgit v1.2.3 From 97a48983d2859740983cbf342e1287182426ed44 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 10 Dec 2020 20:33:13 +0100 Subject: More work --- macros/src/codegen/assertions.rs | 8 +- macros/src/codegen/dispatchers.rs | 2 +- macros/src/codegen/init.rs | 53 +--------- macros/src/codegen/module.rs | 212 +++++++++++++++++++------------------- macros/src/codegen/pre_init.rs | 39 +++---- macros/src/codegen/timer_queue.rs | 2 +- 6 files changed, 138 insertions(+), 178 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/assertions.rs b/macros/src/codegen/assertions.rs index 4d9aae4..a8a4491 100644 --- a/macros/src/codegen/assertions.rs +++ b/macros/src/codegen/assertions.rs @@ -2,9 +2,10 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use crate::analyze::Analysis; +use rtic_syntax::ast::App; /// Generates compile-time assertions that check that types implement the `Send` / `Sync` traits -pub fn codegen(analysis: &Analysis) -> Vec { +pub fn codegen(app: &App, analysis: &Analysis) -> Vec { let mut stmts = vec![]; for ty in &analysis.send_types { @@ -15,5 +16,10 @@ pub fn codegen(analysis: &Analysis) -> Vec { stmts.push(quote!(rtic::export::assert_sync::<#ty>();)); } + for (_, monotonic) in &app.monotonics { + let ty = &monotonic.ty; + stmts.push(quote!(rtic::export::assert_monotonic::<#ty>();)); + } + stmts } diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index d0a3ba0..01fb511 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -5,7 +5,7 @@ use rtic_syntax::ast::App; use crate::{analyze::Analysis, check::Extra, codegen::util}; /// Generates task dispatchers -pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { +pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec { let mut items = vec![]; let interrupts = &analysis.interrupts; diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 6b57add..66c3bc4 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -5,7 +5,7 @@ use rtic_syntax::{ast::App, Context}; use crate::{ analyze::Analysis, check::Extra, - codegen::{locals, module, resources_struct, util}, + codegen::{locals, module, resources_struct}, }; type CodegenResult = ( @@ -32,50 +32,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let mut root_init = vec![]; - let late_fields = analysis - .late_resources - .iter() - .flat_map(|resources| { - resources.iter().map(|name| { - let ty = &app.late_resources[name].ty; - let cfgs = &app.late_resources[name].cfgs; - - quote!( - #(#cfgs)* - pub #name: #ty - ) - }) - }) - .collect::>(); - - let late_resources = util::late_resources_ident(&name); - - root_init.push(quote!( - /// Resources initialized at runtime - #[allow(non_snake_case)] - pub struct #late_resources { - #(#late_fields),* - } - )); - - let monotonic_types: Vec<_> = app - .monotonics - .iter() - .map(|(_, monotonic)| { - let mono = &monotonic.ty; - quote! {#mono} - }) - .collect(); - let monotonics = util::monotonics_ident(&name); - - root_init.push(quote!( - /// Monotonics used by the system - #[allow(non_snake_case)] - pub struct #monotonics( - #(#monotonic_types),* - ); - )); - let mut locals_pat = None; let mut locals_new = None; if !init.locals.is_empty() { @@ -91,15 +47,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let stmts = &init.stmts; let locals_pat = locals_pat.iter(); - let mut user_init_return = vec![quote! {#name::LateResources}]; - if !app.monotonics.is_empty() { - user_init_return.push(quote! {#name::Monotonics}); - } + let user_init_return = quote! {#name::LateResources, #name::Monotonics}; let user_init = Some(quote!( #(#attrs)* #[allow(non_snake_case)] - fn #name(#(#locals_pat,)* #context: #name::Context) -> (#(#user_init_return,)*) { + fn #name(#(#locals_pat,)* #context: #name::Context) -> (#user_init_return) { #(#stmts)* } )); diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 2c42adc..6dd6e9a 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -19,29 +19,13 @@ pub fn codegen( let name = ctxt.ident(app); - let mut needs_instant = false; let mut lt = None; match ctxt { Context::Init => { - // TODO: What fields are needed? - // if let Some(m) = &extra.monotonic { - // fields.push(quote!( - // /// System start time = `Instant(0 /* cycles */)` - // pub start: <#m as rtic::Monotonic>::Instant - // )); - - // values.push(quote!(start: <#m as rtic::Monotonic>::zero())); - - // fields.push(quote!( - // /// Core (Cortex-M) peripherals minus the SysTick - // pub core: rtic::Peripherals - // )); - // } else { - // fields.push(quote!( - // /// Core (Cortex-M) peripherals - // pub core: rtic::export::Peripherals - // )); - // } + fields.push(quote!( + /// Core (Cortex-M) peripherals + pub core: rtic::export::Peripherals + )); if extra.peripherals { let device = &extra.device; @@ -68,31 +52,11 @@ pub fn codegen( Context::Idle => {} Context::HardwareTask(..) => { - // TODO: What fields are needed for monotonic? - // if let Some(m) = &extra.monotonic { - // fields.push(quote!( - // /// Time at which this handler started executing - // pub start: <#m as rtic::Monotonic>::Instant - // )); - - // values.push(quote!(start: instant)); - - // needs_instant = true; - // } + // None for now. } Context::SoftwareTask(..) => { - // TODO: What fields are needed for monotonic? - // if let Some(m) = &extra.monotonic { - // fields.push(quote!( - // /// The time at which this task was scheduled to run - // pub scheduled: <#m as rtic::Monotonic>::Instant - // )); - - // values.push(quote!(scheduled: instant)); - - // needs_instant = true; - // } + // None for now. } } @@ -132,18 +96,45 @@ pub fn codegen( } if let Context::Init = ctxt { - let init = &app.inits.first().unwrap(); - let late_resources = util::late_resources_ident(&init.name); - let monotonics = util::monotonics_ident(&init.name); + let late_fields = analysis + .late_resources + .iter() + .flat_map(|resources| { + resources.iter().map(|name| { + let ty = &app.late_resources[name].ty; + let cfgs = &app.late_resources[name].cfgs; + + quote!( + #(#cfgs)* + pub #name: #ty + ) + }) + }) + .collect::>(); items.push(quote!( - #[doc(inline)] - pub use super::#late_resources as LateResources; + /// Resources initialized at runtime + #[allow(non_snake_case)] + pub struct LateResources { + #(#late_fields),* + } )); + let monotonic_types: Vec<_> = app + .monotonics + .iter() + .map(|(_, monotonic)| { + let mono = &monotonic.ident; + quote! {#mono} + }) + .collect(); + items.push(quote!( - #[doc(inline)] - pub use super::#monotonics as Monotonics; + /// Monotonics used by the system + #[allow(non_snake_case)] + pub struct Monotonics( + #(#monotonic_types),* + ); )); } @@ -166,16 +157,6 @@ pub fn codegen( Some(quote!(priority: &#lt rtic::export::Priority)) }; - // TODO: What is needed for the new monotonic? - // let instant = if needs_instant { - // let m = extra.monotonic.clone().expect("RTIC-ICE: UNREACHABLE"); - - // Some(quote!(, instant: <#m as rtic::Monotonic>::Instant)) - // } else { - // None - // }; - let instant = quote!(); - items.push(quote!( /// Execution context pub struct Context<#lt> { @@ -184,7 +165,7 @@ pub fn codegen( impl<#lt> Context<#lt> { #[inline(always)] - pub unsafe fn new(#core #priority #instant) -> Self { + pub unsafe fn new(#core #priority) -> Self { Context { #(#values,)* } @@ -202,7 +183,7 @@ pub fn codegen( let cfgs = &spawnee.cfgs; // Store a copy of the task cfgs task_cfgs = cfgs.clone(); - let (args, tupled, _untupled, ty) = util::regroup_inputs(&spawnee.inputs); + let (args, tupled, untupled, ty) = util::regroup_inputs(&spawnee.inputs); let args = &args; let tupled = &tupled; let fq = util::fq_ident(name); @@ -251,51 +232,70 @@ pub fn codegen( })); - // TODO: Needs updating for new monotonic. - // // Schedule caller - // if let Some(m) = &extra.monotonic { - // let instants = util::instants_ident(name); - - // let tq = util::tq_ident(); - // let t = util::schedule_t_ident(); - - // items.push(quote!( - // #(#cfgs)* - // pub fn schedule( - // instant: <#m as rtic::Monotonic>::Instant - // #(,#args)* - // ) -> Result<(), #ty> { - // unsafe { - // use rtic::Mutex as _; - // use rtic::mutex_prelude::*; - - // let input = #tupled; - // if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { - // #app_path::#inputs - // .get_unchecked_mut(usize::from(index)) - // .as_mut_ptr() - // .write(input); - - // #app_path::#instants - // .get_unchecked_mut(usize::from(index)) - // .as_mut_ptr() - // .write(instant); - - // let nr = rtic::export::NotReady { - // instant, - // index, - // task: #app_path::#t::#name, - // }; - - // rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr)); - - // Ok(()) - // } else { - // Err(input) - // } - // } - // })); - // } + // Schedule caller + for (_, monotonic) in &app.monotonics { + let instants = util::instants_ident(name); + + let tq = util::tq_ident(&monotonic.ident.to_string()); + let t = util::schedule_t_ident(); + let m = &monotonic.ident; + + if monotonic.args.default { + items.push(quote!(pub use #m::spawn_after;)); + items.push(quote!(pub use #m::spawn_at;)); + } + + items.push(quote!( + pub mod #m { + #(#cfgs)* + pub fn spawn_after( + duration: rtic::Duration, + #(,#args)* + ) -> Result<(), #ty> { + let instant = <#app_path::#m as rtic::Monotonic>::now(); + + spawn_at(instant + duration, #(,#untupled)*) + } + + #(#cfgs)* + pub fn spawn_at( + instant: Instant<#app_path::#m as rtic::Monotonic> + #(,#args)* + ) -> Result<(), #ty> { + unsafe { + use rtic::Mutex as _; + use rtic::mutex_prelude::*; + + let input = #tupled; + if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { + #app_path::#inputs + .get_unchecked_mut(usize::from(index)) + .as_mut_ptr() + .write(input); + + #app_path::#instants + .get_unchecked_mut(usize::from(index)) + .as_mut_ptr() + .write(instant); + + let nr = rtic::export::NotReady { + instant, + index, + task: #app_path::#t::#name, + }; + + rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr)); + + // TODO: After adding the scheduled task, check and setup the timer. + + Ok(()) + } else { + Err(input) + } + } + } + })); + } } if !items.is_empty() { diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index dfdb30a..26ba558 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -74,25 +74,26 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec { +pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec { let mut items = vec![]; if !app.monotonics.is_empty() { -- cgit v1.2.3 From 8e8ec9b7b879adae8d4de6cb2320b9b19290a7e0 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 12 Dec 2020 23:24:54 +0100 Subject: Monotonic codegen now passing compile stage --- macros/src/codegen/dispatchers.rs | 19 +------------------ macros/src/codegen/module.rs | 21 ++++++++++++--------- macros/src/codegen/software_tasks.rs | 29 ++++++++++++++++------------- macros/src/codegen/timer_queue.rs | 8 ++++++-- macros/src/codegen/util.rs | 20 ++------------------ 5 files changed, 37 insertions(+), 60 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index 01fb511..d3adee0 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -70,22 +70,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec { let #tupled = #inputs.get_unchecked(usize::from(index)).as_ptr().read(); - #let_instant #fq.split().0.enqueue_unchecked(index); let priority = &rtic::export::Priority::new(PRIORITY); #app_path::#name( #locals_new - #name::Context::new(priority #instant) + #name::Context::new(priority) #(,#pats)* ) } diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 6dd6e9a..0f495d9 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -18,6 +18,8 @@ pub fn codegen( let mut task_cfgs = vec![]; let name = ctxt.ident(app); + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; let mut lt = None; match ctxt { @@ -125,7 +127,7 @@ pub fn codegen( .iter() .map(|(_, monotonic)| { let mono = &monotonic.ident; - quote! {#mono} + quote! {#app_path::#mono} }) .collect(); @@ -190,9 +192,6 @@ pub fn codegen( let rq = util::rq_ident(priority); let inputs = util::inputs_ident(name); - let app_name = &app.name; - let app_path = quote! {crate::#app_name}; - let device = &extra.device; let enum_ = util::interrupt_ident(); let interrupt = &analysis @@ -234,11 +233,13 @@ pub fn codegen( // Schedule caller for (_, monotonic) in &app.monotonics { - let instants = util::instants_ident(name); + let instants = util::monotonic_instants_ident(name, &monotonic.ident); let tq = util::tq_ident(&monotonic.ident.to_string()); let t = util::schedule_t_ident(); let m = &monotonic.ident; + let m_isr = &monotonic.args.binds; + let enum_ = util::interrupt_ident(); if monotonic.args.default { items.push(quote!(pub use #m::spawn_after;)); @@ -259,7 +260,7 @@ pub fn codegen( #(#cfgs)* pub fn spawn_at( - instant: Instant<#app_path::#m as rtic::Monotonic> + instant: rtic::Instant<#app_path::#m> #(,#args)* ) -> Result<(), #ty> { unsafe { @@ -284,9 +285,11 @@ pub fn codegen( task: #app_path::#t::#name, }; - rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr)); - - // TODO: After adding the scheduled task, check and setup the timer. + rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( + nr, + || rtic::export::NVIC::unmask(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), + || rtic::pend(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), + )); Ok(()) } else { diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index 7b884ea..ebe7bdf 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -57,19 +57,22 @@ pub fn codegen( .map(|_| quote!(core::mem::MaybeUninit::uninit())) .collect::>(); - // TODO: Update for new monotonic - // if let Some(m) = &extra.monotonic { - // let instants = util::instants_ident(name); - - // let uninit = mk_uninit(); - // mod_app.push(quote!( - // #uninit - // /// Buffer that holds the instants associated to the inputs of a task - // static mut #instants: - // [core::mem::MaybeUninit<<#m as rtic::Monotonic>::Instant>; #cap_lit] = - // [#(#elems,)*]; - // )); - // } + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; + + for (_, monotonic) in &app.monotonics { + let instants = util::monotonic_instants_ident(name, &monotonic.ident); + let m = &monotonic.ident; + + let uninit = mk_uninit(); + mod_app.push(quote!( + #uninit + /// Buffer that holds the instants associated to the inputs of a task + static mut #instants: + [core::mem::MaybeUninit>; #cap_lit] = + [#(#elems,)*]; + )); + } let uninit = mk_uninit(); let inputs_ident = util::inputs_ident(name); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index f219eef..dc29835 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -67,6 +67,8 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec Vec>(); let bound_interrupt = &monotonic.args.binds; + items.push(quote!( #[no_mangle] unsafe fn #bound_interrupt() { use rtic::Mutex as _; - while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue()) + while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue( + || rtic::export::NVIC::unmask(you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#bound_interrupt), + )) { match task { #(#arms)* diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index d9310dd..329a7dd 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -77,8 +77,8 @@ pub fn inputs_ident(task: &Ident) -> Ident { } /// Generates an identifier for the `INSTANTS` buffer (`schedule` API) -pub fn instants_ident(task: &Ident) -> Ident { - Ident::new(&format!("{}_INSTANTS", task), Span::call_site()) +pub fn monotonic_instants_ident(task: &Ident, monotonic: &Ident) -> Ident { + Ident::new(&format!("{}_{}_INSTANTS", task, monotonic), Span::call_site()) } pub fn interrupt_ident() -> Ident { @@ -103,22 +103,6 @@ pub fn is_exception(name: &Ident) -> bool { ) } -/// Generates a pre-reexport identifier for the "late resources" struct -pub fn late_resources_ident(init: &Ident) -> Ident { - Ident::new( - &format!("{}LateResources", init.to_string()), - Span::call_site(), - ) -} - -/// Generates a pre-reexport identifier for the "monotonics" struct -pub fn monotonics_ident(init: &Ident) -> Ident { - Ident::new( - &format!("{}Monotonics", init.to_string()), - Span::call_site(), - ) -} - /// Mangle an ident pub fn mangle_ident(ident: &Ident) -> Ident { Ident::new( -- cgit v1.2.3 From 1c8de78f6f6e9e265d9d894d2ebde622bf16d44e Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 12 Dec 2020 23:31:05 +0100 Subject: Cleanup --- macros/src/codegen/hardware_tasks.rs | 14 +------------- macros/src/codegen/util.rs | 5 ++++- 2 files changed, 5 insertions(+), 14 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs index db3ab3a..4a1d749 100644 --- a/macros/src/codegen/hardware_tasks.rs +++ b/macros/src/codegen/hardware_tasks.rs @@ -29,16 +29,6 @@ pub fn codegen( let mut user_tasks = vec![]; for (name, task) in &app.hardware_tasks { - // let (let_instant, instant) = if let Some(ref m) = extra.monotonic { - // ( - // Some(quote!(let instant = <#m as rtic::Monotonic>::now();)), - // Some(quote!(, instant)), - // ) - // } else { - // (None, None) - // }; - let (let_instant, instant) = (quote!(), quote!()); - let locals_new = if task.locals.is_empty() { quote!() } else { @@ -56,12 +46,10 @@ pub fn codegen( unsafe fn #symbol() { const PRIORITY: u8 = #priority; - #let_instant - rtic::export::run(PRIORITY, || { #app_path::#name( #locals_new - #name::Context::new(&rtic::export::Priority::new(PRIORITY) #instant) + #name::Context::new(&rtic::export::Priority::new(PRIORITY)) ) }); } diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 329a7dd..a201dfe 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -78,7 +78,10 @@ pub fn inputs_ident(task: &Ident) -> Ident { /// Generates an identifier for the `INSTANTS` buffer (`schedule` API) pub fn monotonic_instants_ident(task: &Ident, monotonic: &Ident) -> Ident { - Ident::new(&format!("{}_{}_INSTANTS", task, monotonic), Span::call_site()) + Ident::new( + &format!("{}_{}_INSTANTS", task, monotonic), + Span::call_site(), + ) } pub fn interrupt_ident() -> Ident { -- cgit v1.2.3 From 35b4ec0d0435879cca97536b5c866fc2ac2e9210 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 00:06:50 +0100 Subject: Reexport embedded-time as rtic::time --- macros/src/codegen/module.rs | 4 ++-- macros/src/codegen/software_tasks.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 0f495d9..2b6042c 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -250,7 +250,7 @@ pub fn codegen( pub mod #m { #(#cfgs)* pub fn spawn_after( - duration: rtic::Duration, + duration: rtic::time::duration::Duration, #(,#args)* ) -> Result<(), #ty> { let instant = <#app_path::#m as rtic::Monotonic>::now(); @@ -260,7 +260,7 @@ pub fn codegen( #(#cfgs)* pub fn spawn_at( - instant: rtic::Instant<#app_path::#m> + instant: rtic::time::Instant<#app_path::#m> #(,#args)* ) -> Result<(), #ty> { unsafe { diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index ebe7bdf..53de50b 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -69,7 +69,7 @@ pub fn codegen( #uninit /// Buffer that holds the instants associated to the inputs of a task static mut #instants: - [core::mem::MaybeUninit>; #cap_lit] = + [core::mem::MaybeUninit>; #cap_lit] = [#(#elems,)*]; )); } -- cgit v1.2.3 From 62771839061aaa7dd518d40969bee609d7d2bda8 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 14:52:16 +0100 Subject: Now handling SysTick as well --- macros/src/codegen/module.rs | 17 +++++++++++++++-- macros/src/codegen/pre_init.rs | 32 ++++++++++++++++++++++---------- macros/src/codegen/timer_queue.rs | 12 ++++++++++-- macros/src/codegen/util.rs | 11 ++++++++++- 4 files changed, 57 insertions(+), 15 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 2b6042c..bf77c4d 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -246,6 +246,19 @@ pub fn codegen( items.push(quote!(pub use #m::spawn_at;)); } + let (unmask, pend) = if &*m_isr.to_string() == "SysTick" { + ( + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()), + quote!(cortex_m::peripheral::SCB::set_pendst()), + ) + } else { + let rt_err = util::rt_err_ident(); + ( + quote!(rtic::export::NVIC::unmask(#app_path::#rt_err::#enum_::#m_isr)), + quote!(rtic::pend(#app_path::#rt_err::#enum_::#m_isr)), + ) + }; + items.push(quote!( pub mod #m { #(#cfgs)* @@ -287,8 +300,8 @@ pub fn codegen( rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( nr, - || rtic::export::NVIC::unmask(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), - || rtic::pend(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), + || #unmask, + || #pend, )); Ok(()) diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index 26ba558..e7b1b03 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -8,6 +8,8 @@ use crate::{analyze::Analysis, check::Extra, codegen::util}; pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { let mut stmts = vec![]; + let rt_err = util::rt_err_ident(); + // Disable interrupts -- `init` must run with interrupts disabled stmts.push(quote!(rtic::export::interrupt::disable();)); @@ -47,14 +49,14 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec Vec Vec 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()) + } else { + quote!(rtic::export::NVIC::mask(#rt_err::#enum_::#bound_interrupt)) + }; items.push(quote!( #[no_mangle] @@ -106,7 +114,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Ident { /// Generates an identifier for the `enum` of `schedule`-able tasks pub fn schedule_t_ident() -> Ident { - Ident::new(&"SCHED_T".to_string(), Span::call_site()) + Ident::new(&"SCHED_T", Span::call_site()) } /// Generates an identifier for the `enum` of `spawn`-able tasks @@ -228,6 +228,7 @@ pub fn spawn_t_ident(priority: u8) -> Ident { Ident::new(&format!("P{}_T", priority), Span::call_site()) } +/// Suffixed identifier pub fn suffixed(name: &str) -> Ident { let span = Span::call_site(); Ident::new(name, span) @@ -237,3 +238,11 @@ pub fn suffixed(name: &str) -> Ident { pub fn tq_ident(name: &str) -> Ident { Ident::new(&format!("TQ_{}", name), Span::call_site()) } + +/// The name to get better RT flag errors +pub fn rt_err_ident() -> Ident { + Ident::new( + &"you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml", + Span::call_site(), + ) +} -- cgit v1.2.3 From aaa92ea2fac23d2679b5efc1178a45d994762bca Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 17:48:11 +0100 Subject: Cleanup --- macros/src/codegen/module.rs | 7 ------- macros/src/codegen/timer_queue.rs | 4 ---- 2 files changed, 11 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index bf77c4d..d15b5ec 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -204,10 +204,6 @@ pub fn codegen( items.push(quote!( #(#cfgs)* pub fn spawn(#(#args,)*) -> Result<(), #ty> { - // #let_instant // do we need it? - use rtic::Mutex as _; - use rtic::mutex_prelude::*; - let input = #tupled; unsafe { @@ -277,9 +273,6 @@ pub fn codegen( #(,#args)* ) -> Result<(), #ty> { unsafe { - use rtic::Mutex as _; - use rtic::mutex_prelude::*; - let input = #tupled; if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { #app_path::#inputs diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index ef0fda3..99dfa5b 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -68,8 +68,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec Date: Thu, 4 Feb 2021 20:22:02 +0100 Subject: Minor fixes --- macros/src/codegen/module.rs | 11 +++++++---- macros/src/codegen/post_init.rs | 4 ++++ macros/src/codegen/timer_queue.rs | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index d15b5ec..93fbeae 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -135,7 +135,7 @@ pub fn codegen( /// Monotonics used by the system #[allow(non_snake_case)] pub struct Monotonics( - #(#monotonic_types),* + #(pub #monotonic_types),* ); )); } @@ -258,10 +258,13 @@ pub fn codegen( items.push(quote!( pub mod #m { #(#cfgs)* - pub fn spawn_after( - duration: rtic::time::duration::Duration, + pub fn spawn_after( + duration: D, #(,#args)* - ) -> Result<(), #ty> { + ) -> Result<(), #ty> + where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, + D::T: Into<<#app_path::#m as rtic::time::Clock>::T>, + { let instant = <#app_path::#m as rtic::Monotonic>::now(); spawn_at(instant + duration, #(,#untupled)*) diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 9174dae..9268e04 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -25,6 +25,10 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { } } + for (monotonic, _) in app.monotonics.iter() { + stmts.push(quote!(#monotonic::reset();)); + } + // Forget the monotonics so they won't be dropped. stmts.push(quote!(core::mem::forget(monotonics);)); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 99dfa5b..9a430a0 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -108,6 +108,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Thu, 18 Feb 2021 19:30:59 +0100 Subject: Now with new monotonic trait and crate --- macros/src/codegen/init.rs | 2 +- macros/src/codegen/module.rs | 16 +++++++++------- macros/src/codegen/post_init.rs | 18 ++++++++++++------ macros/src/codegen/pre_init.rs | 20 ++++++++++++++++---- macros/src/codegen/software_tasks.rs | 2 +- macros/src/codegen/timer_queue.rs | 21 +++++++++++++++++---- macros/src/codegen/util.rs | 10 ++++++++++ 7 files changed, 66 insertions(+), 23 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 66c3bc4..aa9adcb 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 93fbeae..f0f403b 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 9268e04..b6cf47c 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 { } } - 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 e7b1b03..fbfff3b 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 Vec(()) + .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 Vec Vec); + + 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>(); 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 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( -- cgit v1.2.3 From 1a46345a2aa710c4ec5ea8fb6589424bc4450d0f Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 21 Feb 2021 16:15:34 +0100 Subject: Fixed UB in generated `Monotonic::now()` --- macros/src/codegen/post_init.rs | 2 +- macros/src/codegen/timer_queue.rs | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index b6cf47c..8ebcb12 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -35,7 +35,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { // Store the monotonic let name = util::monotonic_ident(&monotonic.to_string()); - stmts.push(quote!(#name.as_mut_ptr().write(monotonics.#idx);)); + stmts.push(quote!(#name = Some(monotonics.#idx);)); } // Enable the interrupts -- this completes the `init`-ialization phase diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 54b2c1f..6556068 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -69,11 +69,11 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let mono_ty = quote!(Option<#m>); items.push(quote!( #[doc = #doc] - static mut #mono: #mono_ty = core::mem::MaybeUninit::uninit(); + static mut #mono: #mono_ty = None; )); } @@ -122,10 +122,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Sun, 21 Feb 2021 21:57:18 +0100 Subject: Properly call `on_interrupt` --- macros/src/codegen/timer_queue.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 6556068..ea2fee6 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -136,6 +136,10 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Mon, 22 Feb 2021 20:59:03 +0100 Subject: Added enable/disable timer calls --- macros/src/codegen/module.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index f0f403b..76641fa 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -230,11 +230,13 @@ pub fn codegen( // Schedule caller for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); + let monotonic_name = monotonic.ident.to_string(); 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_mangled = util::mangle_monotonic_type(&monotonic_name); + let m_ident = util::monotonic_ident(&monotonic_name); let m_isr = &monotonic.args.binds; let enum_ = util::interrupt_ident(); @@ -296,11 +298,18 @@ pub fn codegen( task: #app_path::#t::#name, }; - rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( - nr, - || #enable_interrupt, - || #pend, - )); + rtic::export::interrupt::free(|_| + if let Some(mono) = #app_path::#m_ident.as_mut() { + #app_path::#tq.enqueue_unchecked( + nr, + || #enable_interrupt, + || #pend, + mono) + } else { + // We can only use the timer queue if `init` has returned, and it + // writes the `Some(monotonic)` we are accessing here. + core::hint::unreachable_unchecked() + }); Ok(()) } else { -- cgit v1.2.3 From 26870ae12ede1a70ca5685a7c0e0113c6bed58dd Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 22 Feb 2021 21:45:22 +0100 Subject: Use zero time in init for `spawn_after` to not cause panic --- macros/src/codegen/module.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 76641fa..b0ac65f 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -269,7 +269,12 @@ pub fn codegen( where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, D::T: Into<<#app_path::#m_mangled as rtic::time::Clock>::T>, { - let instant = #app_path::#m::now(); + + let instant = if rtic::export::interrupt::free(|_| unsafe { #app_path::#m_ident.is_none() }) { + rtic::time::Instant::new(0) + } else { + #app_path::#m::now() + }; spawn_at(instant + duration, #(,#untupled)*) } -- cgit v1.2.3 From cd3484cbab3c4cd7e483e8de19bcdd9498443412 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 23 Feb 2021 19:35:26 +0100 Subject: GHA update Fmt fixes Spawn_after did not work with parameters Examples working again Revert "GHA update" This reverts commit e0a71d4859966a6c5cf2629d3cb27e88acada9c0. Readd flags Only add DWT based dep with __v7 flag --- macros/src/codegen/module.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index b0ac65f..e480b86 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -263,7 +263,7 @@ pub fn codegen( pub mod #m { #(#cfgs)* pub fn spawn_after( - duration: D, + duration: D #(,#args)* ) -> Result<(), #ty> where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, @@ -276,7 +276,7 @@ pub fn codegen( #app_path::#m::now() }; - spawn_at(instant + duration, #(,#untupled)*) + spawn_at(instant + duration #(,#untupled)*) } #(#cfgs)* -- cgit v1.2.3 From 767d46e05bbc88eb3c236cf468f9432c7fe0ce05 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 25 Feb 2021 17:32:12 +0100 Subject: Review fixes --- macros/src/codegen/module.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index e480b86..25260be 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -53,13 +53,9 @@ pub fn codegen( Context::Idle => {} - Context::HardwareTask(..) => { - // None for now. - } + Context::HardwareTask(_) => {} - Context::SoftwareTask(..) => { - // None for now. - } + Context::SoftwareTask(_) => {} } if ctxt.has_locals(app) { -- cgit v1.2.3 From d351f55e1c8e60a9bbd69b40b84a39dab5d20051 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 25 Feb 2021 19:05:39 +0100 Subject: Documentation generation fixes Test fixes --- macros/src/codegen/dispatchers.rs | 24 ++++++++++++++---------- macros/src/codegen/locals.rs | 1 + macros/src/codegen/module.rs | 28 +++++++++++++++++++++++----- macros/src/codegen/post_init.rs | 3 ++- macros/src/codegen/pre_init.rs | 22 ++++++++++++---------- macros/src/codegen/resources.rs | 3 ++- macros/src/codegen/resources_struct.rs | 3 ++- macros/src/codegen/software_tasks.rs | 21 ++++++++++++--------- macros/src/codegen/timer_queue.rs | 24 ++++++++++++++---------- macros/src/codegen/util.rs | 9 ++------- 10 files changed, 84 insertions(+), 54 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index d3adee0..dc33b1a 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -26,15 +26,16 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec>(); - let doc = format!( - "Software tasks to be dispatched at priority level {}", - level, - ); + // let doc = format!( + // "Software tasks to be dispatched at priority level {}", + // level, + // ); let t = util::spawn_t_ident(level); items.push(quote!( #[allow(non_camel_case_types)] #[derive(Clone, Copy)] - #[doc = #doc] + // #[doc = #doc] + #[doc(hidden)] pub enum #t { #(#variants,)* } @@ -42,6 +43,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec), @@ -51,12 +53,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec Result<(), #ty> { let input = #tupled; @@ -226,13 +231,16 @@ pub fn codegen( // Schedule caller for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); + let instants = util::mark_internal_ident(&instants); let monotonic_name = monotonic.ident.to_string(); let tq = util::tq_ident(&monotonic.ident.to_string()); + let tq = util::mark_internal_ident(&tq); let t = util::schedule_t_ident(); let m = &monotonic.ident; - let m_mangled = util::mangle_monotonic_type(&monotonic_name); + let mono_type = &monotonic.ty; let m_ident = util::monotonic_ident(&monotonic_name); + let m_ident = util::mark_internal_ident(&m_ident); let m_isr = &monotonic.args.binds; let enum_ = util::interrupt_ident(); @@ -255,15 +263,24 @@ pub fn codegen( ) }; + let user_imports = &app.user_imports; + items.push(quote!( + /// Holds methods related to this monotonic pub mod #m { + #( + #[allow(unused_imports)] + #user_imports + )* + #(#cfgs)* + /// Spawns the task after a set duration relative to the current time pub fn spawn_after( duration: D #(,#args)* ) -> Result<(), #ty> where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, - D::T: Into<<#app_path::#m_mangled as rtic::time::Clock>::T>, + D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>, { let instant = if rtic::export::interrupt::free(|_| unsafe { #app_path::#m_ident.is_none() }) { @@ -276,8 +293,9 @@ pub fn codegen( } #(#cfgs)* + /// Spawns the task at a fixed time instant pub fn spawn_at( - instant: rtic::time::Instant<#app_path::#m_mangled> + instant: rtic::time::Instant<#app_path::#mono_type> #(,#args)* ) -> Result<(), #ty> { unsafe { diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 8ebcb12..96c5df8 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -13,7 +13,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { if !analysis.late_resources.is_empty() { // BTreeSet wrapped in a vector for name in analysis.late_resources.first().unwrap() { - let mangled_name = util::mangle_ident(&name); + let mangled_name = util::mark_internal_ident(&name); // If it's live let cfgs = app.late_resources[name].cfgs.clone(); if analysis.locations.get(name).is_some() { @@ -35,6 +35,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { // Store the monotonic let name = util::monotonic_ident(&monotonic.to_string()); + let name = util::mark_internal_ident(&name); stmts.push(quote!(#name = Some(monotonics.#idx);)); } diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index fbfff3b..d510544 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -17,6 +17,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec Vec::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { core::mem::transmute::<_, cortex_m::peripheral::SYST>(()) .enable_interrupt(); } @@ -107,13 +109,13 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { + rtic::export::NVIC::unmask(#app_path::#rt_err::#interrupt::#binds); } )); } diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs index 76871e5..fa52b86 100644 --- a/macros/src/codegen/resources.rs +++ b/macros/src/codegen/resources.rs @@ -21,7 +21,7 @@ pub fn codegen( for (name, res, expr, _) in app.resources(analysis) { let cfgs = &res.cfgs; let ty = &res.ty; - let mangled_name = util::mangle_ident(&name); + let mangled_name = util::mark_internal_ident(&name); { let section = if expr.is_none() { @@ -42,6 +42,7 @@ pub fn codegen( let attrs = &res.attrs; mod_app.push(quote!( #[allow(non_upper_case_globals)] + #[doc(hidden)] #(#attrs)* #(#cfgs)* #section diff --git a/macros/src/codegen/resources_struct.rs b/macros/src/codegen/resources_struct.rs index bffe943..8ed8a29 100644 --- a/macros/src/codegen/resources_struct.rs +++ b/macros/src/codegen/resources_struct.rs @@ -31,7 +31,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, None }; let ty = &res.ty; - let mangled_name = util::mangle_ident(&name); + let mangled_name = util::mark_internal_ident(&name); // let ownership = &analysis.ownerships[name]; let r_prop = &res.properties; @@ -112,6 +112,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, let doc = format!("Resources `{}` has access to", ctxt.ident(app)); let ident = util::resources_ident(ctxt, app); + let ident = util::mark_internal_ident(&ident); let item = quote!( #[allow(non_snake_case)] #[doc = #doc] diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index a760b06..a39fe4c 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -37,6 +37,7 @@ pub fn codegen( // Create free queues and inputs / instants buffers let fq = util::fq_ident(name); + let fq = util::mark_internal_ident(&fq); let (fq_ty, fq_expr, mk_uninit): (_, _, Box Option<_>>) = { ( @@ -48,8 +49,9 @@ pub fn codegen( ) }; mod_app.push(quote!( - /// Queue version of a free-list that keeps track of empty slots in - /// the following buffers + // /// Queue version of a free-list that keeps track of empty slots in + // /// the following buffers + #[doc(hidden)] static mut #fq: #fq_ty = #fq_expr; )); @@ -57,28 +59,29 @@ pub fn codegen( .map(|_| quote!(core::mem::MaybeUninit::uninit())) .collect::>(); - let app_name = &app.name; - let app_path = quote! {crate::#app_name}; - for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); - let m = util::mangle_monotonic_type(&monotonic.ident.to_string()); + let instants = util::mark_internal_ident(&instants); + let mono_type = &monotonic.ty; let uninit = mk_uninit(); mod_app.push(quote!( #uninit - /// Buffer that holds the instants associated to the inputs of a task + // /// Buffer that holds the instants associated to the inputs of a task + #[doc(hidden)] static mut #instants: - [core::mem::MaybeUninit>; #cap_lit] = + [core::mem::MaybeUninit>; #cap_lit] = [#(#elems,)*]; )); } let uninit = mk_uninit(); let inputs_ident = util::inputs_ident(name); + let inputs_ident = util::mark_internal_ident(&inputs_ident); mod_app.push(quote!( #uninit - /// Buffer that holds the inputs of a task + // /// Buffer that holds the inputs of a task + #[doc(hidden)] static mut #inputs_ident: [core::mem::MaybeUninit<#input_ty>; #cap_lit] = [#(#elems,)*]; )); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index ea2fee6..82d0ac9 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -26,9 +26,10 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec>(); - let doc = "Tasks that can be scheduled".to_string(); + // let doc = "Tasks that can be scheduled".to_string(); items.push(quote!( - #[doc = #doc] + // #[doc = #doc] + #[doc(hidden)] #[allow(non_camel_case_types)] #[derive(Clone, Copy)] enum #t { @@ -41,25 +42,27 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let tq_ty = quote!(rtic::export::TimerQueue<#mono_type, #t, #n>); items.push(quote!( - #[doc = #doc] + #[doc(hidden)] static mut #tq: #tq_ty = rtic::export::TimerQueue( rtic::export::BinaryHeap( rtic::export::iBinaryHeap::new() @@ -68,12 +71,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let mono = util::mark_internal_ident(&mono); + // let doc = &format!("Storage for {}", monotonic_name); items.push(quote!( - #[doc = #doc] - static mut #mono: #mono_ty = None; + #[doc(hidden)] + static mut #mono: Option<#mono_type> = None; )); } @@ -89,6 +92,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec bool { ) } -/// Mangle an ident -pub fn mangle_ident(ident: &Ident) -> Ident { +/// Mark an ident as internal +pub fn mark_internal_ident(ident: &Ident) -> Ident { Ident::new( &format!("__rtic_internal_{}", ident.to_string()), Span::call_site(), @@ -244,11 +244,6 @@ 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( -- cgit v1.2.3 From 08a37d6d3d7e7f599c7d5b2723ed15d8355963d1 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 2 Mar 2021 19:31:47 +0100 Subject: Updated `spawn_after` docs --- macros/src/codegen/module.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 41f5b22..75435b5 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -275,6 +275,9 @@ pub fn codegen( #(#cfgs)* /// Spawns the task after a set duration relative to the current time + /// + /// This will use the time `Instant::new(0)` as baseline if called in `#[init]`, + /// so if you use a non-resetable timer use `spawn_at` when in `#[init]` pub fn spawn_after( duration: D #(,#args)* -- cgit v1.2.3