mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-19 14:25:18 +01:00
Cancel and reschedule working
Support cfgs in the imports Account for extern tasks
This commit is contained in:
parent
1087f2ee64
commit
53c407017f
7 changed files with 716 additions and 35 deletions
|
|
@ -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;
|
||||
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);
|
||||
|
||||
Err(())
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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)];));
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue