Cancel and reschedule working

Support cfgs in the imports

Account for extern tasks
This commit is contained in:
Emil Fresk 2021-03-14 21:27:21 +01:00
parent 1087f2ee64
commit 53c407017f
7 changed files with 716 additions and 35 deletions

View file

@ -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,

View file

@ -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)];));

View file

@ -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.