Enable at least masking out a Monotonic

Simplest case working, but leaves a lot to ask
as shown by examples/cfg-monotonic.rs

Current `rtic-syntax` is unable to validate and
handle the `cfgs[]` which limits the usefulness
of this.
This commit is contained in:
Henrik Tjäder 2023-01-22 03:03:24 +01:00
parent 3240fb332a
commit be74469ab7
6 changed files with 40 additions and 10 deletions

View file

View file

@ -108,6 +108,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
.map(|(_, monotonic)| { .map(|(_, monotonic)| {
let name = &monotonic.ident; let name = &monotonic.ident;
let name_str = &name.to_string(); let name_str = &name.to_string();
let cfgs = &monotonic.cfgs;
let ident = util::monotonic_ident(name_str); let ident = util::monotonic_ident(name_str);
let doc = &format!( let doc = &format!(
"This module holds the static implementation for `{}::now()`", "This module holds the static implementation for `{}::now()`",
@ -115,7 +116,10 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
); );
let default_monotonic = if monotonic.args.default { let default_monotonic = if monotonic.args.default {
quote!(pub use #name::now;) quote!(
#(#cfgs)*
pub use #name::now;
)
} else { } else {
quote!() quote!()
}; };
@ -125,6 +129,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
#[doc = #doc] #[doc = #doc]
#[allow(non_snake_case)] #[allow(non_snake_case)]
#(#cfgs)*
pub mod #name { pub mod #name {
/// Read the current time from this monotonic /// Read the current time from this monotonic

View file

@ -116,8 +116,12 @@ pub fn codegen(
.monotonics .monotonics
.iter() .iter()
.map(|(_, monotonic)| { .map(|(_, monotonic)| {
let cfgs = &monotonic.cfgs;
let mono = &monotonic.ty; let mono = &monotonic.ty;
quote! {#mono} quote! {
#(#cfgs)*
pub #mono
}
}) })
.collect(); .collect();
@ -128,7 +132,7 @@ pub fn codegen(
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct #internal_monotonics_ident( pub struct #internal_monotonics_ident(
#(pub #monotonic_types),* #(#monotonic_types),*
); );
)); ));
@ -226,8 +230,8 @@ pub fn codegen(
// Spawn caller // Spawn caller
items.push(quote!( items.push(quote!(
#(#cfgs)*
/// Spawns the task directly /// Spawns the task directly
#(#cfgs)*
pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> { pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
let input = #tupled; let input = #tupled;
@ -267,6 +271,7 @@ pub fn codegen(
let tq = util::tq_ident(&monotonic.ident.to_string()); let tq = util::tq_ident(&monotonic.ident.to_string());
let t = util::schedule_t_ident(); let t = util::schedule_t_ident();
let m = &monotonic.ident; let m = &monotonic.ident;
let cfgs = &monotonic.cfgs;
let m_ident = util::monotonic_ident(&monotonic_name); let m_ident = util::monotonic_ident(&monotonic_name);
let m_isr = &monotonic.args.binds; let m_isr = &monotonic.args.binds;
let enum_ = util::interrupt_ident(); let enum_ = util::interrupt_ident();
@ -298,13 +303,17 @@ pub fn codegen(
if monotonic.args.default { if monotonic.args.default {
module_items.push(quote!( module_items.push(quote!(
#(#cfgs)*
pub use #m::spawn_after; pub use #m::spawn_after;
#(#cfgs)*
pub use #m::spawn_at; pub use #m::spawn_at;
#(#cfgs)*
pub use #m::SpawnHandle; pub use #m::SpawnHandle;
)); ));
} }
module_items.push(quote!( module_items.push(quote!(
#[doc(hidden)] #[doc(hidden)]
#(#cfgs)*
pub mod #m { pub mod #m {
pub use super::super::#internal_spawn_after_ident as spawn_after; pub use super::super::#internal_spawn_after_ident as spawn_after;
pub use super::super::#internal_spawn_at_ident as spawn_at; pub use super::super::#internal_spawn_at_ident as spawn_at;
@ -322,6 +331,7 @@ pub fn codegen(
marker: u32, marker: u32,
} }
#(#cfgs)*
impl core::fmt::Debug for #internal_spawn_handle_ident { impl core::fmt::Debug for #internal_spawn_handle_ident {
#[doc(hidden)] #[doc(hidden)]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
@ -353,6 +363,7 @@ pub fn codegen(
/// Reschedule after /// Reschedule after
#[inline] #[inline]
#(#cfgs)*
pub fn reschedule_after( pub fn reschedule_after(
self, self,
duration: <#m as rtic::Monotonic>::Duration duration: <#m as rtic::Monotonic>::Duration
@ -361,6 +372,7 @@ pub fn codegen(
} }
/// Reschedule at /// Reschedule at
#(#cfgs)*
pub fn reschedule_at( pub fn reschedule_at(
self, self,
instant: <#m as rtic::Monotonic>::Instant instant: <#m as rtic::Monotonic>::Instant
@ -376,11 +388,11 @@ pub fn codegen(
} }
} }
#(#cfgs)*
/// Spawns the task after a set duration relative to the current time /// 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]`, /// 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]` /// so if you use a non-resetable timer use `spawn_at` when in `#[init]`
#(#cfgs)*
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn #internal_spawn_after_ident( pub fn #internal_spawn_after_ident(
duration: <#m as rtic::Monotonic>::Duration duration: <#m as rtic::Monotonic>::Duration

View file

@ -43,21 +43,28 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
} }
} }
for (i, (monotonic, _)) in app.monotonics.iter().enumerate() { for (i, (monotonic_ident, monotonic)) in app.monotonics.iter().enumerate() {
// For future use // For future use
// let doc = format!(" RTIC internal: {}:{}", file!(), line!()); // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
// stmts.push(quote!(#[doc = #doc])); // stmts.push(quote!(#[doc = #doc]));
let cfgs = &monotonic.cfgs;
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
let idx = Index { let idx = Index {
index: i as u32, index: i as u32,
span: Span::call_site(), span: Span::call_site(),
}; };
stmts.push(quote!(monotonics.#idx.reset();)); stmts.push(quote!(
#(#cfgs)*
monotonics.#idx.reset();
));
// Store the monotonic // Store the monotonic
let name = util::monotonic_ident(&monotonic.to_string()); let name = util::monotonic_ident(&monotonic_ident.to_string());
stmts.push(quote!(#name.get_mut().write(Some(monotonics.#idx));)); stmts.push(quote!(
#(#cfgs)*
#name.get_mut().write(Some(monotonics.#idx));
));
} }
// Enable the interrupts -- this completes the `init`-ialization phase // Enable the interrupts -- this completes the `init`-ialization phase

View file

@ -62,6 +62,7 @@ pub fn codegen(
for (_, monotonic) in &app.monotonics { for (_, monotonic) in &app.monotonics {
let instants = util::monotonic_instants_ident(name, &monotonic.ident); let instants = util::monotonic_instants_ident(name, &monotonic.ident);
let mono_type = &monotonic.ty; let mono_type = &monotonic.ty;
let cfgs = &monotonic.cfgs;
let uninit = mk_uninit(); let uninit = mk_uninit();
// For future use // For future use
@ -73,6 +74,7 @@ pub fn codegen(
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
#[doc(hidden)] #[doc(hidden)]
#(#cfgs)*
static #instants: static #instants:
rtic::RacyCell<[core::mem::MaybeUninit<<#mono_type as rtic::Monotonic>::Instant>; #cap_lit]> = rtic::RacyCell<[core::mem::MaybeUninit<<#mono_type as rtic::Monotonic>::Instant>; #cap_lit]> =
rtic::RacyCell::new([#(#elems,)*]); rtic::RacyCell::new([#(#elems,)*]);

View file

@ -13,7 +13,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
// Generate the marker counter used to track for `cancel` and `reschedule` // Generate the marker counter used to track for `cancel` and `reschedule`
let tq_marker = util::timer_queue_marker_ident(); let tq_marker = util::timer_queue_marker_ident();
items.push(quote!( items.push(quote!(
// #[doc = #doc]
#[doc(hidden)] #[doc(hidden)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
@ -56,6 +55,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
let tq = util::tq_ident(&monotonic_name); let tq = util::tq_ident(&monotonic_name);
let t = util::schedule_t_ident(); let t = util::schedule_t_ident();
let mono_type = &monotonic.ty; let mono_type = &monotonic.ty;
let cfgs = &monotonic.cfgs;
let m_ident = util::monotonic_ident(&monotonic_name); let m_ident = util::monotonic_ident(&monotonic_name);
// Static variables and resource proxy // Static variables and resource proxy
@ -76,6 +76,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
#[doc(hidden)] #[doc(hidden)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
#(#cfgs)*
static #tq: rtic::RacyCell<#tq_ty> = static #tq: rtic::RacyCell<#tq_ty> =
rtic::RacyCell::new(rtic::export::TimerQueue(rtic::export::SortedLinkedList::new_u16())); rtic::RacyCell::new(rtic::export::TimerQueue(rtic::export::SortedLinkedList::new_u16()));
)); ));
@ -88,6 +89,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
#[doc(hidden)] #[doc(hidden)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
#(#cfgs)*
static #mono: rtic::RacyCell<Option<#mono_type>> = rtic::RacyCell::new(None); static #mono: rtic::RacyCell<Option<#mono_type>> = rtic::RacyCell::new(None);
)); ));
} }
@ -126,6 +128,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let cfgs = &monotonic.cfgs;
let bound_interrupt = &monotonic.args.binds; let bound_interrupt = &monotonic.args.binds;
let disable_isr = if &*bound_interrupt.to_string() == "SysTick" { let disable_isr = if &*bound_interrupt.to_string() == "SysTick" {
quote!(core::mem::transmute::<_, rtic::export::SYST>(()).disable_interrupt()) quote!(core::mem::transmute::<_, rtic::export::SYST>(()).disable_interrupt())
@ -136,6 +139,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
items.push(quote!( items.push(quote!(
#[no_mangle] #[no_mangle]
#[allow(non_snake_case)] #[allow(non_snake_case)]
#(#cfgs)*
unsafe fn #bound_interrupt() { unsafe fn #bound_interrupt() {
while let Some((task, index)) = rtic::export::interrupt::free(|_| while let Some((task, index)) = rtic::export::interrupt::free(|_|
if let Some(mono) = (&mut *#m_ident.get_mut()).as_mut() { if let Some(mono) = (&mut *#m_ident.get_mut()).as_mut() {