aboutsummaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
Diffstat (limited to 'macros')
-rw-r--r--macros/src/codegen/module.rs74
-rw-r--r--macros/src/codegen/timer_queue.rs11
-rw-r--r--macros/src/codegen/util.rs5
3 files changed, 79 insertions, 11 deletions
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index 75435b54..fb028e01 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -264,15 +264,64 @@ pub fn codegen(
};
let user_imports = &app.user_imports;
+ let tq_marker = util::mark_internal_ident(&util::timer_queue_marker_ident());
items.push(quote!(
/// Holds methods related to this monotonic
pub mod #m {
+ #[allow(unused_imports)]
+ use #app_path::#tq_marker;
+ #[allow(unused_imports)]
+ use #app_path::#t;
#(
#[allow(unused_imports)]
#user_imports
)*
+ pub struct SpawnHandle {
+ #[doc(hidden)]
+ marker: u32,
+ }
+
+ // TODO: remove
+ impl core::fmt::Debug for SpawnHandle
+ {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ let handle = unsafe { &#app_path::#tq as *const _ as u32 };
+ f.debug_struct("SpawnHandle")
+ .field("marker", &self.marker)
+ .field("handle", &handle)
+ .finish()
+ }
+ }
+
+ impl SpawnHandle {
+ pub fn cancel(self) -> Result<#ty, ()> {
+ // TODO: Actually cancel...
+ // &mut #app_path::#tq;
+
+ Err(())
+ }
+
+ #[inline]
+ pub fn reschedule_after<D>(self, duration: D) -> Result<Self, ()>
+ where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint,
+ D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>,
+ {
+ self.reschedule_at(#app_path::#m::now() + duration)
+ }
+
+ pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result<Self, ()>
+ {
+ let _ = instant;
+
+ // TODO: Actually reschedule...
+ // &mut #app_path::#tq;
+
+ Err(())
+ }
+ }
+
#(#cfgs)*
/// Spawns the task after a set duration relative to the current time
///
@@ -281,7 +330,7 @@ pub fn codegen(
pub fn spawn_after<D>(
duration: D
#(,#args)*
- ) -> Result<(), #ty>
+ ) -> Result<SpawnHandle, #ty>
where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint,
D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>,
{
@@ -300,7 +349,7 @@ pub fn codegen(
pub fn spawn_at(
instant: rtic::time::Instant<#app_path::#mono_type>
#(,#args)*
- ) -> Result<(), #ty> {
+ ) -> Result<SpawnHandle, #ty> {
unsafe {
let input = #tupled;
if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
@@ -314,13 +363,17 @@ pub fn codegen(
.as_mut_ptr()
.write(instant);
- let nr = rtic::export::NotReady {
- instant,
- index,
- task: #app_path::#t::#name,
- };
+ rtic::export::interrupt::free(|_| {
+ let marker = #tq_marker;
+ let nr = rtic::export::NotReady {
+ instant,
+ index,
+ task: #app_path::#t::#name,
+ marker,
+ };
+
+ #tq_marker = #tq_marker.wrapping_add(1);
- rtic::export::interrupt::free(|_|
if let Some(mono) = #app_path::#m_ident.as_mut() {
#app_path::#tq.enqueue_unchecked(
nr,
@@ -331,9 +384,10 @@ pub fn codegen(
// 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(())
+ Ok(SpawnHandle { marker })
+ })
} else {
Err(input)
}
diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs
index 82d0ac98..33905516 100644
--- a/macros/src/codegen/timer_queue.rs
+++ b/macros/src/codegen/timer_queue.rs
@@ -9,6 +9,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
let mut items = vec![];
if !app.monotonics.is_empty() {
+ // Generate the marker counter used to track for `cancel` and `reschedule`
+ let tq_marker = util::mark_internal_ident(&util::timer_queue_marker_ident());
+ items.push(quote!(
+ // #[doc = #doc]
+ #[doc(hidden)]
+ #[allow(non_camel_case_types)]
+ static mut #tq_marker: u32 = 0;
+ ));
+
let t = util::schedule_t_ident();
// Enumeration of `schedule`-able tasks
@@ -32,7 +41,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
#[doc(hidden)]
#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
- enum #t {
+ pub enum #t {
#(#variants,)*
}
));
diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs
index 6589f62d..9ccdbf78 100644
--- a/macros/src/codegen/util.rs
+++ b/macros/src/codegen/util.rs
@@ -89,6 +89,11 @@ pub fn interrupt_ident() -> Ident {
Ident::new("interrupt", span)
}
+pub fn timer_queue_marker_ident() -> Ident {
+ let span = Span::call_site();
+ Ident::new("TIMER_QUEUE_MARKER", span)
+}
+
/// Whether `name` is an exception with configurable priority
pub fn is_exception(name: &Ident) -> bool {
let s = name.to_string();