aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/module.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/module.rs')
-rw-r--r--macros/src/codegen/module.rs202
1 files changed, 116 insertions, 86 deletions
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index 29f27662..913588a2 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -206,44 +206,75 @@ pub fn codegen(
let device = &extra.device;
let enum_ = util::interrupt_ident();
- let interrupt = &analysis
- .interrupts
- .get(&priority)
- .expect("RTIC-ICE: interrupt identifer not found")
- .0;
+ let interrupt = if spawnee.is_async {
+ &analysis
+ .interrupts_async
+ .get(&priority)
+ .expect("RTIC-ICE: interrupt identifer not found")
+ .0
+ } else {
+ &analysis
+ .interrupts_normal
+ .get(&priority)
+ .expect("RTIC-ICE: interrupt identifer not found")
+ .0
+ };
let internal_spawn_ident = util::internal_task_ident(name, "spawn");
// Spawn caller
- items.push(quote!(
+ if spawnee.is_async {
+ let rq = util::rq_async_ident(name);
+ items.push(quote!(
- #(#cfgs)*
- /// Spawns the task directly
- #[allow(non_snake_case)]
- #[doc(hidden)]
- pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
- let input = #tupled;
-
- unsafe {
- if let Some(index) = rtic::export::interrupt::free(|_| (&mut *#fq.get_mut()).dequeue()) {
- (&mut *#inputs
- .get_mut())
- .get_unchecked_mut(usize::from(index))
- .as_mut_ptr()
- .write(input);
-
- rtic::export::interrupt::free(|_| {
- (&mut *#rq.get_mut()).enqueue_unchecked((#t::#name, index));
- });
- rtic::pend(#device::#enum_::#interrupt);
-
- Ok(())
- } else {
- Err(input)
+ #(#cfgs)*
+ /// Spawns the task directly
+ #[allow(non_snake_case)]
+ #[doc(hidden)]
+ pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
+ let input = #tupled;
+
+ unsafe {
+ let r = rtic::export::interrupt::free(|_| (&mut *#rq.get_mut()).enqueue(input));
+
+ if r.is_ok() {
+ rtic::pend(#device::#enum_::#interrupt);
+ }
+
+ r
+ }
+ }));
+ } else {
+ items.push(quote!(
+
+ #(#cfgs)*
+ /// Spawns the task directly
+ #[allow(non_snake_case)]
+ #[doc(hidden)]
+ pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
+ let input = #tupled;
+
+ unsafe {
+ if let Some(index) = rtic::export::interrupt::free(|_| (&mut *#fq.get_mut()).dequeue()) {
+ (&mut *#inputs
+ .get_mut())
+ .get_unchecked_mut(usize::from(index))
+ .as_mut_ptr()
+ .write(input);
+
+ rtic::export::interrupt::free(|_| {
+ (&mut *#rq.get_mut()).enqueue_unchecked((#t::#name, index));
+ });
+ rtic::pend(#device::#enum_::#interrupt);
+
+ Ok(())
+ } else {
+ Err(input)
+ }
}
- }
- }));
+ }));
+ }
module_items.push(quote!(
#(#cfgs)*
@@ -252,64 +283,62 @@ 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_ident = util::monotonic_ident(&monotonic_name);
- let m_isr = &monotonic.args.binds;
- let enum_ = util::interrupt_ident();
- let spawn_handle_string = format!("{}::SpawnHandle", m);
-
- let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" {
- (
- quote!(core::mem::transmute::<_, rtic::export::SYST>(()).enable_interrupt()),
- quote!(rtic::export::SCB::set_pendst()),
- )
- } else {
- let rt_err = util::rt_err_ident();
- (
- quote!(rtic::export::NVIC::unmask(#rt_err::#enum_::#m_isr)),
- quote!(rtic::pend(#rt_err::#enum_::#m_isr)),
- )
- };
-
- let tq_marker = &util::timer_queue_marker_ident();
-
- // For future use
- // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
- // items.push(quote!(#[doc = #doc]));
- let internal_spawn_handle_ident =
- util::internal_monotonics_ident(name, m, "SpawnHandle");
- let internal_spawn_at_ident = util::internal_monotonics_ident(name, m, "spawn_at");
- let internal_spawn_after_ident =
- util::internal_monotonics_ident(name, m, "spawn_after");
-
- if monotonic.args.default {
+ if !spawnee.is_async {
+ 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_ident = util::monotonic_ident(&monotonic_name);
+ let m_isr = &monotonic.args.binds;
+ let enum_ = util::interrupt_ident();
+ let spawn_handle_string = format!("{}::SpawnHandle", m);
+
+ let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" {
+ (
+ quote!(core::mem::transmute::<_, rtic::export::SYST>(()).enable_interrupt()),
+ quote!(rtic::export::SCB::set_pendst()),
+ )
+ } else {
+ let rt_err = util::rt_err_ident();
+ (
+ quote!(rtic::export::NVIC::unmask(#rt_err::#enum_::#m_isr)),
+ quote!(rtic::pend(#rt_err::#enum_::#m_isr)),
+ )
+ };
+
+ let tq_marker = &util::timer_queue_marker_ident();
+
+ let internal_spawn_handle_ident =
+ util::internal_monotonics_ident(name, m, "SpawnHandle");
+ let internal_spawn_at_ident = util::internal_monotonics_ident(name, m, "spawn_at");
+ let internal_spawn_after_ident =
+ util::internal_monotonics_ident(name, m, "spawn_after");
+
+ if monotonic.args.default {
+ module_items.push(quote!(
+ #[doc(inline)]
+ pub use #m::spawn_after;
+ #[doc(inline)]
+ pub use #m::spawn_at;
+ #[doc(inline)]
+ pub use #m::SpawnHandle;
+ ));
+ }
module_items.push(quote!(
- #[doc(inline)]
- pub use #m::spawn_after;
- #[doc(inline)]
- pub use #m::spawn_at;
- #[doc(inline)]
- pub use #m::SpawnHandle;
+ pub mod #m {
+ #[doc(inline)]
+ pub use super::super::#internal_spawn_after_ident as spawn_after;
+ #[doc(inline)]
+ pub use super::super::#internal_spawn_at_ident as spawn_at;
+ #[doc(inline)]
+ pub use super::super::#internal_spawn_handle_ident as SpawnHandle;
+ }
));
- }
- module_items.push(quote!(
- pub mod #m {
- #[doc(inline)]
- pub use super::super::#internal_spawn_after_ident as spawn_after;
- #[doc(inline)]
- pub use super::super::#internal_spawn_at_ident as spawn_at;
- #[doc(inline)]
- pub use super::super::#internal_spawn_handle_ident as SpawnHandle;
- }
- ));
- items.push(quote!(
+ items.push(quote!(
#(#cfgs)*
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
@@ -436,6 +465,7 @@ pub fn codegen(
}
}
));
+ }
}
}