aboutsummaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
authorGravatar Emil Fresk <emil.fresk@gmail.com> 2021-03-14 21:27:21 +0100
committerGravatar Emil Fresk <emil.fresk@gmail.com> 2021-03-20 08:19:56 +0100
commit53c407017f50d0fde17d38afed714b2fcb54194b (patch)
treeed4e5a8b95896e07e0a6d4209844665d9a678324 /macros/src
parent1087f2ee64a5be1aedf3b702ccb5d86cc64708d9 (diff)
downloadrtic-53c407017f50d0fde17d38afed714b2fcb54194b.tar.gz
rtic-53c407017f50d0fde17d38afed714b2fcb54194b.tar.zst
rtic-53c407017f50d0fde17d38afed714b2fcb54194b.zip
Cancel and reschedule working
Support cfgs in the imports Account for extern tasks
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/codegen/module.rs67
-rw-r--r--macros/src/codegen/pre_init.rs12
-rw-r--r--macros/src/codegen/timer_queue.rs11
3 files changed, 70 insertions, 20 deletions
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index fb028e01..5a594c66 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -21,6 +21,33 @@ pub fn codegen(
let app_name = &app.name;
let app_path = quote! {crate::#app_name};
+ let all_task_names: Vec<_> = app
+ .software_tasks
+ .iter()
+ .map(|(name, st)| {
+ if !st.is_extern {
+ let cfgs = &st.cfgs;
+ quote! {
+ #(#cfgs)*
+ #[allow(unused_imports)]
+ use #app_path::#name as #name;
+ }
+ } else {
+ quote!()
+ }
+ })
+ .chain(app.hardware_tasks.iter().map(|(name, ht)| {
+ if !ht.is_extern {
+ quote! {
+ #[allow(unused_imports)]
+ use #app_path::#name as #name;
+ }
+ } else {
+ quote!()
+ }
+ }))
+ .collect();
+
let mut lt = None;
match ctxt {
Context::Init => {
@@ -202,6 +229,9 @@ pub fn codegen(
// Spawn caller
items.push(quote!(
+
+ #(#all_task_names)*
+
#(#cfgs)*
/// Spawns the task directly
pub fn spawn(#(#args,)*) -> Result<(), #ty> {
@@ -247,6 +277,7 @@ pub fn codegen(
if monotonic.args.default {
items.push(quote!(pub use #m::spawn_after;));
items.push(quote!(pub use #m::spawn_at;));
+ items.push(quote!(pub use #m::SpawnHandle;));
}
let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" {
@@ -269,6 +300,11 @@ pub fn codegen(
items.push(quote!(
/// Holds methods related to this monotonic
pub mod #m {
+ // #(
+ // #[allow(unused_imports)]
+ // use #app_path::#all_task_names as #all_task_names;
+ // )*
+ use super::*;
#[allow(unused_imports)]
use #app_path::#tq_marker;
#[allow(unused_imports)]
@@ -297,10 +333,19 @@ pub fn codegen(
impl SpawnHandle {
pub fn cancel(self) -> Result<#ty, ()> {
- // TODO: Actually cancel...
- // &mut #app_path::#tq;
-
- Err(())
+ rtic::export::interrupt::free(|_| unsafe {
+ let tq = &mut *#app_path::#tq.as_mut_ptr();
+ if let Some((_task, index)) = tq.cancel_marker(self.marker) {
+ // Get the message
+ let msg = #app_path::#inputs.get_unchecked(usize::from(index)).as_ptr().read();
+ // Return the index to the free queue
+ #app_path::#fq.split().0.enqueue_unchecked(index);
+
+ Ok(msg)
+ } else {
+ Err(())
+ }
+ })
}
#[inline]
@@ -313,12 +358,14 @@ pub fn codegen(
pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result<Self, ()>
{
- let _ = instant;
+ rtic::export::interrupt::free(|_| unsafe {
+ let marker = #tq_marker;
+ #tq_marker = #tq_marker.wrapping_add(1);
- // TODO: Actually reschedule...
- // &mut #app_path::#tq;
+ let tq = &mut *#app_path::#tq.as_mut_ptr();
- Err(())
+ tq.update_marker(self.marker, marker, instant, || #pend).map(|_| SpawnHandle { marker })
+ })
}
}
@@ -374,8 +421,10 @@ pub fn codegen(
#tq_marker = #tq_marker.wrapping_add(1);
+ let tq = unsafe { &mut *#app_path::#tq.as_mut_ptr() };
+
if let Some(mono) = #app_path::#m_ident.as_mut() {
- #app_path::#tq.enqueue_unchecked(
+ tq.enqueue_unchecked(
nr,
|| #enable_interrupt,
|| #pend,
diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs
index d5105445..287f41a4 100644
--- a/macros/src/codegen/pre_init.rs
+++ b/macros/src/codegen/pre_init.rs
@@ -77,12 +77,16 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
);));
}
- // Initialize monotonic's interrupts
- for (_, monotonic) in app.monotonics.iter()
- //.map(|(ident, monotonic)| (ident, &monotonic.args.priority, &monotonic.args.binds))
- {
+ // Initialize monotonic's interrupts and timer queues
+ for (_, monotonic) in &app.monotonics {
let priority = &monotonic.args.priority;
let binds = &monotonic.args.binds;
+ let monotonic_name = monotonic.ident.to_string();
+ let tq = util::tq_ident(&monotonic_name);
+ let tq = util::mark_internal_ident(&tq);
+
+ // Initialize timer queues
+ stmts.push(quote!(#tq.as_mut_ptr().write(rtic::export::TimerQueue::new());));
// Compile time assert that this priority is supported by the device
stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs
index 33905516..0d2c51ea 100644
--- a/macros/src/codegen/timer_queue.rs
+++ b/macros/src/codegen/timer_queue.rs
@@ -68,15 +68,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
.map(|(_name, task)| task.args.capacity)
.sum();
let n = util::capacity_typenum(cap, false);
- let tq_ty = quote!(rtic::export::TimerQueue<#mono_type, #t, #n>);
+ let tq_ty =
+ quote!(core::mem::MaybeUninit<rtic::export::TimerQueue<#mono_type, #t, #n>>);
items.push(quote!(
#[doc(hidden)]
- static mut #tq: #tq_ty = rtic::export::TimerQueue(
- rtic::export::BinaryHeap(
- rtic::export::iBinaryHeap::new()
- )
- );
+ static mut #tq: #tq_ty = core::mem::MaybeUninit::uninit();
));
let mono = util::monotonic_ident(&monotonic_name);
@@ -138,7 +135,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
while let Some((task, index)) = rtic::export::interrupt::free(|_|
if let Some(mono) = #app_path::#m_ident.as_mut() {
- #tq.dequeue(|| #disable_isr, mono)
+ (&mut *#tq.as_mut_ptr()).dequeue(|| #disable_isr, mono)
} else {
// We can only use the timer queue if `init` has returned, and it
// writes the `Some(monotonic)` we are accessing here.