mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-23 20:22:51 +01:00
More work
This commit is contained in:
parent
b23bb1192c
commit
97a48983d2
10 changed files with 155 additions and 176 deletions
|
@ -9,10 +9,10 @@ use rtic::app;
|
||||||
#[app(device = lm3s6965, dispatchers = [UART])]
|
#[app(device = lm3s6965, dispatchers = [UART])]
|
||||||
mod app {
|
mod app {
|
||||||
#[monotonic(binds = SomeISR1)]
|
#[monotonic(binds = SomeISR1)]
|
||||||
type Mono1 = hal::Mono1;
|
type MyMono1 = hal::Mono1;
|
||||||
|
|
||||||
#[monotonic(binds = SomeISR2)]
|
#[monotonic(binds = SomeISR2, default = true)]
|
||||||
type Mono2 = hal::Mono2;
|
type MyMono2 = hal::Mono2;
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) {
|
fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) {
|
||||||
|
|
|
@ -27,13 +27,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
||||||
let mut user = vec![];
|
let mut user = vec![];
|
||||||
|
|
||||||
// Generate the `main` function
|
// Generate the `main` function
|
||||||
let assertion_stmts = assertions::codegen(analysis);
|
let assertion_stmts = assertions::codegen(app, analysis);
|
||||||
|
|
||||||
let pre_init_stmts = pre_init::codegen(&app, analysis, extra);
|
let pre_init_stmts = pre_init::codegen(app, analysis, extra);
|
||||||
|
|
||||||
let (mod_app_init, root_init, user_init, call_init) = init::codegen(app, analysis, extra);
|
let (mod_app_init, root_init, user_init, call_init) = init::codegen(app, analysis, extra);
|
||||||
|
|
||||||
let post_init_stmts = post_init::codegen(&app, analysis);
|
let post_init_stmts = post_init::codegen(app, analysis);
|
||||||
|
|
||||||
let (mod_app_idle, root_idle, user_idle, call_idle) = idle::codegen(app, analysis, extra);
|
let (mod_app_idle, root_idle, user_idle, call_idle) = idle::codegen(app, analysis, extra);
|
||||||
|
|
||||||
|
@ -104,12 +104,20 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let monotonic_imports: Vec<_> = app.monotonics.iter().map(|(_, monotonic)| {
|
||||||
|
let name = &monotonic.ident;
|
||||||
|
let ty = &monotonic.ty;
|
||||||
|
quote!(pub type #name = #ty;)
|
||||||
|
}).collect();
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
/// Implementation details
|
/// Implementation details
|
||||||
pub mod #name {
|
pub mod #name {
|
||||||
/// Always include the device crate which contains the vector table
|
/// Always include the device crate which contains the vector table
|
||||||
use #device as you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml;
|
use #device as you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml;
|
||||||
|
|
||||||
|
#(#monotonic_imports)*
|
||||||
|
|
||||||
#(#user_imports)*
|
#(#user_imports)*
|
||||||
|
|
||||||
/// User code from within the module
|
/// User code from within the module
|
||||||
|
|
|
@ -2,9 +2,10 @@ use proc_macro2::TokenStream as TokenStream2;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
use crate::analyze::Analysis;
|
use crate::analyze::Analysis;
|
||||||
|
use rtic_syntax::ast::App;
|
||||||
|
|
||||||
/// Generates compile-time assertions that check that types implement the `Send` / `Sync` traits
|
/// Generates compile-time assertions that check that types implement the `Send` / `Sync` traits
|
||||||
pub fn codegen(analysis: &Analysis) -> Vec<TokenStream2> {
|
pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
|
||||||
let mut stmts = vec![];
|
let mut stmts = vec![];
|
||||||
|
|
||||||
for ty in &analysis.send_types {
|
for ty in &analysis.send_types {
|
||||||
|
@ -15,5 +16,10 @@ pub fn codegen(analysis: &Analysis) -> Vec<TokenStream2> {
|
||||||
stmts.push(quote!(rtic::export::assert_sync::<#ty>();));
|
stmts.push(quote!(rtic::export::assert_sync::<#ty>();));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (_, monotonic) in &app.monotonics {
|
||||||
|
let ty = &monotonic.ty;
|
||||||
|
stmts.push(quote!(rtic::export::assert_monotonic::<#ty>();));
|
||||||
|
}
|
||||||
|
|
||||||
stmts
|
stmts
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rtic_syntax::ast::App;
|
||||||
use crate::{analyze::Analysis, check::Extra, codegen::util};
|
use crate::{analyze::Analysis, check::Extra, codegen::util};
|
||||||
|
|
||||||
/// Generates task dispatchers
|
/// Generates task dispatchers
|
||||||
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
|
pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStream2> {
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
|
|
||||||
let interrupts = &analysis.interrupts;
|
let interrupts = &analysis.interrupts;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rtic_syntax::{ast::App, Context};
|
||||||
use crate::{
|
use crate::{
|
||||||
analyze::Analysis,
|
analyze::Analysis,
|
||||||
check::Extra,
|
check::Extra,
|
||||||
codegen::{locals, module, resources_struct, util},
|
codegen::{locals, module, resources_struct},
|
||||||
};
|
};
|
||||||
|
|
||||||
type CodegenResult = (
|
type CodegenResult = (
|
||||||
|
@ -32,50 +32,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
|
||||||
|
|
||||||
let mut root_init = vec![];
|
let mut root_init = vec![];
|
||||||
|
|
||||||
let late_fields = analysis
|
|
||||||
.late_resources
|
|
||||||
.iter()
|
|
||||||
.flat_map(|resources| {
|
|
||||||
resources.iter().map(|name| {
|
|
||||||
let ty = &app.late_resources[name].ty;
|
|
||||||
let cfgs = &app.late_resources[name].cfgs;
|
|
||||||
|
|
||||||
quote!(
|
|
||||||
#(#cfgs)*
|
|
||||||
pub #name: #ty
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let late_resources = util::late_resources_ident(&name);
|
|
||||||
|
|
||||||
root_init.push(quote!(
|
|
||||||
/// Resources initialized at runtime
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub struct #late_resources {
|
|
||||||
#(#late_fields),*
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
let monotonic_types: Vec<_> = app
|
|
||||||
.monotonics
|
|
||||||
.iter()
|
|
||||||
.map(|(_, monotonic)| {
|
|
||||||
let mono = &monotonic.ty;
|
|
||||||
quote! {#mono}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let monotonics = util::monotonics_ident(&name);
|
|
||||||
|
|
||||||
root_init.push(quote!(
|
|
||||||
/// Monotonics used by the system
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub struct #monotonics(
|
|
||||||
#(#monotonic_types),*
|
|
||||||
);
|
|
||||||
));
|
|
||||||
|
|
||||||
let mut locals_pat = None;
|
let mut locals_pat = None;
|
||||||
let mut locals_new = None;
|
let mut locals_new = None;
|
||||||
if !init.locals.is_empty() {
|
if !init.locals.is_empty() {
|
||||||
|
@ -91,15 +47,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
|
||||||
let stmts = &init.stmts;
|
let stmts = &init.stmts;
|
||||||
let locals_pat = locals_pat.iter();
|
let locals_pat = locals_pat.iter();
|
||||||
|
|
||||||
let mut user_init_return = vec![quote! {#name::LateResources}];
|
let user_init_return = quote! {#name::LateResources, #name::Monotonics};
|
||||||
if !app.monotonics.is_empty() {
|
|
||||||
user_init_return.push(quote! {#name::Monotonics});
|
|
||||||
}
|
|
||||||
|
|
||||||
let user_init = Some(quote!(
|
let user_init = Some(quote!(
|
||||||
#(#attrs)*
|
#(#attrs)*
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn #name(#(#locals_pat,)* #context: #name::Context) -> (#(#user_init_return,)*) {
|
fn #name(#(#locals_pat,)* #context: #name::Context) -> (#user_init_return) {
|
||||||
#(#stmts)*
|
#(#stmts)*
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
|
@ -19,29 +19,13 @@ pub fn codegen(
|
||||||
|
|
||||||
let name = ctxt.ident(app);
|
let name = ctxt.ident(app);
|
||||||
|
|
||||||
let mut needs_instant = false;
|
|
||||||
let mut lt = None;
|
let mut lt = None;
|
||||||
match ctxt {
|
match ctxt {
|
||||||
Context::Init => {
|
Context::Init => {
|
||||||
// TODO: What fields are needed?
|
fields.push(quote!(
|
||||||
// if let Some(m) = &extra.monotonic {
|
/// Core (Cortex-M) peripherals
|
||||||
// fields.push(quote!(
|
pub core: rtic::export::Peripherals
|
||||||
// /// System start time = `Instant(0 /* cycles */)`
|
));
|
||||||
// pub start: <#m as rtic::Monotonic>::Instant
|
|
||||||
// ));
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
|
|
||||||
if extra.peripherals {
|
if extra.peripherals {
|
||||||
let device = &extra.device;
|
let device = &extra.device;
|
||||||
|
@ -68,31 +52,11 @@ pub fn codegen(
|
||||||
Context::Idle => {}
|
Context::Idle => {}
|
||||||
|
|
||||||
Context::HardwareTask(..) => {
|
Context::HardwareTask(..) => {
|
||||||
// TODO: What fields are needed for monotonic?
|
// None for now.
|
||||||
// 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));
|
|
||||||
|
|
||||||
// needs_instant = true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Context::SoftwareTask(..) => {
|
Context::SoftwareTask(..) => {
|
||||||
// TODO: What fields are needed for monotonic?
|
// None for now.
|
||||||
// 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));
|
|
||||||
|
|
||||||
// needs_instant = true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,18 +96,45 @@ pub fn codegen(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Context::Init = ctxt {
|
if let Context::Init = ctxt {
|
||||||
let init = &app.inits.first().unwrap();
|
let late_fields = analysis
|
||||||
let late_resources = util::late_resources_ident(&init.name);
|
.late_resources
|
||||||
let monotonics = util::monotonics_ident(&init.name);
|
.iter()
|
||||||
|
.flat_map(|resources| {
|
||||||
|
resources.iter().map(|name| {
|
||||||
|
let ty = &app.late_resources[name].ty;
|
||||||
|
let cfgs = &app.late_resources[name].cfgs;
|
||||||
|
|
||||||
|
quote!(
|
||||||
|
#(#cfgs)*
|
||||||
|
pub #name: #ty
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#[doc(inline)]
|
/// Resources initialized at runtime
|
||||||
pub use super::#late_resources as LateResources;
|
#[allow(non_snake_case)]
|
||||||
|
pub struct LateResources {
|
||||||
|
#(#late_fields),*
|
||||||
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let monotonic_types: Vec<_> = app
|
||||||
|
.monotonics
|
||||||
|
.iter()
|
||||||
|
.map(|(_, monotonic)| {
|
||||||
|
let mono = &monotonic.ident;
|
||||||
|
quote! {#mono}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#[doc(inline)]
|
/// Monotonics used by the system
|
||||||
pub use super::#monotonics as Monotonics;
|
#[allow(non_snake_case)]
|
||||||
|
pub struct Monotonics(
|
||||||
|
#(#monotonic_types),*
|
||||||
|
);
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,16 +157,6 @@ pub fn codegen(
|
||||||
Some(quote!(priority: &#lt rtic::export::Priority))
|
Some(quote!(priority: &#lt rtic::export::Priority))
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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
|
|
||||||
// };
|
|
||||||
let instant = quote!();
|
|
||||||
|
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
/// Execution context
|
/// Execution context
|
||||||
pub struct Context<#lt> {
|
pub struct Context<#lt> {
|
||||||
|
@ -184,7 +165,7 @@ pub fn codegen(
|
||||||
|
|
||||||
impl<#lt> Context<#lt> {
|
impl<#lt> Context<#lt> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn new(#core #priority #instant) -> Self {
|
pub unsafe fn new(#core #priority) -> Self {
|
||||||
Context {
|
Context {
|
||||||
#(#values,)*
|
#(#values,)*
|
||||||
}
|
}
|
||||||
|
@ -202,7 +183,7 @@ pub fn codegen(
|
||||||
let cfgs = &spawnee.cfgs;
|
let cfgs = &spawnee.cfgs;
|
||||||
// Store a copy of the task cfgs
|
// Store a copy of the task cfgs
|
||||||
task_cfgs = cfgs.clone();
|
task_cfgs = cfgs.clone();
|
||||||
let (args, tupled, _untupled, ty) = util::regroup_inputs(&spawnee.inputs);
|
let (args, tupled, untupled, ty) = util::regroup_inputs(&spawnee.inputs);
|
||||||
let args = &args;
|
let args = &args;
|
||||||
let tupled = &tupled;
|
let tupled = &tupled;
|
||||||
let fq = util::fq_ident(name);
|
let fq = util::fq_ident(name);
|
||||||
|
@ -251,51 +232,70 @@ pub fn codegen(
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// TODO: Needs updating for new monotonic.
|
// Schedule caller
|
||||||
// // Schedule caller
|
for (_, monotonic) in &app.monotonics {
|
||||||
// if let Some(m) = &extra.monotonic {
|
let instants = util::instants_ident(name);
|
||||||
// let instants = util::instants_ident(name);
|
|
||||||
|
|
||||||
// let tq = util::tq_ident();
|
let tq = util::tq_ident(&monotonic.ident.to_string());
|
||||||
// let t = util::schedule_t_ident();
|
let t = util::schedule_t_ident();
|
||||||
|
let m = &monotonic.ident;
|
||||||
|
|
||||||
// items.push(quote!(
|
if monotonic.args.default {
|
||||||
// #(#cfgs)*
|
items.push(quote!(pub use #m::spawn_after;));
|
||||||
// pub fn schedule(
|
items.push(quote!(pub use #m::spawn_at;));
|
||||||
// instant: <#m as rtic::Monotonic>::Instant
|
}
|
||||||
// #(,#args)*
|
|
||||||
// ) -> Result<(), #ty> {
|
|
||||||
// unsafe {
|
|
||||||
// use rtic::Mutex as _;
|
|
||||||
// use rtic::mutex_prelude::*;
|
|
||||||
|
|
||||||
// let input = #tupled;
|
items.push(quote!(
|
||||||
// if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
|
pub mod #m {
|
||||||
// #app_path::#inputs
|
#(#cfgs)*
|
||||||
// .get_unchecked_mut(usize::from(index))
|
pub fn spawn_after(
|
||||||
// .as_mut_ptr()
|
duration: rtic::Duration,
|
||||||
// .write(input);
|
#(,#args)*
|
||||||
|
) -> Result<(), #ty> {
|
||||||
|
let instant = <#app_path::#m as rtic::Monotonic>::now();
|
||||||
|
|
||||||
// #app_path::#instants
|
spawn_at(instant + duration, #(,#untupled)*)
|
||||||
// .get_unchecked_mut(usize::from(index))
|
}
|
||||||
// .as_mut_ptr()
|
|
||||||
// .write(instant);
|
|
||||||
|
|
||||||
// let nr = rtic::export::NotReady {
|
#(#cfgs)*
|
||||||
// instant,
|
pub fn spawn_at(
|
||||||
// index,
|
instant: Instant<#app_path::#m as rtic::Monotonic>
|
||||||
// task: #app_path::#t::#name,
|
#(,#args)*
|
||||||
// };
|
) -> Result<(), #ty> {
|
||||||
|
unsafe {
|
||||||
|
use rtic::Mutex as _;
|
||||||
|
use rtic::mutex_prelude::*;
|
||||||
|
|
||||||
// rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr));
|
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);
|
||||||
|
|
||||||
// Ok(())
|
#app_path::#instants
|
||||||
// } else {
|
.get_unchecked_mut(usize::from(index))
|
||||||
// Err(input)
|
.as_mut_ptr()
|
||||||
// }
|
.write(instant);
|
||||||
// }
|
|
||||||
// }));
|
let nr = rtic::export::NotReady {
|
||||||
// }
|
instant,
|
||||||
|
index,
|
||||||
|
task: #app_path::#t::#name,
|
||||||
|
};
|
||||||
|
|
||||||
|
rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr));
|
||||||
|
|
||||||
|
// TODO: After adding the scheduled task, check and setup the timer.
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !items.is_empty() {
|
if !items.is_empty() {
|
||||||
|
|
|
@ -74,25 +74,26 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
||||||
);));
|
);));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update for noew monotonic
|
// Initialize monotonic's interrupts
|
||||||
// // Initialize the SysTick if there exist a TimerQueue
|
for (priority, name) in app
|
||||||
// if extra.monotonic.is_some() {
|
.monotonics
|
||||||
// let priority = analysis.channels.keys().max().unwrap();
|
.iter()
|
||||||
|
.map(|(_, monotonic)| (&monotonic.args.priority, &monotonic.args.binds))
|
||||||
|
{
|
||||||
|
// 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
|
// NOTE this also checks that the interrupt exists in the `Interrupt` enumeration
|
||||||
// stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
let interrupt = util::interrupt_ident();
|
||||||
|
stmts.push(quote!(
|
||||||
|
core.NVIC.set_priority(
|
||||||
|
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#interrupt::#name,
|
||||||
|
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||||
|
);
|
||||||
|
));
|
||||||
|
|
||||||
// stmts.push(quote!(core.SCB.set_priority(
|
// NOTE we do not unmask the interrupt as this is part of the monotonic to keep track of
|
||||||
// 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();
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// If there's no user `#[idle]` then optimize returning from interrupt handlers
|
// If there's no user `#[idle]` then optimize returning from interrupt handlers
|
||||||
if app.idles.is_empty() {
|
if app.idles.is_empty() {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rtic_syntax::ast::App;
|
||||||
use crate::{analyze::Analysis, check::Extra, codegen::util};
|
use crate::{analyze::Analysis, check::Extra, codegen::util};
|
||||||
|
|
||||||
/// Generates timer queues and timer queue handlers
|
/// Generates timer queues and timer queue handlers
|
||||||
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
|
pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStream2> {
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
|
|
||||||
if !app.monotonics.is_empty() {
|
if !app.monotonics.is_empty() {
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub use cortex_m::{
|
||||||
use heapless::spsc::SingleCore;
|
use heapless::spsc::SingleCore;
|
||||||
pub use heapless::{consts, i::Queue as iQueue, spsc::Queue};
|
pub use heapless::{consts, i::Queue as iQueue, spsc::Queue};
|
||||||
pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap};
|
pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap};
|
||||||
|
pub use rtic_core::monotonic::Monotonic;
|
||||||
|
|
||||||
pub type SCFQ<N> = Queue<u8, N, u8, SingleCore>;
|
pub type SCFQ<N> = Queue<u8, N, u8, SingleCore>;
|
||||||
pub type SCRQ<T, N> = Queue<(T, u8), N, u8, SingleCore>;
|
pub type SCRQ<T, N> = Queue<(T, u8), N, u8, SingleCore>;
|
||||||
|
@ -112,6 +113,13 @@ where
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn assert_monotonic<T>()
|
||||||
|
where
|
||||||
|
T: Monotonic,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// Lock the resource proxy by setting the BASEPRI
|
/// Lock the resource proxy by setting the BASEPRI
|
||||||
/// and running the closure with interrupt::free
|
/// and running the closure with interrupt::free
|
||||||
///
|
///
|
||||||
|
|
|
@ -39,7 +39,10 @@ use core::ops::Sub;
|
||||||
|
|
||||||
use cortex_m::{interrupt::Nr, peripheral::NVIC};
|
use cortex_m::{interrupt::Nr, peripheral::NVIC};
|
||||||
pub use cortex_m_rtic_macros::app;
|
pub use cortex_m_rtic_macros::app;
|
||||||
pub use rtic_core::{prelude as mutex_prelude, Exclusive, monotonic::Monotonic, Mutex};
|
pub use rtic_core::{
|
||||||
|
monotonic::{Clock, Instant, Monotonic},
|
||||||
|
prelude as mutex_prelude, Exclusive, Mutex,
|
||||||
|
};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod export;
|
pub mod export;
|
||||||
|
|
Loading…
Reference in a new issue