mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
TQ handlers being generated
This commit is contained in:
parent
ef50aeb2e8
commit
b23bb1192c
10 changed files with 157 additions and 140 deletions
|
@ -6,7 +6,7 @@
|
|||
use panic_semihosting as _; // panic handler
|
||||
use rtic::app;
|
||||
|
||||
#[app(device = lm3s6965)]
|
||||
#[app(device = lm3s6965, dispatchers = [UART])]
|
||||
mod app {
|
||||
#[monotonic(binds = SomeISR1)]
|
||||
type Mono1 = hal::Mono1;
|
||||
|
@ -17,5 +17,11 @@ mod app {
|
|||
#[init]
|
||||
fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) {
|
||||
}
|
||||
|
||||
#[task]
|
||||
fn task1(_: task1::Context) {}
|
||||
|
||||
#[task]
|
||||
fn task2(_: task2::Context) {}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use syn::{parse, Path};
|
|||
|
||||
pub struct Extra {
|
||||
pub device: Path,
|
||||
pub monotonic: Option<Path>,
|
||||
pub peripherals: bool,
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,6 @@ pub fn app(app: &App, _analysis: &Analysis) -> parse::Result<Extra> {
|
|||
if let Some(device) = app.args.device.clone() {
|
||||
Ok(Extra {
|
||||
device,
|
||||
monotonic: None,
|
||||
peripherals: app.args.peripherals,
|
||||
})
|
||||
} else {
|
||||
|
|
|
@ -70,19 +70,21 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
let inputs = util::inputs_ident(name);
|
||||
let (_, tupled, pats, _) = util::regroup_inputs(&task.inputs);
|
||||
|
||||
let (let_instant, instant) = if extra.monotonic.is_some() {
|
||||
let instants = util::instants_ident(name);
|
||||
// TODO: Fix for new monotonics
|
||||
// let (let_instant, instant) = if extra.monotonic.is_some() {
|
||||
// let instants = util::instants_ident(name);
|
||||
|
||||
(
|
||||
quote!(
|
||||
let instant =
|
||||
#instants.get_unchecked(usize::from(index)).as_ptr().read();
|
||||
),
|
||||
quote!(, instant),
|
||||
)
|
||||
} else {
|
||||
(quote!(), quote!())
|
||||
};
|
||||
// (
|
||||
// quote!(
|
||||
// let instant =
|
||||
// #instants.get_unchecked(usize::from(index)).as_ptr().read();
|
||||
// ),
|
||||
// quote!(, instant),
|
||||
// )
|
||||
// } else {
|
||||
// (quote!(), quote!())
|
||||
// };
|
||||
let (let_instant, instant) = (quote!(), quote!());
|
||||
|
||||
let locals_new = if task.locals.is_empty() {
|
||||
quote!()
|
||||
|
|
|
@ -29,14 +29,15 @@ pub fn codegen(
|
|||
let mut user_tasks = vec![];
|
||||
|
||||
for (name, task) in &app.hardware_tasks {
|
||||
let (let_instant, instant) = if let Some(ref m) = extra.monotonic {
|
||||
(
|
||||
Some(quote!(let instant = <#m as rtic::Monotonic>::now();)),
|
||||
Some(quote!(, instant)),
|
||||
)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
// let (let_instant, instant) = if let Some(ref m) = extra.monotonic {
|
||||
// (
|
||||
// Some(quote!(let instant = <#m as rtic::Monotonic>::now();)),
|
||||
// Some(quote!(, instant)),
|
||||
// )
|
||||
// } else {
|
||||
// (None, None)
|
||||
// };
|
||||
let (let_instant, instant) = (quote!(), quote!());
|
||||
|
||||
let locals_new = if task.locals.is_empty() {
|
||||
quote!()
|
||||
|
|
|
@ -23,24 +23,25 @@ pub fn codegen(
|
|||
let mut lt = None;
|
||||
match ctxt {
|
||||
Context::Init => {
|
||||
if let Some(m) = &extra.monotonic {
|
||||
fields.push(quote!(
|
||||
/// System start time = `Instant(0 /* cycles */)`
|
||||
pub start: <#m as rtic::Monotonic>::Instant
|
||||
));
|
||||
// TODO: What fields are needed?
|
||||
// if let Some(m) = &extra.monotonic {
|
||||
// fields.push(quote!(
|
||||
// /// System start time = `Instant(0 /* cycles */)`
|
||||
// pub start: <#m as rtic::Monotonic>::Instant
|
||||
// ));
|
||||
|
||||
values.push(quote!(start: <#m as rtic::Monotonic>::zero()));
|
||||
// values.push(quote!(start: <#m as rtic::Monotonic>::zero()));
|
||||
|
||||
fields.push(quote!(
|
||||
/// Core (Cortex-M) peripherals minus the SysTick
|
||||
pub core: rtic::Peripherals
|
||||
));
|
||||
} else {
|
||||
fields.push(quote!(
|
||||
/// Core (Cortex-M) peripherals
|
||||
pub core: rtic::export::Peripherals
|
||||
));
|
||||
}
|
||||
// fields.push(quote!(
|
||||
// /// Core (Cortex-M) peripherals minus the SysTick
|
||||
// pub core: rtic::Peripherals
|
||||
// ));
|
||||
// } else {
|
||||
// fields.push(quote!(
|
||||
// /// Core (Cortex-M) peripherals
|
||||
// pub core: rtic::export::Peripherals
|
||||
// ));
|
||||
// }
|
||||
|
||||
if extra.peripherals {
|
||||
let device = &extra.device;
|
||||
|
@ -67,29 +68,31 @@ pub fn codegen(
|
|||
Context::Idle => {}
|
||||
|
||||
Context::HardwareTask(..) => {
|
||||
if let Some(m) = &extra.monotonic {
|
||||
fields.push(quote!(
|
||||
/// Time at which this handler started executing
|
||||
pub start: <#m as rtic::Monotonic>::Instant
|
||||
));
|
||||
// TODO: What fields are needed for monotonic?
|
||||
// if let Some(m) = &extra.monotonic {
|
||||
// fields.push(quote!(
|
||||
// /// Time at which this handler started executing
|
||||
// pub start: <#m as rtic::Monotonic>::Instant
|
||||
// ));
|
||||
|
||||
values.push(quote!(start: instant));
|
||||
// values.push(quote!(start: instant));
|
||||
|
||||
needs_instant = true;
|
||||
}
|
||||
// needs_instant = true;
|
||||
// }
|
||||
}
|
||||
|
||||
Context::SoftwareTask(..) => {
|
||||
if let Some(m) = &extra.monotonic {
|
||||
fields.push(quote!(
|
||||
/// The time at which this task was scheduled to run
|
||||
pub scheduled: <#m as rtic::Monotonic>::Instant
|
||||
));
|
||||
// TODO: What fields are needed for monotonic?
|
||||
// if let Some(m) = &extra.monotonic {
|
||||
// fields.push(quote!(
|
||||
// /// The time at which this task was scheduled to run
|
||||
// pub scheduled: <#m as rtic::Monotonic>::Instant
|
||||
// ));
|
||||
|
||||
values.push(quote!(scheduled: instant));
|
||||
// values.push(quote!(scheduled: instant));
|
||||
|
||||
needs_instant = true;
|
||||
}
|
||||
// needs_instant = true;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,11 +155,7 @@ pub fn codegen(
|
|||
};
|
||||
|
||||
let core = if ctxt.is_init() {
|
||||
if extra.monotonic.is_some() {
|
||||
Some(quote!(core: rtic::Peripherals,))
|
||||
} else {
|
||||
Some(quote!(core: rtic::export::Peripherals,))
|
||||
}
|
||||
Some(quote!(core: rtic::export::Peripherals,))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -167,13 +166,15 @@ pub fn codegen(
|
|||
Some(quote!(priority: &#lt rtic::export::Priority))
|
||||
};
|
||||
|
||||
let instant = if needs_instant {
|
||||
let m = extra.monotonic.clone().expect("RTIC-ICE: UNREACHABLE");
|
||||
// TODO: What is needed for the new monotonic?
|
||||
// let instant = if needs_instant {
|
||||
// let m = extra.monotonic.clone().expect("RTIC-ICE: UNREACHABLE");
|
||||
|
||||
Some(quote!(, instant: <#m as rtic::Monotonic>::Instant))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
// Some(quote!(, instant: <#m as rtic::Monotonic>::Instant))
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
let instant = quote!();
|
||||
|
||||
items.push(quote!(
|
||||
/// Execution context
|
||||
|
@ -250,50 +251,51 @@ pub fn codegen(
|
|||
|
||||
}));
|
||||
|
||||
// Schedule caller
|
||||
if let Some(m) = &extra.monotonic {
|
||||
let instants = util::instants_ident(name);
|
||||
// TODO: Needs updating for new monotonic.
|
||||
// // Schedule caller
|
||||
// if let Some(m) = &extra.monotonic {
|
||||
// let instants = util::instants_ident(name);
|
||||
|
||||
let tq = util::tq_ident();
|
||||
let t = util::schedule_t_ident();
|
||||
// let tq = util::tq_ident();
|
||||
// let t = util::schedule_t_ident();
|
||||
|
||||
items.push(quote!(
|
||||
#(#cfgs)*
|
||||
pub fn schedule(
|
||||
instant: <#m as rtic::Monotonic>::Instant
|
||||
#(,#args)*
|
||||
) -> Result<(), #ty> {
|
||||
unsafe {
|
||||
use rtic::Mutex as _;
|
||||
use rtic::mutex_prelude::*;
|
||||
// items.push(quote!(
|
||||
// #(#cfgs)*
|
||||
// pub fn schedule(
|
||||
// instant: <#m as rtic::Monotonic>::Instant
|
||||
// #(,#args)*
|
||||
// ) -> Result<(), #ty> {
|
||||
// unsafe {
|
||||
// use rtic::Mutex as _;
|
||||
// use rtic::mutex_prelude::*;
|
||||
|
||||
let input = #tupled;
|
||||
if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
|
||||
#app_path::#inputs
|
||||
.get_unchecked_mut(usize::from(index))
|
||||
.as_mut_ptr()
|
||||
.write(input);
|
||||
// let input = #tupled;
|
||||
// if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
|
||||
// #app_path::#inputs
|
||||
// .get_unchecked_mut(usize::from(index))
|
||||
// .as_mut_ptr()
|
||||
// .write(input);
|
||||
|
||||
#app_path::#instants
|
||||
.get_unchecked_mut(usize::from(index))
|
||||
.as_mut_ptr()
|
||||
.write(instant);
|
||||
// #app_path::#instants
|
||||
// .get_unchecked_mut(usize::from(index))
|
||||
// .as_mut_ptr()
|
||||
// .write(instant);
|
||||
|
||||
let nr = rtic::export::NotReady {
|
||||
instant,
|
||||
index,
|
||||
task: #app_path::#t::#name,
|
||||
};
|
||||
// let nr = rtic::export::NotReady {
|
||||
// instant,
|
||||
// index,
|
||||
// task: #app_path::#t::#name,
|
||||
// };
|
||||
|
||||
rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr));
|
||||
// rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr));
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(input)
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
// Ok(())
|
||||
// } else {
|
||||
// Err(input)
|
||||
// }
|
||||
// }
|
||||
// }));
|
||||
// }
|
||||
}
|
||||
|
||||
if !items.is_empty() {
|
||||
|
|
|
@ -74,24 +74,25 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
);));
|
||||
}
|
||||
|
||||
// Initialize the SysTick if there exist a TimerQueue
|
||||
if extra.monotonic.is_some() {
|
||||
let priority = analysis.channels.keys().max().unwrap();
|
||||
// TODO: Update for noew monotonic
|
||||
// // Initialize the SysTick if there exist a TimerQueue
|
||||
// if extra.monotonic.is_some() {
|
||||
// let priority = analysis.channels.keys().max().unwrap();
|
||||
|
||||
// Compile time assert that this priority is supported by the device
|
||||
stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
||||
// // Compile time assert that this priority is supported by the device
|
||||
// stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
||||
|
||||
stmts.push(quote!(core.SCB.set_priority(
|
||||
rtic::export::SystemHandler::SysTick,
|
||||
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||
);));
|
||||
// stmts.push(quote!(core.SCB.set_priority(
|
||||
// rtic::export::SystemHandler::SysTick,
|
||||
// rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||
// );));
|
||||
|
||||
stmts.push(quote!(
|
||||
core.SYST.set_clock_source(rtic::export::SystClkSource::Core);
|
||||
core.SYST.enable_counter();
|
||||
core.DCB.enable_trace();
|
||||
));
|
||||
}
|
||||
// stmts.push(quote!(
|
||||
// core.SYST.set_clock_source(rtic::export::SystClkSource::Core);
|
||||
// core.SYST.enable_counter();
|
||||
// core.DCB.enable_trace();
|
||||
// ));
|
||||
// }
|
||||
|
||||
// If there's no user `#[idle]` then optimize returning from interrupt handlers
|
||||
if app.idles.is_empty() {
|
||||
|
|
|
@ -57,18 +57,19 @@ pub fn codegen(
|
|||
.map(|_| quote!(core::mem::MaybeUninit::uninit()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(m) = &extra.monotonic {
|
||||
let instants = util::instants_ident(name);
|
||||
// TODO: Update for new monotonic
|
||||
// if let Some(m) = &extra.monotonic {
|
||||
// let instants = util::instants_ident(name);
|
||||
|
||||
let uninit = mk_uninit();
|
||||
mod_app.push(quote!(
|
||||
#uninit
|
||||
/// Buffer that holds the instants associated to the inputs of a task
|
||||
static mut #instants:
|
||||
[core::mem::MaybeUninit<<#m as rtic::Monotonic>::Instant>; #cap_lit] =
|
||||
[#(#elems,)*];
|
||||
));
|
||||
}
|
||||
// let uninit = mk_uninit();
|
||||
// mod_app.push(quote!(
|
||||
// #uninit
|
||||
// /// Buffer that holds the instants associated to the inputs of a task
|
||||
// static mut #instants:
|
||||
// [core::mem::MaybeUninit<<#m as rtic::Monotonic>::Instant>; #cap_lit] =
|
||||
// [#(#elems,)*];
|
||||
// ));
|
||||
// }
|
||||
|
||||
let uninit = mk_uninit();
|
||||
let inputs_ident = util::inputs_ident(name);
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{analyze::Analysis, check::Extra, codegen::util};
|
|||
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
|
||||
let mut items = vec![];
|
||||
|
||||
if let Some(m) = &extra.monotonic {
|
||||
if !app.monotonics.is_empty() {
|
||||
let t = util::schedule_t_ident();
|
||||
|
||||
// Enumeration of `schedule`-able tasks
|
||||
|
@ -36,12 +36,17 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let tq = util::tq_ident();
|
||||
for (_, monotonic) in &app.monotonics {
|
||||
let monotonic_name = monotonic.ident.to_string();
|
||||
let tq = util::tq_ident(&monotonic_name);
|
||||
let t = util::schedule_t_ident();
|
||||
let m = &monotonic.ident;
|
||||
|
||||
// Static variable and resource proxy
|
||||
// Static variables and resource proxy
|
||||
{
|
||||
let doc = "Timer queue".to_string();
|
||||
let doc = &format!("Timer queue for {}", monotonic_name);
|
||||
let cap = app
|
||||
.software_tasks
|
||||
.iter()
|
||||
|
@ -71,6 +76,8 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
let rq = util::rq_ident(priority);
|
||||
let rqt = util::spawn_t_ident(priority);
|
||||
let enum_ = util::interrupt_ident();
|
||||
|
||||
// The interrupt that runs the task dispatcher
|
||||
let interrupt = &analysis.interrupts.get(&priority).expect("RTIC-ICE: interrupt not found").0;
|
||||
|
||||
let pend = {
|
||||
|
@ -90,10 +97,10 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let sys_tick = util::suffixed("SysTick");
|
||||
let bound_interrupt = &monotonic.args.binds;
|
||||
items.push(quote!(
|
||||
#[no_mangle]
|
||||
unsafe fn #sys_tick() {
|
||||
unsafe fn #bound_interrupt() {
|
||||
use rtic::Mutex as _;
|
||||
|
||||
while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue())
|
||||
|
@ -106,5 +113,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
items
|
||||
}
|
||||
|
|
|
@ -247,8 +247,6 @@ pub fn suffixed(name: &str) -> Ident {
|
|||
}
|
||||
|
||||
/// Generates an identifier for a timer queue
|
||||
///
|
||||
/// At most there is one timer queue
|
||||
pub fn tq_ident() -> Ident {
|
||||
Ident::new(&"TQ".to_string(), Span::call_site())
|
||||
pub fn tq_ident(name: &str) -> Ident {
|
||||
Ident::new(&format!("TQ_{}", name), Span::call_site())
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use core::{
|
|||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
//pub use crate::tq::{NotReady, TimerQueue};
|
||||
// pub use crate::tq::{NotReady, TimerQueue};
|
||||
pub use bare_metal::CriticalSection;
|
||||
#[cfg(armv7m)]
|
||||
pub use cortex_m::register::basepri;
|
||||
|
|
Loading…
Reference in a new issue