mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
Flattened the _ out of it
This commit is contained in:
parent
aad8f81991
commit
b4509bdbfe
11 changed files with 146 additions and 147 deletions
|
@ -7,15 +7,11 @@
|
|||
|
||||
use panic_semihosting as _;
|
||||
|
||||
pub struct SomeStruct;
|
||||
|
||||
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||
mod app {
|
||||
use dwt_systick_monotonic::DwtSystick;
|
||||
use rtic::time::duration::Seconds;
|
||||
|
||||
use super::SomeStruct;
|
||||
|
||||
#[monotonic(binds = SysTick, default = true)]
|
||||
type MyMono = DwtSystick<8_000_000>; // 8 MHz
|
||||
|
||||
|
|
|
@ -22,4 +22,5 @@ proc-macro2 = "1"
|
|||
proc-macro-error = "1"
|
||||
quote = "1"
|
||||
syn = "1"
|
||||
rtic-syntax = "0.5.0-alpha.2"
|
||||
# rtic-syntax = "0.5.0-alpha.2"
|
||||
rtic-syntax = { path = "../../rtic-syntax" }
|
||||
|
|
|
@ -97,8 +97,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|||
let user_code = &app.user_code;
|
||||
let name = &app.name;
|
||||
let device = &extra.device;
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
|
||||
let monotonic_parts: Vec<_> = app
|
||||
.monotonics
|
||||
|
@ -106,7 +104,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|||
.map(|(_, monotonic)| {
|
||||
let name = &monotonic.ident;
|
||||
let name_str = &name.to_string();
|
||||
let ty = &monotonic.ty;
|
||||
let ident = util::monotonic_ident(&name_str);
|
||||
let ident = util::mark_internal_ident(&ident);
|
||||
let panic_str = &format!(
|
||||
|
@ -117,7 +114,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|||
"This module holds the static implementation for `{}::now()`",
|
||||
name_str
|
||||
);
|
||||
let user_imports = &app.user_imports;
|
||||
|
||||
let default_monotonic = if monotonic.args.default {
|
||||
quote!(pub use #name::now;)
|
||||
|
@ -131,17 +127,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|||
#[doc = #doc]
|
||||
#[allow(non_snake_case)]
|
||||
pub mod #name {
|
||||
#(
|
||||
#[allow(unused_imports)]
|
||||
#user_imports
|
||||
)*
|
||||
|
||||
/// Read the current time from this monotonic
|
||||
pub fn now() -> rtic::time::Instant<#ty> {
|
||||
pub fn now() -> rtic::time::Instant<super::super::#name> {
|
||||
rtic::export::interrupt::free(|_| {
|
||||
use rtic::Monotonic as _;
|
||||
use rtic::time::Clock as _;
|
||||
if let Some(m) = unsafe{ #app_path::#ident.get_mut_unchecked() } {
|
||||
if let Some(m) = unsafe{ super::super::#ident.get_mut_unchecked() } {
|
||||
if let Ok(v) = m.try_now() {
|
||||
v
|
||||
} else {
|
||||
|
@ -163,11 +155,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|||
|
||||
/// Holds static methods for each monotonic.
|
||||
pub mod monotonics {
|
||||
#(
|
||||
#[allow(unused_imports)]
|
||||
#user_imports
|
||||
)*
|
||||
|
||||
#(#monotonic_parts)*
|
||||
}
|
||||
)
|
||||
|
|
|
@ -82,8 +82,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
quote!(#name::Locals::new(),)
|
||||
};
|
||||
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
quote!(
|
||||
#(#cfgs)*
|
||||
#t::#name => {
|
||||
|
@ -95,7 +93,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
.read();
|
||||
#fq.get_mut_unchecked().split().0.enqueue_unchecked(index);
|
||||
let priority = &rtic::export::Priority::new(PRIORITY);
|
||||
#app_path::#name(
|
||||
#name(
|
||||
#locals_new
|
||||
#name::Context::new(priority)
|
||||
#(,#pats)*
|
||||
|
|
|
@ -40,8 +40,6 @@ pub fn codegen(
|
|||
let cfgs = &task.cfgs;
|
||||
let attrs = &task.attrs;
|
||||
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
mod_app.push(quote!(
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
|
@ -51,7 +49,7 @@ pub fn codegen(
|
|||
const PRIORITY: u8 = #priority;
|
||||
|
||||
rtic::export::run(PRIORITY, || {
|
||||
#app_path::#name(
|
||||
#name(
|
||||
#locals_new
|
||||
#name::Context::new(&rtic::export::Priority::new(PRIORITY))
|
||||
)
|
||||
|
|
|
@ -74,10 +74,8 @@ pub fn codegen(
|
|||
}
|
||||
));
|
||||
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
let locals_new = locals_new.iter();
|
||||
let call_idle = quote!(#app_path::#name(
|
||||
let call_idle = quote!(#name(
|
||||
#(#locals_new,)*
|
||||
#name::Context::new(&rtic::export::Priority::new(0))
|
||||
));
|
||||
|
|
|
@ -65,11 +65,9 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
|
|||
mod_app = Some(constructor);
|
||||
}
|
||||
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
let locals_new = locals_new.iter();
|
||||
let call_init = Some(
|
||||
quote!(let (late, mut monotonics) = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));),
|
||||
quote!(let (late, mut monotonics) = #name(#(#locals_new,)* #name::Context::new(core.into()));),
|
||||
);
|
||||
|
||||
root_init.push(module::codegen(
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::{analyze::Analysis, check::Extra, codegen::util};
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use rtic_syntax::{ast::App, Context};
|
||||
|
||||
use crate::{analyze::Analysis, check::Extra, codegen::util};
|
||||
|
||||
pub fn codegen(
|
||||
ctxt: Context,
|
||||
resources_tick: bool,
|
||||
|
@ -12,48 +11,13 @@ pub fn codegen(
|
|||
extra: &Extra,
|
||||
) -> TokenStream2 {
|
||||
let mut items = vec![];
|
||||
let mut module_items = vec![];
|
||||
let mut fields = vec![];
|
||||
let mut values = vec![];
|
||||
// Used to copy task cfgs to the whole module
|
||||
let mut task_cfgs = vec![];
|
||||
|
||||
let name = ctxt.ident(app);
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
|
||||
let all_task_imports: 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!()
|
||||
}
|
||||
}))
|
||||
.chain(app.user_types.iter().map(|ty| {
|
||||
let t = &ty.ident;
|
||||
quote! {
|
||||
#[allow(unused_imports)]
|
||||
use super::#t;
|
||||
}
|
||||
}))
|
||||
.collect();
|
||||
|
||||
let mut lt = None;
|
||||
match ctxt {
|
||||
|
@ -94,7 +58,7 @@ pub fn codegen(
|
|||
|
||||
if ctxt.has_locals(app) {
|
||||
let ident = util::locals_ident(ctxt, app);
|
||||
items.push(quote!(
|
||||
module_items.push(quote!(
|
||||
#[doc(inline)]
|
||||
pub use super::#ident as Locals;
|
||||
));
|
||||
|
@ -110,14 +74,14 @@ pub fn codegen(
|
|||
None
|
||||
};
|
||||
|
||||
items.push(quote!(
|
||||
module_items.push(quote!(
|
||||
#[doc(inline)]
|
||||
pub use super::#ident as Resources;
|
||||
));
|
||||
|
||||
fields.push(quote!(
|
||||
/// Resources this task has access to
|
||||
pub resources: Resources<#lt>
|
||||
pub resources: #name::Resources<#lt>
|
||||
));
|
||||
|
||||
let priority = if ctxt.is_init() {
|
||||
|
@ -125,7 +89,7 @@ pub fn codegen(
|
|||
} else {
|
||||
Some(quote!(priority))
|
||||
};
|
||||
values.push(quote!(resources: Resources::new(#priority)));
|
||||
values.push(quote!(resources: #name::Resources::new(#priority)));
|
||||
}
|
||||
|
||||
if let Context::Init = ctxt {
|
||||
|
@ -145,13 +109,17 @@ pub fn codegen(
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let internal_late_ident = util::mark_internal_name("LateResources");
|
||||
items.push(quote!(
|
||||
/// Resources initialized at runtime
|
||||
#[allow(non_snake_case)]
|
||||
pub struct LateResources {
|
||||
pub struct #internal_late_ident {
|
||||
#(#late_fields),*
|
||||
}
|
||||
));
|
||||
module_items.push(quote!(
|
||||
pub use super::#internal_late_ident as LateResources;
|
||||
));
|
||||
|
||||
let monotonic_types: Vec<_> = app
|
||||
.monotonics
|
||||
|
@ -162,13 +130,19 @@ pub fn codegen(
|
|||
})
|
||||
.collect();
|
||||
|
||||
let internal_monotonics_ident = util::mark_internal_name("Monotonics");
|
||||
|
||||
items.push(quote!(
|
||||
/// Monotonics used by the system
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Monotonics(
|
||||
pub struct #internal_monotonics_ident(
|
||||
#(pub #monotonic_types),*
|
||||
);
|
||||
));
|
||||
|
||||
module_items.push(quote!(
|
||||
pub use super::#internal_monotonics_ident as Monotonics;
|
||||
));
|
||||
}
|
||||
|
||||
let doc = match ctxt {
|
||||
|
@ -178,6 +152,19 @@ pub fn codegen(
|
|||
Context::SoftwareTask(_) => "Software task",
|
||||
};
|
||||
|
||||
let v = Vec::new();
|
||||
let cfgs = match ctxt {
|
||||
Context::HardwareTask(t) => {
|
||||
&app.hardware_tasks[t].cfgs
|
||||
// ...
|
||||
},
|
||||
Context::SoftwareTask(t) => {
|
||||
&app.software_tasks[t].cfgs
|
||||
// ...
|
||||
},
|
||||
_ => &v,
|
||||
};
|
||||
|
||||
let core = if ctxt.is_init() {
|
||||
Some(quote!(core: rtic::export::Peripherals,))
|
||||
} else {
|
||||
|
@ -190,22 +177,31 @@ pub fn codegen(
|
|||
Some(quote!(priority: &#lt rtic::export::Priority))
|
||||
};
|
||||
|
||||
let internal_context_name = util::internal_task_ident(name, "Context");
|
||||
|
||||
items.push(quote!(
|
||||
#(#cfgs)*
|
||||
/// Execution context
|
||||
pub struct Context<#lt> {
|
||||
pub struct #internal_context_name<#lt> {
|
||||
#(#fields,)*
|
||||
}
|
||||
|
||||
impl<#lt> Context<#lt> {
|
||||
#(#cfgs)*
|
||||
impl<#lt> #internal_context_name<#lt> {
|
||||
#[inline(always)]
|
||||
pub unsafe fn new(#core #priority) -> Self {
|
||||
Context {
|
||||
#internal_context_name {
|
||||
#(#values,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
module_items.push(quote!(
|
||||
#(#cfgs)*
|
||||
pub use super::#internal_context_name as Context;
|
||||
));
|
||||
|
||||
// not sure if this is the right way, maybe its backwards,
|
||||
// that spawn_module should put in in root
|
||||
|
||||
|
@ -234,26 +230,26 @@ pub fn codegen(
|
|||
.expect("RTIC-ICE: interrupt identifer not found")
|
||||
.0;
|
||||
|
||||
let internal_spawn_ident = util::internal_task_ident(name, "spawn");
|
||||
|
||||
// Spawn caller
|
||||
items.push(quote!(
|
||||
|
||||
#(#all_task_imports)*
|
||||
|
||||
#(#cfgs)*
|
||||
/// Spawns the task directly
|
||||
pub fn spawn(#(#args,)*) -> Result<(), #ty> {
|
||||
pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
|
||||
let input = #tupled;
|
||||
|
||||
unsafe {
|
||||
if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.get_mut_unchecked().dequeue()) {
|
||||
#app_path::#inputs
|
||||
if let Some(index) = rtic::export::interrupt::free(|_| #fq.get_mut_unchecked().dequeue()) {
|
||||
#inputs
|
||||
.get_mut_unchecked()
|
||||
.get_unchecked_mut(usize::from(index))
|
||||
.as_mut_ptr()
|
||||
.write(input);
|
||||
|
||||
rtic::export::interrupt::free(|_| {
|
||||
#app_path::#rq.get_mut_unchecked().enqueue_unchecked((#app_path::#t::#name, index));
|
||||
#rq.get_mut_unchecked().enqueue_unchecked((#t::#name, index));
|
||||
});
|
||||
|
||||
rtic::pend(#device::#enum_::#interrupt);
|
||||
|
@ -266,6 +262,11 @@ pub fn codegen(
|
|||
|
||||
}));
|
||||
|
||||
module_items.push(quote!(
|
||||
#(#cfgs)*
|
||||
pub use super::#internal_spawn_ident as spawn;
|
||||
));
|
||||
|
||||
// Schedule caller
|
||||
for (_, monotonic) in &app.monotonics {
|
||||
let instants = util::monotonic_instants_ident(name, &monotonic.ident);
|
||||
|
@ -282,12 +283,6 @@ pub fn codegen(
|
|||
let m_isr = &monotonic.args.binds;
|
||||
let enum_ = util::interrupt_ident();
|
||||
|
||||
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" {
|
||||
(
|
||||
quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(())
|
||||
|
@ -297,49 +292,56 @@ pub fn codegen(
|
|||
} else {
|
||||
let rt_err = util::rt_err_ident();
|
||||
(
|
||||
quote!(rtic::export::NVIC::unmask(#app_path::#rt_err::#enum_::#m_isr)),
|
||||
quote!(rtic::pend(#app_path::#rt_err::#enum_::#m_isr)),
|
||||
quote!(rtic::export::NVIC::unmask(#rt_err::#enum_::#m_isr)),
|
||||
quote!(rtic::pend(#rt_err::#enum_::#m_isr)),
|
||||
)
|
||||
};
|
||||
|
||||
let user_imports = &app.user_imports;
|
||||
let tq_marker = util::mark_internal_ident(&util::timer_queue_marker_ident());
|
||||
|
||||
// For future use
|
||||
// let doc = format!(" RTIC internal: {}:{}", file!(), line!());
|
||||
// items.push(quote!(#[doc = #doc]));
|
||||
let internal_spawn_handle_ident =
|
||||
util::internal_monotonics_ident(name, m, "SpawnHandle");
|
||||
let internal_spawn_at_ident = util::internal_monotonics_ident(name, m, "spawn_at");
|
||||
let internal_spawn_after_ident =
|
||||
util::internal_monotonics_ident(name, m, "spawn_after");
|
||||
|
||||
if monotonic.args.default {
|
||||
module_items.push(quote!(
|
||||
pub use #m::spawn_after;
|
||||
pub use #m::spawn_at;
|
||||
pub use #m::SpawnHandle;
|
||||
));
|
||||
}
|
||||
module_items.push(quote!(
|
||||
pub mod #m {
|
||||
pub use super::super::#internal_spawn_after_ident as spawn_after;
|
||||
pub use super::super::#internal_spawn_at_ident as spawn_at;
|
||||
pub use super::super::#internal_spawn_handle_ident as SpawnHandle;
|
||||
}
|
||||
));
|
||||
|
||||
items.push(quote!(
|
||||
/// Holds methods related to this monotonic
|
||||
pub mod #m {
|
||||
use super::*;
|
||||
#[allow(unused_imports)]
|
||||
use #app_path::#tq_marker;
|
||||
#[allow(unused_imports)]
|
||||
use #app_path::#t;
|
||||
#(
|
||||
#[allow(unused_imports)]
|
||||
#user_imports
|
||||
)*
|
||||
|
||||
pub struct SpawnHandle {
|
||||
pub struct #internal_spawn_handle_ident {
|
||||
#[doc(hidden)]
|
||||
marker: u32,
|
||||
}
|
||||
|
||||
impl SpawnHandle {
|
||||
impl #internal_spawn_handle_ident {
|
||||
pub fn cancel(self) -> Result<#ty, ()> {
|
||||
rtic::export::interrupt::free(|_| unsafe {
|
||||
let tq = &mut *#app_path::#tq.get_mut_unchecked().as_mut_ptr();
|
||||
let tq = &mut *#tq.get_mut_unchecked().as_mut_ptr();
|
||||
if let Some((_task, index)) = tq.cancel_marker(self.marker) {
|
||||
// Get the message
|
||||
let msg = #app_path::#inputs
|
||||
let msg = #inputs
|
||||
.get_unchecked()
|
||||
.get_unchecked(usize::from(index))
|
||||
.as_ptr()
|
||||
.read();
|
||||
// Return the index to the free queue
|
||||
#app_path::#fq.get_mut_unchecked().split().0.enqueue_unchecked(index);
|
||||
#fq.get_mut_unchecked().split().0.enqueue_unchecked(index);
|
||||
|
||||
Ok(msg)
|
||||
} else {
|
||||
|
@ -351,20 +353,20 @@ pub fn codegen(
|
|||
#[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>,
|
||||
D::T: Into<<#mono_type as rtic::time::Clock>::T>,
|
||||
{
|
||||
self.reschedule_at(#app_path::monotonics::#m::now() + duration)
|
||||
self.reschedule_at(monotonics::#m::now() + duration)
|
||||
}
|
||||
|
||||
pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result<Self, ()>
|
||||
pub fn reschedule_at(self, instant: rtic::time::Instant<#mono_type>) -> Result<Self, ()>
|
||||
{
|
||||
rtic::export::interrupt::free(|_| unsafe {
|
||||
let marker = *#tq_marker.get_mut_unchecked();
|
||||
*#tq_marker.get_mut_unchecked() = #tq_marker.get_mut_unchecked().wrapping_add(1);
|
||||
|
||||
let tq = &mut *#app_path::#tq.get_mut_unchecked().as_mut_ptr();
|
||||
let tq = &mut *#tq.get_mut_unchecked().as_mut_ptr();
|
||||
|
||||
tq.update_marker(self.marker, marker, instant, || #pend).map(|_| SpawnHandle { marker })
|
||||
tq.update_marker(self.marker, marker, instant, || #pend).map(|_| #name::#m::SpawnHandle { marker })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -374,39 +376,39 @@ pub fn codegen(
|
|||
///
|
||||
/// This will use the time `Instant::new(0)` as baseline if called in `#[init]`,
|
||||
/// so if you use a non-resetable timer use `spawn_at` when in `#[init]`
|
||||
pub fn spawn_after<D>(
|
||||
pub fn #internal_spawn_after_ident<D>(
|
||||
duration: D
|
||||
#(,#args)*
|
||||
) -> Result<SpawnHandle, #ty>
|
||||
) -> Result<#name::#m::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>,
|
||||
D::T: Into<<#mono_type as rtic::time::Clock>::T>,
|
||||
{
|
||||
|
||||
let instant = if rtic::export::interrupt::free(|_| unsafe { #app_path::#m_ident.get_mut_unchecked().is_none() }) {
|
||||
let instant = if rtic::export::interrupt::free(|_| unsafe { #m_ident.get_mut_unchecked().is_none() }) {
|
||||
rtic::time::Instant::new(0)
|
||||
} else {
|
||||
#app_path::monotonics::#m::now()
|
||||
monotonics::#m::now()
|
||||
};
|
||||
|
||||
spawn_at(instant + duration #(,#untupled)*)
|
||||
#internal_spawn_at_ident(instant + duration #(,#untupled)*)
|
||||
}
|
||||
|
||||
#(#cfgs)*
|
||||
/// Spawns the task at a fixed time instant
|
||||
pub fn spawn_at(
|
||||
instant: rtic::time::Instant<#app_path::#mono_type>
|
||||
pub fn #internal_spawn_at_ident(
|
||||
instant: rtic::time::Instant<#mono_type>
|
||||
#(,#args)*
|
||||
) -> Result<SpawnHandle, #ty> {
|
||||
) -> Result<#name::#m::SpawnHandle, #ty> {
|
||||
unsafe {
|
||||
let input = #tupled;
|
||||
if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.get_mut_unchecked().dequeue()) {
|
||||
#app_path::#inputs
|
||||
if let Some(index) = rtic::export::interrupt::free(|_| #fq.get_mut_unchecked().dequeue()) {
|
||||
#inputs
|
||||
.get_mut_unchecked()
|
||||
.get_unchecked_mut(usize::from(index))
|
||||
.as_mut_ptr()
|
||||
.write(input);
|
||||
|
||||
#app_path::#instants
|
||||
#instants
|
||||
.get_mut_unchecked()
|
||||
.get_unchecked_mut(usize::from(index))
|
||||
.as_mut_ptr()
|
||||
|
@ -417,44 +419,40 @@ pub fn codegen(
|
|||
let nr = rtic::export::NotReady {
|
||||
instant,
|
||||
index,
|
||||
task: #app_path::#t::#name,
|
||||
task: #t::#name,
|
||||
marker,
|
||||
};
|
||||
|
||||
*#tq_marker.get_mut_unchecked() = #tq_marker.get_mut_unchecked().wrapping_add(1);
|
||||
|
||||
let tq = &mut *#app_path::#tq.get_mut_unchecked().as_mut_ptr();
|
||||
let tq = &mut *#tq.get_mut_unchecked().as_mut_ptr();
|
||||
|
||||
tq.enqueue_unchecked(
|
||||
nr,
|
||||
|| #enable_interrupt,
|
||||
|| #pend,
|
||||
#app_path::#m_ident.get_mut_unchecked().as_mut());
|
||||
#m_ident.get_mut_unchecked().as_mut());
|
||||
|
||||
Ok(SpawnHandle { marker })
|
||||
Ok(#name::#m::SpawnHandle { marker })
|
||||
})
|
||||
} else {
|
||||
Err(input)
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if !items.is_empty() {
|
||||
let user_imports = &app.user_imports;
|
||||
|
||||
quote!(
|
||||
#(#items)*
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#(#task_cfgs)*
|
||||
#[doc = #doc]
|
||||
pub mod #name {
|
||||
#(
|
||||
#[allow(unused_imports)]
|
||||
#user_imports
|
||||
)*
|
||||
#(#items)*
|
||||
#(#module_items)*
|
||||
}
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -93,8 +93,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
// Compile time assert that this priority is supported by the device
|
||||
stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
||||
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
let mono_type = &monotonic.ty;
|
||||
|
||||
if &*binds.to_string() == "SysTick" {
|
||||
|
@ -121,7 +119,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
|
||||
// Always enable monotonic interrupts if they should never be off
|
||||
if !<#mono_type as rtic::Monotonic>::DISABLE_INTERRUPT_ON_EMPTY_QUEUE {
|
||||
rtic::export::NVIC::unmask(#app_path::#rt_err::#interrupt::#binds);
|
||||
rtic::export::NVIC::unmask(#rt_err::#interrupt::#binds);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
|
|
@ -57,8 +57,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
let mono_type = &monotonic.ty;
|
||||
let m_ident = util::monotonic_ident(&monotonic_name);
|
||||
let m_ident = util::mark_internal_ident(&m_ident);
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
|
||||
// Static variables and resource proxy
|
||||
{
|
||||
|
@ -139,7 +137,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
#[allow(non_snake_case)]
|
||||
unsafe fn #bound_interrupt() {
|
||||
while let Some((task, index)) = rtic::export::interrupt::free(|_|
|
||||
if let Some(mono) = #app_path::#m_ident.get_mut_unchecked().as_mut() {
|
||||
if let Some(mono) = #m_ident.get_mut_unchecked().as_mut() {
|
||||
(&mut *#tq.get_mut_unchecked().as_mut_ptr()).dequeue(|| #disable_isr, mono)
|
||||
} else {
|
||||
// We can only use the timer queue if `init` has returned, and it
|
||||
|
@ -152,7 +150,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
}
|
||||
}
|
||||
|
||||
rtic::export::interrupt::free(|_| if let Some(mono) = #app_path::#m_ident.get_mut_unchecked().as_mut() {
|
||||
rtic::export::interrupt::free(|_| if let Some(mono) = #m_ident.get_mut_unchecked().as_mut() {
|
||||
mono.on_interrupt();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -111,6 +111,27 @@ pub fn is_exception(name: &Ident) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
/// Generate an internal identifier for monotonics
|
||||
pub fn internal_monotonics_ident(task: &Ident, monotonic: &Ident, ident_name: &str) -> Ident {
|
||||
Ident::new(
|
||||
&format!(
|
||||
"__rtic_internal_{}_{}_{}",
|
||||
task.to_string(),
|
||||
monotonic.to_string(),
|
||||
ident_name,
|
||||
),
|
||||
Span::call_site(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate an internal identifier for tasks
|
||||
pub fn internal_task_ident(task: &Ident, ident_name: &str) -> Ident {
|
||||
Ident::new(
|
||||
&format!("__rtic_internal_{}_{}", task.to_string(), ident_name,),
|
||||
Span::call_site(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Mark an ident as internal
|
||||
pub fn mark_internal_ident(ident: &Ident) -> Ident {
|
||||
Ident::new(
|
||||
|
@ -119,6 +140,14 @@ pub fn mark_internal_ident(ident: &Ident) -> Ident {
|
|||
)
|
||||
}
|
||||
|
||||
/// Mark an ident as internal
|
||||
pub fn mark_internal_name(name: &str) -> Ident {
|
||||
Ident::new(
|
||||
&format!("__rtic_internal_{}", name),
|
||||
Span::call_site(),
|
||||
)
|
||||
}
|
||||
|
||||
fn link_section_index() -> usize {
|
||||
static INDEX: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue