diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index f0f403b21d..76641faed4 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 { diff --git a/src/tq.rs b/src/tq.rs index 541ffcd13b..a637007d28 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -29,6 +29,7 @@ where nr: NotReady, enable_interrupt: F1, pend_handler: F2, + mono: &mut Mono, ) where F1: FnOnce(), F2: FnOnce(), @@ -46,7 +47,8 @@ where .unwrap_or(true); if if_heap_max_greater_than_nr { if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE && is_empty { - // mem::transmute::<_, SYST>(()).enable_interrupt(); + // mem::transmute::<_, SYST>(()).enable_interrupt();A + mono.enable_timer(); enable_interrupt(); } @@ -108,6 +110,7 @@ where // The queue is empty, disable the interrupt. if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { disable_interrupt(); + mono.disable_timer(); } None