From 3b4c10e790e63ac328a7bdb98451ac11d5935731 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 26 Nov 2020 18:07:22 +0100 Subject: [PATCH 01/36] Removed monotonic trait, moved to rtic-core --- src/lib.rs | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f1fb550b53..385b5ea3da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,50 +108,6 @@ impl From for Peripherals { } } -/// A fraction -pub struct Fraction { - /// The numerator - pub numerator: u32, - - /// The denominator - pub denominator: u32, -} - -/// A monotonic clock / counter -pub trait Monotonic { - /// A measurement of this clock, use `CYCCNT` as a reference implementation for `Instant`. - /// Note that the Instant must be a signed value such as `i32`. - type Instant: Copy + Ord + Sub; - - /// The ratio between the system timer (SysTick) frequency and this clock frequency, i.e. - /// `Monotonic clock * Fraction = System clock` - /// - /// The ratio must be expressed in *reduced* `Fraction` form to prevent overflows. That is - /// `2 / 3` instead of `4 / 6` - fn ratio() -> Fraction; - - /// Returns the current time - /// - /// # Correctness - /// - /// This function is *allowed* to return nonsensical values if called before `reset` is invoked - /// by the runtime. Therefore application authors should *not* call this function during the - /// `#[init]` phase. - fn now() -> Self::Instant; - - /// Resets the counter to *zero* - /// - /// # Safety - /// - /// This function will be called *exactly once* by the RTIC runtime after `#[init]` returns and - /// before tasks can start; this is also the case in multi-core applications. User code must - /// *never* call this function. - unsafe fn reset(); - - /// A `Self::Instant` that represents a count of *zero* - fn zero() -> Self::Instant; -} - /// Sets the given `interrupt` as pending /// /// This is a convenience function around From ef50aeb2e8245b69843280fabb62589c0716ffdd Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 3 Dec 2020 21:04:06 +0100 Subject: [PATCH 02/36] Save, init generation fixed --- Cargo.toml | 3 +- examples/test_new_monotonic.rs | 21 +++ macros/Cargo.toml | 2 +- macros/src/check.rs | 14 +- macros/src/codegen.rs | 2 - macros/src/codegen/init.rs | 28 ++- macros/src/codegen/module.rs | 6 + macros/src/codegen/post_init.rs | 3 + macros/src/codegen/util.rs | 8 + macros/src/lib.rs | 2 +- src/export.rs | 2 +- src/lib.rs | 68 +------ src/tq.rs | 312 ++++++++++++++++---------------- 13 files changed, 229 insertions(+), 242 deletions(-) create mode 100644 examples/test_new_monotonic.rs diff --git a/Cargo.toml b/Cargo.toml index 9a10ec276f..679dcc0425 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,8 @@ required-features = ["__v7"] [dependencies] cortex-m = "0.6.2" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } -rtic-core = "0.3.1" +rtic-core = { git = "https://github.com/rtic-rs/rtic-core", branch = "new_monotonic" } +#rtic-core = "0.3.1" heapless = "0.5.0" bare-metal = "1.0.0" diff --git a/examples/test_new_monotonic.rs b/examples/test_new_monotonic.rs new file mode 100644 index 0000000000..5aac48ba56 --- /dev/null +++ b/examples/test_new_monotonic.rs @@ -0,0 +1,21 @@ +//! examples/test_new_monotonic.rs + +#![no_main] +#![no_std] + +use panic_semihosting as _; // panic handler +use rtic::app; + +#[app(device = lm3s6965)] +mod app { + #[monotonic(binds = SomeISR1)] + type Mono1 = hal::Mono1; + + #[monotonic(binds = SomeISR2)] + type Mono2 = hal::Mono2; + + #[init] + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { + } +} + diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 3af48c7684..6996bef4a1 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -22,5 +22,5 @@ proc-macro2 = "1" proc-macro-error = "1" quote = "1" syn = "1" -rtic-syntax = { git = "https://github.com/rtic-rs/rtic-syntax", branch = "master", version = "0.5.0-alpha.0" } +rtic-syntax = { git = "https://github.com/rtic-rs/rtic-syntax", branch = "new_monotonic", version = "0.5.0-alpha.0" } diff --git a/macros/src/check.rs b/macros/src/check.rs index e3161cb950..42bd90db47 100644 --- a/macros/src/check.rs +++ b/macros/src/check.rs @@ -62,18 +62,6 @@ pub fn app(app: &App, _analysis: &Analysis) -> parse::Result { for (name, task) in &app.hardware_tasks { let name_s = task.args.binds.to_string(); match &*name_s { - "SysTick" => { - // If the timer queue is used, then SysTick is unavailable - if app.args.monotonic.is_some() { - return Err(parse::Error::new( - name.span(), - "this exception can't be used because it's being used by the runtime", - )); - } else { - // OK - } - } - "NonMaskableInt" | "HardFault" => { return Err(parse::Error::new( name.span(), @@ -88,7 +76,7 @@ pub fn app(app: &App, _analysis: &Analysis) -> parse::Result { if let Some(device) = app.args.device.clone() { Ok(Extra { device, - monotonic: app.args.monotonic.clone(), + monotonic: None, peripherals: app.args.peripherals, }) } else { diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 3cddf57018..52940bc3e0 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -61,8 +61,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { use super::*; #[no_mangle] unsafe extern "C" fn #main() -> ! { - let _TODO: () = (); - #(#assertion_stmts)* #(#pre_init_stmts)* diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 6376ce31c4..6b57add1b2 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -58,6 +58,24 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { } )); + 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_new = None; if !init.locals.is_empty() { @@ -72,10 +90,16 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let attrs = &init.attrs; let stmts = &init.stmts; let locals_pat = locals_pat.iter(); + + let mut user_init_return = vec![quote! {#name::LateResources}]; + if !app.monotonics.is_empty() { + user_init_return.push(quote! {#name::Monotonics}); + } + let user_init = Some(quote!( #(#attrs)* #[allow(non_snake_case)] - fn #name(#(#locals_pat,)* #context: #name::Context) -> #name::LateResources { + fn #name(#(#locals_pat,)* #context: #name::Context) -> (#(#user_init_return,)*) { #(#stmts)* } )); @@ -92,7 +116,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let app_path = quote! {crate::#app_name}; let locals_new = locals_new.iter(); let call_init = Some( - quote!(let late = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), + quote!(let (late, monotonics) = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), ); root_init.push(module::codegen( diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 2ff4801e43..d398a1a860 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -131,11 +131,17 @@ pub fn codegen( if let Context::Init = ctxt { let init = &app.inits.first().unwrap(); let late_resources = util::late_resources_ident(&init.name); + let monotonics = util::monotonics_ident(&init.name); items.push(quote!( #[doc(inline)] pub use super::#late_resources as LateResources; )); + + items.push(quote!( + #[doc(inline)] + pub use super::#monotonics as Monotonics; + )); } let doc = match ctxt { diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 5545944d18..9174daebcb 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -25,6 +25,9 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { } } + // Forget the monotonics so they won't be dropped. + stmts.push(quote!(core::mem::forget(monotonics);)); + // Enable the interrupts -- this completes the `init`-ialization phase stmts.push(quote!(rtic::export::interrupt::enable();)); diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index fb8f1a8450..4273ee2c42 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -111,6 +111,14 @@ pub fn late_resources_ident(init: &Ident) -> Ident { ) } +/// Generates a pre-reexport identifier for the "monotonics" struct +pub fn monotonics_ident(init: &Ident) -> Ident { + Ident::new( + &format!("{}Monotonics", init.to_string()), + Span::call_site(), + ) +} + /// Mangle an ident pub fn mangle_ident(ident: &Ident) -> Ident { Ident::new( diff --git a/macros/src/lib.rs b/macros/src/lib.rs index dc37eaea3c..c9136e5552 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(warnings)] +// #![deny(warnings)] extern crate proc_macro; diff --git a/src/export.rs b/src/export.rs index 72d954ab14..46793aa64e 100644 --- a/src/export.rs +++ b/src/export.rs @@ -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; diff --git a/src/lib.rs b/src/lib.rs index 385b5ea3da..c1930b034e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,82 +32,20 @@ #![deny(missing_docs)] #![deny(rust_2018_compatibility)] #![deny(rust_2018_idioms)] -#![deny(warnings)] +// #![deny(warnings)] #![no_std] use core::ops::Sub; -use cortex_m::{ - interrupt::Nr, - peripheral::{CBP, CPUID, DCB, DWT, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU}, -}; +use cortex_m::{interrupt::Nr, peripheral::NVIC}; pub use cortex_m_rtic_macros::app; -pub use rtic_core::{prelude as mutex_prelude, Exclusive, Mutex}; +pub use rtic_core::{prelude as mutex_prelude, Exclusive, monotonic::Monotonic, Mutex}; -#[cfg(armv7m)] -pub mod cyccnt; #[doc(hidden)] pub mod export; #[doc(hidden)] mod tq; -/// `cortex_m::Peripherals` minus `SYST` -#[allow(non_snake_case)] -pub struct Peripherals { - /// Cache and branch predictor maintenance operations (not present on Cortex-M0 variants) - pub CBP: CBP, - - /// CPUID - pub CPUID: CPUID, - - /// Debug Control Block - pub DCB: DCB, - - /// Data Watchpoint and Trace unit - pub DWT: DWT, - - /// Flash Patch and Breakpoint unit (not present on Cortex-M0 variants) - pub FPB: FPB, - - /// Floating Point Unit (only present on `thumbv7em-none-eabihf`) - pub FPU: FPU, - - /// Instrumentation Trace Macrocell (not present on Cortex-M0 variants) - pub ITM: ITM, - - /// Memory Protection Unit - pub MPU: MPU, - - /// Nested Vector Interrupt Controller - pub NVIC: NVIC, - - /// System Control Block - pub SCB: SCB, - - // SysTick: System Timer - // pub SYST: SYST, - /// Trace Port Interface Unit (not present on Cortex-M0 variants) - pub TPIU: TPIU, -} - -impl From for Peripherals { - fn from(p: cortex_m::Peripherals) -> Self { - Self { - CBP: p.CBP, - CPUID: p.CPUID, - DCB: p.DCB, - DWT: p.DWT, - FPB: p.FPB, - FPU: p.FPU, - ITM: p.ITM, - MPU: p.MPU, - NVIC: p.NVIC, - SCB: p.SCB, - TPIU: p.TPIU, - } - } -} - /// Sets the given `interrupt` as pending /// /// This is a convenience function around diff --git a/src/tq.rs b/src/tq.rs index b2a84c8593..f2539a991a 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -1,156 +1,156 @@ -use core::{ - cmp::{self, Ordering}, - convert::TryInto, - mem, - ops::Sub, -}; - -use cortex_m::peripheral::{SCB, SYST}; -use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; - -use crate::Monotonic; - -pub struct TimerQueue(pub BinaryHeap, N, Min>) -where - M: Monotonic, - ::Output: TryInto, - N: ArrayLength>, - T: Copy; - -impl TimerQueue -where - M: Monotonic, - ::Output: TryInto, - N: ArrayLength>, - T: Copy, -{ - /// # Safety - /// - /// Writing to memory with a transmute in order to enable - /// interrupts of the SysTick timer - /// - /// Enqueue a task without checking if it is full - #[inline] - pub unsafe fn enqueue_unchecked(&mut self, nr: NotReady) { - let mut is_empty = true; - // Check if the top contains a non-empty element and if that element is - // greater than nr - let if_heap_max_greater_than_nr = self - .0 - .peek() - .map(|head| { - is_empty = false; - nr.instant < head.instant - }) - .unwrap_or(true); - if if_heap_max_greater_than_nr { - if is_empty { - mem::transmute::<_, SYST>(()).enable_interrupt(); - } - - // Set SysTick pending - SCB::set_pendst(); - } - - self.0.push_unchecked(nr); - } - - /// Dequeue a task from the TimerQueue - #[inline] - pub fn dequeue(&mut self) -> Option<(T, u8)> { - unsafe { - if let Some(instant) = self.0.peek().map(|p| p.instant) { - let now = M::now(); - - if instant < now { - // task became ready - let nr = self.0.pop_unchecked(); - - Some((nr.task, nr.index)) - } else { - // set a new timeout - const MAX: u32 = 0x00ffffff; - - let ratio = M::ratio(); - let dur = match (instant - now).try_into().ok().and_then(|x| { - x.checked_mul(ratio.numerator) - .map(|x| x / ratio.denominator) - }) { - None => MAX, - - // ARM Architecture Reference Manual says: - // "Setting SYST_RVR to zero has the effect of - // disabling the SysTick counter independently - // of the counter enable bit." - Some(0) => 1, - - Some(x) => cmp::min(MAX, x), - }; - mem::transmute::<_, SYST>(()).set_reload(dur); - - // Start counting down from the new reload - mem::transmute::<_, SYST>(()).clear_current(); - - None - } - } else { - // The queue is empty - mem::transmute::<_, SYST>(()).disable_interrupt(); - - None - } - } - } -} - -pub struct NotReady -where - T: Copy, - M: Monotonic, - ::Output: TryInto, -{ - pub index: u8, - pub instant: M::Instant, - pub task: T, -} - -impl Eq for NotReady -where - T: Copy, - M: Monotonic, - ::Output: TryInto, -{ -} - -impl Ord for NotReady -where - T: Copy, - M: Monotonic, - ::Output: TryInto, -{ - fn cmp(&self, other: &Self) -> Ordering { - self.instant.cmp(&other.instant) - } -} - -impl PartialEq for NotReady -where - T: Copy, - M: Monotonic, - ::Output: TryInto, -{ - fn eq(&self, other: &Self) -> bool { - self.instant == other.instant - } -} - -impl PartialOrd for NotReady -where - T: Copy, - M: Monotonic, - ::Output: TryInto, -{ - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(&other)) - } -} +// use core::{ +// cmp::{self, Ordering}, +// convert::TryInto, +// mem, +// ops::Sub, +// }; +// +// use cortex_m::peripheral::{SCB, SYST}; +// use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; +// +// use crate::Monotonic; +// +// pub struct TimerQueue(pub BinaryHeap, N, Min>) +// where +// M: Monotonic, +// ::Output: TryInto, +// N: ArrayLength>, +// T: Copy; +// +// impl TimerQueue +// where +// M: Monotonic, +// ::Output: TryInto, +// N: ArrayLength>, +// T: Copy, +// { +// /// # Safety +// /// +// /// Writing to memory with a transmute in order to enable +// /// interrupts of the SysTick timer +// /// +// /// Enqueue a task without checking if it is full +// #[inline] +// pub unsafe fn enqueue_unchecked(&mut self, nr: NotReady) { +// let mut is_empty = true; +// // Check if the top contains a non-empty element and if that element is +// // greater than nr +// let if_heap_max_greater_than_nr = self +// .0 +// .peek() +// .map(|head| { +// is_empty = false; +// nr.instant < head.instant +// }) +// .unwrap_or(true); +// if if_heap_max_greater_than_nr { +// if is_empty { +// mem::transmute::<_, SYST>(()).enable_interrupt(); +// } +// +// // Set SysTick pending +// SCB::set_pendst(); +// } +// +// self.0.push_unchecked(nr); +// } +// +// /// Dequeue a task from the TimerQueue +// #[inline] +// pub fn dequeue(&mut self) -> Option<(T, u8)> { +// unsafe { +// if let Some(instant) = self.0.peek().map(|p| p.instant) { +// let now = M::now(); +// +// if instant < now { +// // task became ready +// let nr = self.0.pop_unchecked(); +// +// Some((nr.task, nr.index)) +// } else { +// // set a new timeout +// const MAX: u32 = 0x00ffffff; +// +// let ratio = M::ratio(); +// let dur = match (instant - now).try_into().ok().and_then(|x| { +// x.checked_mul(ratio.numerator) +// .map(|x| x / ratio.denominator) +// }) { +// None => MAX, +// +// // ARM Architecture Reference Manual says: +// // "Setting SYST_RVR to zero has the effect of +// // disabling the SysTick counter independently +// // of the counter enable bit." +// Some(0) => 1, +// +// Some(x) => cmp::min(MAX, x), +// }; +// mem::transmute::<_, SYST>(()).set_reload(dur); +// +// // Start counting down from the new reload +// mem::transmute::<_, SYST>(()).clear_current(); +// +// None +// } +// } else { +// // The queue is empty +// mem::transmute::<_, SYST>(()).disable_interrupt(); +// +// None +// } +// } +// } +// } +// +// pub struct NotReady +// where +// T: Copy, +// M: Monotonic, +// ::Output: TryInto, +// { +// pub index: u8, +// pub instant: M::Instant, +// pub task: T, +// } +// +// impl Eq for NotReady +// where +// T: Copy, +// M: Monotonic, +// ::Output: TryInto, +// { +// } +// +// impl Ord for NotReady +// where +// T: Copy, +// M: Monotonic, +// ::Output: TryInto, +// { +// fn cmp(&self, other: &Self) -> Ordering { +// self.instant.cmp(&other.instant) +// } +// } +// +// impl PartialEq for NotReady +// where +// T: Copy, +// M: Monotonic, +// ::Output: TryInto, +// { +// fn eq(&self, other: &Self) -> bool { +// self.instant == other.instant +// } +// } +// +// impl PartialOrd for NotReady +// where +// T: Copy, +// M: Monotonic, +// ::Output: TryInto, +// { +// fn partial_cmp(&self, other: &Self) -> Option { +// Some(self.cmp(&other)) +// } +// } From b23bb1192c8dc1f2e8f157db2147b1737abc1033 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 8 Dec 2020 20:49:13 +0100 Subject: [PATCH 03/36] TQ handlers being generated --- examples/test_new_monotonic.rs | 8 +- macros/src/check.rs | 2 - macros/src/codegen/dispatchers.rs | 26 +++-- macros/src/codegen/hardware_tasks.rs | 17 +-- macros/src/codegen/module.rs | 162 ++++++++++++++------------- macros/src/codegen/pre_init.rs | 31 ++--- macros/src/codegen/software_tasks.rs | 23 ++-- macros/src/codegen/timer_queue.rs | 20 +++- macros/src/codegen/util.rs | 6 +- src/export.rs | 2 +- 10 files changed, 157 insertions(+), 140 deletions(-) diff --git a/examples/test_new_monotonic.rs b/examples/test_new_monotonic.rs index 5aac48ba56..b3890581c2 100644 --- a/examples/test_new_monotonic.rs +++ b/examples/test_new_monotonic.rs @@ -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) {} } diff --git a/macros/src/check.rs b/macros/src/check.rs index 42bd90db47..374fcedd09 100644 --- a/macros/src/check.rs +++ b/macros/src/check.rs @@ -6,7 +6,6 @@ use syn::{parse, Path}; pub struct Extra { pub device: Path, - pub monotonic: Option, pub peripherals: bool, } @@ -76,7 +75,6 @@ pub fn app(app: &App, _analysis: &Analysis) -> parse::Result { if let Some(device) = app.args.device.clone() { Ok(Extra { device, - monotonic: None, peripherals: app.args.peripherals, }) } else { diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index a6c695f191..d0a3ba01da 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -70,19 +70,21 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec::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!() diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index d398a1a860..2c42adce70 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -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() { diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index 969de84a67..dfdb30a07e 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -74,24 +74,25 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> 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); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index fa2c7b3699..ccde957dd4 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -8,7 +8,7 @@ use crate::{analyze::Analysis, check::Extra, codegen::util}; pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { 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 Vec 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 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()) } diff --git a/src/export.rs b/src/export.rs index 46793aa64e..dedff2fb2e 100644 --- a/src/export.rs +++ b/src/export.rs @@ -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; From 97a48983d2859740983cbf342e1287182426ed44 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 10 Dec 2020 20:33:13 +0100 Subject: [PATCH 04/36] More work --- examples/test_new_monotonic.rs | 6 +- macros/src/codegen.rs | 14 ++- macros/src/codegen/assertions.rs | 8 +- macros/src/codegen/dispatchers.rs | 2 +- macros/src/codegen/init.rs | 53 +------- macros/src/codegen/module.rs | 198 +++++++++++++++--------------- macros/src/codegen/pre_init.rs | 35 +++--- macros/src/codegen/timer_queue.rs | 2 +- src/export.rs | 8 ++ src/lib.rs | 5 +- 10 files changed, 155 insertions(+), 176 deletions(-) diff --git a/examples/test_new_monotonic.rs b/examples/test_new_monotonic.rs index b3890581c2..d2530c660b 100644 --- a/examples/test_new_monotonic.rs +++ b/examples/test_new_monotonic.rs @@ -9,10 +9,10 @@ use rtic::app; #[app(device = lm3s6965, dispatchers = [UART])] mod app { #[monotonic(binds = SomeISR1)] - type Mono1 = hal::Mono1; + type MyMono1 = hal::Mono1; - #[monotonic(binds = SomeISR2)] - type Mono2 = hal::Mono2; + #[monotonic(binds = SomeISR2, default = true)] + type MyMono2 = hal::Mono2; #[init] fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 52940bc3e0..03bac849e2 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -27,13 +27,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let mut user = vec![]; // 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 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); @@ -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!( /// Implementation details pub mod #name { /// 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; + #(#monotonic_imports)* + #(#user_imports)* /// User code from within the module diff --git a/macros/src/codegen/assertions.rs b/macros/src/codegen/assertions.rs index 4d9aae4725..a8a4491bdf 100644 --- a/macros/src/codegen/assertions.rs +++ b/macros/src/codegen/assertions.rs @@ -2,9 +2,10 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use crate::analyze::Analysis; +use rtic_syntax::ast::App; /// Generates compile-time assertions that check that types implement the `Send` / `Sync` traits -pub fn codegen(analysis: &Analysis) -> Vec { +pub fn codegen(app: &App, analysis: &Analysis) -> Vec { let mut stmts = vec![]; for ty in &analysis.send_types { @@ -15,5 +16,10 @@ pub fn codegen(analysis: &Analysis) -> Vec { 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 } diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index d0a3ba01da..01fb511930 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -5,7 +5,7 @@ use rtic_syntax::ast::App; use crate::{analyze::Analysis, check::Extra, codegen::util}; /// Generates task dispatchers -pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { +pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec { let mut items = vec![]; let interrupts = &analysis.interrupts; diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 6b57add1b2..66c3bc4e69 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -5,7 +5,7 @@ use rtic_syntax::{ast::App, Context}; use crate::{ analyze::Analysis, check::Extra, - codegen::{locals, module, resources_struct, util}, + codegen::{locals, module, resources_struct}, }; type CodegenResult = ( @@ -32,50 +32,6 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { 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::>(); - - 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_new = None; if !init.locals.is_empty() { @@ -91,15 +47,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let stmts = &init.stmts; let locals_pat = locals_pat.iter(); - let mut user_init_return = vec![quote! {#name::LateResources}]; - if !app.monotonics.is_empty() { - user_init_return.push(quote! {#name::Monotonics}); - } + let user_init_return = quote! {#name::LateResources, #name::Monotonics}; let user_init = Some(quote!( #(#attrs)* #[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)* } )); diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 2c42adce70..6dd6e9a7f4 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -19,29 +19,13 @@ pub fn codegen( let name = ctxt.ident(app); - let mut needs_instant = false; let mut lt = None; match ctxt { Context::Init => { - // 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())); - - // 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 + pub core: rtic::export::Peripherals + )); if extra.peripherals { let device = &extra.device; @@ -68,31 +52,11 @@ pub fn codegen( Context::Idle => {} Context::HardwareTask(..) => { - // 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)); - - // needs_instant = true; - // } + // None for now. } Context::SoftwareTask(..) => { - // 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)); - - // needs_instant = true; - // } + // None for now. } } @@ -132,18 +96,45 @@ pub fn codegen( } if let Context::Init = ctxt { - let init = &app.inits.first().unwrap(); - let late_resources = util::late_resources_ident(&init.name); - let monotonics = util::monotonics_ident(&init.name); + 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::>(); items.push(quote!( - #[doc(inline)] - pub use super::#late_resources as LateResources; + /// Resources initialized at runtime + #[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!( - #[doc(inline)] - pub use super::#monotonics as Monotonics; + /// Monotonics used by the system + #[allow(non_snake_case)] + pub struct Monotonics( + #(#monotonic_types),* + ); )); } @@ -166,16 +157,6 @@ pub fn codegen( 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!( /// Execution context pub struct Context<#lt> { @@ -184,7 +165,7 @@ pub fn codegen( impl<#lt> Context<#lt> { #[inline(always)] - pub unsafe fn new(#core #priority #instant) -> Self { + pub unsafe fn new(#core #priority) -> Self { Context { #(#values,)* } @@ -202,7 +183,7 @@ pub fn codegen( let cfgs = &spawnee.cfgs; // Store a copy of the task cfgs 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 tupled = &tupled; let fq = util::fq_ident(name); @@ -251,51 +232,70 @@ pub fn codegen( })); - // TODO: Needs updating for new monotonic. - // // Schedule caller - // if let Some(m) = &extra.monotonic { - // let instants = util::instants_ident(name); + // Schedule caller + for (_, monotonic) in &app.monotonics { + let instants = util::instants_ident(name); - // let tq = util::tq_ident(); - // let t = util::schedule_t_ident(); + let tq = util::tq_ident(&monotonic.ident.to_string()); + let t = util::schedule_t_ident(); + let m = &monotonic.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::*; + if monotonic.args.default { + items.push(quote!(pub use #m::spawn_after;)); + items.push(quote!(pub use #m::spawn_at;)); + } - // 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); + items.push(quote!( + pub mod #m { + #(#cfgs)* + pub fn spawn_after( + duration: rtic::Duration, + #(,#args)* + ) -> Result<(), #ty> { + let instant = <#app_path::#m as rtic::Monotonic>::now(); - // #app_path::#instants - // .get_unchecked_mut(usize::from(index)) - // .as_mut_ptr() - // .write(instant); + spawn_at(instant + duration, #(,#untupled)*) + } - // let nr = rtic::export::NotReady { - // instant, - // index, - // task: #app_path::#t::#name, - // }; + #(#cfgs)* + pub fn spawn_at( + instant: Instant<#app_path::#m as rtic::Monotonic> + #(,#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(()) - // } else { - // Err(input) - // } - // } - // })); - // } + #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, + }; + + 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() { diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index dfdb30a07e..26ba558c8f 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -74,25 +74,26 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec { +pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec { let mut items = vec![]; if !app.monotonics.is_empty() { diff --git a/src/export.rs b/src/export.rs index dedff2fb2e..080b1f6717 100644 --- a/src/export.rs +++ b/src/export.rs @@ -16,6 +16,7 @@ pub use cortex_m::{ use heapless::spsc::SingleCore; pub use heapless::{consts, i::Queue as iQueue, spsc::Queue}; pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap}; +pub use rtic_core::monotonic::Monotonic; pub type SCFQ = Queue; pub type SCRQ = Queue<(T, u8), N, u8, SingleCore>; @@ -112,6 +113,13 @@ where { } +#[inline(always)] +pub fn assert_monotonic() +where + T: Monotonic, +{ +} + /// Lock the resource proxy by setting the BASEPRI /// and running the closure with interrupt::free /// diff --git a/src/lib.rs b/src/lib.rs index c1930b034e..ade126781e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,10 @@ use core::ops::Sub; use cortex_m::{interrupt::Nr, peripheral::NVIC}; 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)] pub mod export; From 8e8ec9b7b879adae8d4de6cb2320b9b19290a7e0 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 12 Dec 2020 23:24:54 +0100 Subject: [PATCH 05/36] Monotonic codegen now passing compile stage --- macros/src/codegen/dispatchers.rs | 19 +- macros/src/codegen/module.rs | 21 +- macros/src/codegen/software_tasks.rs | 27 +-- macros/src/codegen/timer_queue.rs | 8 +- macros/src/codegen/util.rs | 20 +- src/export.rs | 2 +- src/lib.rs | 4 +- src/tq.rs | 307 +++++++++++++-------------- 8 files changed, 189 insertions(+), 219 deletions(-) diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index 01fb511930..d3adee0d42 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -70,22 +70,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec { let #tupled = #inputs.get_unchecked(usize::from(index)).as_ptr().read(); - #let_instant #fq.split().0.enqueue_unchecked(index); let priority = &rtic::export::Priority::new(PRIORITY); #app_path::#name( #locals_new - #name::Context::new(priority #instant) + #name::Context::new(priority) #(,#pats)* ) } diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 6dd6e9a7f4..0f495d9783 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -18,6 +18,8 @@ pub fn codegen( let mut task_cfgs = vec![]; let name = ctxt.ident(app); + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; let mut lt = None; match ctxt { @@ -125,7 +127,7 @@ pub fn codegen( .iter() .map(|(_, monotonic)| { let mono = &monotonic.ident; - quote! {#mono} + quote! {#app_path::#mono} }) .collect(); @@ -190,9 +192,6 @@ pub fn codegen( let rq = util::rq_ident(priority); let inputs = util::inputs_ident(name); - let app_name = &app.name; - let app_path = quote! {crate::#app_name}; - let device = &extra.device; let enum_ = util::interrupt_ident(); let interrupt = &analysis @@ -234,11 +233,13 @@ pub fn codegen( // Schedule caller for (_, monotonic) in &app.monotonics { - let instants = util::instants_ident(name); + let instants = util::monotonic_instants_ident(name, &monotonic.ident); let tq = util::tq_ident(&monotonic.ident.to_string()); let t = util::schedule_t_ident(); let m = &monotonic.ident; + let m_isr = &monotonic.args.binds; + let enum_ = util::interrupt_ident(); if monotonic.args.default { items.push(quote!(pub use #m::spawn_after;)); @@ -259,7 +260,7 @@ pub fn codegen( #(#cfgs)* pub fn spawn_at( - instant: Instant<#app_path::#m as rtic::Monotonic> + instant: rtic::Instant<#app_path::#m> #(,#args)* ) -> Result<(), #ty> { unsafe { @@ -284,9 +285,11 @@ pub fn codegen( 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. + rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( + nr, + || rtic::export::NVIC::unmask(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), + || rtic::pend(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), + )); Ok(()) } else { diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index 7b884eadb2..ebe7bdf48e 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -57,19 +57,22 @@ pub fn codegen( .map(|_| quote!(core::mem::MaybeUninit::uninit())) .collect::>(); - // TODO: Update for new monotonic - // if let Some(m) = &extra.monotonic { - // let instants = util::instants_ident(name); + let app_name = &app.name; + let app_path = quote! {crate::#app_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,)*]; - // )); - // } + for (_, monotonic) in &app.monotonics { + let instants = util::monotonic_instants_ident(name, &monotonic.ident); + let m = &monotonic.ident; + + 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>; #cap_lit] = + [#(#elems,)*]; + )); + } let uninit = mk_uninit(); let inputs_ident = util::inputs_ident(name); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index f219eef230..dc29835577 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -67,6 +67,8 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec Vec>(); let bound_interrupt = &monotonic.args.binds; + items.push(quote!( #[no_mangle] unsafe fn #bound_interrupt() { use rtic::Mutex as _; - while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue()) + while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue( + || rtic::export::NVIC::unmask(you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#bound_interrupt), + )) { match task { #(#arms)* diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index d9310dde9f..329a7ddf6d 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -77,8 +77,8 @@ pub fn inputs_ident(task: &Ident) -> Ident { } /// Generates an identifier for the `INSTANTS` buffer (`schedule` API) -pub fn instants_ident(task: &Ident) -> Ident { - Ident::new(&format!("{}_INSTANTS", task), Span::call_site()) +pub fn monotonic_instants_ident(task: &Ident, monotonic: &Ident) -> Ident { + Ident::new(&format!("{}_{}_INSTANTS", task, monotonic), Span::call_site()) } pub fn interrupt_ident() -> Ident { @@ -103,22 +103,6 @@ pub fn is_exception(name: &Ident) -> bool { ) } -/// Generates a pre-reexport identifier for the "late resources" struct -pub fn late_resources_ident(init: &Ident) -> Ident { - Ident::new( - &format!("{}LateResources", init.to_string()), - Span::call_site(), - ) -} - -/// Generates a pre-reexport identifier for the "monotonics" struct -pub fn monotonics_ident(init: &Ident) -> Ident { - Ident::new( - &format!("{}Monotonics", init.to_string()), - Span::call_site(), - ) -} - /// Mangle an ident pub fn mangle_ident(ident: &Ident) -> Ident { Ident::new( diff --git a/src/export.rs b/src/export.rs index 080b1f6717..ab5984e83c 100644 --- a/src/export.rs +++ b/src/export.rs @@ -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; diff --git a/src/lib.rs b/src/lib.rs index ade126781e..c85090fbd7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,12 +35,10 @@ // #![deny(warnings)] #![no_std] -use core::ops::Sub; - use cortex_m::{interrupt::Nr, peripheral::NVIC}; pub use cortex_m_rtic_macros::app; pub use rtic_core::{ - monotonic::{Clock, Instant, Monotonic}, + monotonic::{self, Clock, Duration, Instant, Monotonic}, prelude as mutex_prelude, Exclusive, Mutex, }; diff --git a/src/tq.rs b/src/tq.rs index f2539a991a..2bfb651eee 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -1,156 +1,151 @@ -// use core::{ -// cmp::{self, Ordering}, -// convert::TryInto, -// mem, -// ops::Sub, -// }; -// -// use cortex_m::peripheral::{SCB, SYST}; -// use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; -// -// use crate::Monotonic; -// -// pub struct TimerQueue(pub BinaryHeap, N, Min>) -// where -// M: Monotonic, -// ::Output: TryInto, -// N: ArrayLength>, -// T: Copy; -// -// impl TimerQueue -// where -// M: Monotonic, -// ::Output: TryInto, -// N: ArrayLength>, -// T: Copy, -// { -// /// # Safety -// /// -// /// Writing to memory with a transmute in order to enable -// /// interrupts of the SysTick timer -// /// -// /// Enqueue a task without checking if it is full -// #[inline] -// pub unsafe fn enqueue_unchecked(&mut self, nr: NotReady) { -// let mut is_empty = true; -// // Check if the top contains a non-empty element and if that element is -// // greater than nr -// let if_heap_max_greater_than_nr = self -// .0 -// .peek() -// .map(|head| { -// is_empty = false; -// nr.instant < head.instant -// }) -// .unwrap_or(true); -// if if_heap_max_greater_than_nr { -// if is_empty { -// mem::transmute::<_, SYST>(()).enable_interrupt(); -// } -// -// // Set SysTick pending -// SCB::set_pendst(); -// } -// -// self.0.push_unchecked(nr); -// } -// -// /// Dequeue a task from the TimerQueue -// #[inline] -// pub fn dequeue(&mut self) -> Option<(T, u8)> { -// unsafe { -// if let Some(instant) = self.0.peek().map(|p| p.instant) { -// let now = M::now(); -// -// if instant < now { -// // task became ready -// let nr = self.0.pop_unchecked(); -// -// Some((nr.task, nr.index)) -// } else { -// // set a new timeout -// const MAX: u32 = 0x00ffffff; -// -// let ratio = M::ratio(); -// let dur = match (instant - now).try_into().ok().and_then(|x| { -// x.checked_mul(ratio.numerator) -// .map(|x| x / ratio.denominator) -// }) { -// None => MAX, -// -// // ARM Architecture Reference Manual says: -// // "Setting SYST_RVR to zero has the effect of -// // disabling the SysTick counter independently -// // of the counter enable bit." -// Some(0) => 1, -// -// Some(x) => cmp::min(MAX, x), -// }; -// mem::transmute::<_, SYST>(()).set_reload(dur); -// -// // Start counting down from the new reload -// mem::transmute::<_, SYST>(()).clear_current(); -// -// None -// } -// } else { -// // The queue is empty -// mem::transmute::<_, SYST>(()).disable_interrupt(); -// -// None -// } -// } -// } -// } -// -// pub struct NotReady -// where -// T: Copy, -// M: Monotonic, -// ::Output: TryInto, -// { -// pub index: u8, -// pub instant: M::Instant, -// pub task: T, -// } -// -// impl Eq for NotReady -// where -// T: Copy, -// M: Monotonic, -// ::Output: TryInto, -// { -// } -// -// impl Ord for NotReady -// where -// T: Copy, -// M: Monotonic, -// ::Output: TryInto, -// { -// fn cmp(&self, other: &Self) -> Ordering { -// self.instant.cmp(&other.instant) -// } -// } -// -// impl PartialEq for NotReady -// where -// T: Copy, -// M: Monotonic, -// ::Output: TryInto, -// { -// fn eq(&self, other: &Self) -> bool { -// self.instant == other.instant -// } -// } -// -// impl PartialOrd for NotReady -// where -// T: Copy, -// M: Monotonic, -// ::Output: TryInto, -// { -// fn partial_cmp(&self, other: &Self) -> Option { -// Some(self.cmp(&other)) -// } -// } +use crate::{Instant, Monotonic}; +use core::cmp::Ordering; +use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; + +pub struct TimerQueue(pub BinaryHeap, N, Min>) +where + M: Monotonic, + N: ArrayLength>, + T: Copy; + +impl TimerQueue +where + M: Monotonic, + N: ArrayLength>, + T: Copy, +{ + /// # Safety + /// + /// Writing to memory with a transmute in order to enable + /// interrupts of the SysTick timer + /// + /// Enqueue a task without checking if it is full + #[inline] + pub unsafe fn enqueue_unchecked( + &mut self, + nr: NotReady, + enable_interrupt: F1, + pend_handler: F2, + ) where + F1: FnOnce(), + F2: FnOnce(), + { + let mut is_empty = true; + // Check if the top contains a non-empty element and if that element is + // greater than nr + let if_heap_max_greater_than_nr = self + .0 + .peek() + .map(|head| { + is_empty = false; + nr.instant < head.instant + }) + .unwrap_or(true); + if if_heap_max_greater_than_nr { + if is_empty { + // mem::transmute::<_, SYST>(()).enable_interrupt(); + enable_interrupt(); + } + + // Set SysTick pending + // SCB::set_pendst(); + pend_handler(); + } + + self.0.push_unchecked(nr); + } + + /// Check if the timer queue is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Dequeue a task from the TimerQueue + #[inline] + pub fn dequeue(&mut self, disable_interrupt: F) -> Option<(T, u8)> + where + F: FnOnce(), + { + unsafe { + M::clear_compare(); + + if let Some(instant) = self.0.peek().map(|p| p.instant) { + let now = M::now(); + + match instant.checked_duration_since(&now) { + None => { + // instant < now + // task became ready + let nr = self.0.pop_unchecked(); + + Some((nr.task, nr.index)) + } + Some(dur) => { + // TODO: Fix this hack... + let new_instant = *now.duration_since_epoch().integer() + *dur.integer(); + M::set_compare(new_instant); + + // Start counting down from the new reload + // mem::transmute::<_, SYST>(()).clear_current(); + + None + } + } + } else { + // The queue is empty + // mem::transmute::<_, SYST>(()).disable_interrupt(); + disable_interrupt(); + + None + } + } + } +} + +pub struct NotReady +where + T: Copy, + M: Monotonic, +{ + pub index: u8, + pub instant: Instant, + pub task: T, +} + +impl Eq for NotReady +where + T: Copy, + M: Monotonic, +{ +} + +impl Ord for NotReady +where + T: Copy, + M: Monotonic, +{ + fn cmp(&self, other: &Self) -> Ordering { + self.instant.cmp(&other.instant) + } +} + +impl PartialEq for NotReady +where + T: Copy, + M: Monotonic, +{ + fn eq(&self, other: &Self) -> bool { + self.instant == other.instant + } +} + +impl PartialOrd for NotReady +where + T: Copy, + M: Monotonic, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(&other)) + } +} From 1c8de78f6f6e9e265d9d894d2ebde622bf16d44e Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 12 Dec 2020 23:31:05 +0100 Subject: [PATCH 06/36] Cleanup --- examples/test_new_monotonic.rs | 4 +--- macros/src/codegen.rs | 14 +++++++++----- macros/src/codegen/hardware_tasks.rs | 14 +------------- macros/src/codegen/util.rs | 5 ++++- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/examples/test_new_monotonic.rs b/examples/test_new_monotonic.rs index d2530c660b..3323c09b3b 100644 --- a/examples/test_new_monotonic.rs +++ b/examples/test_new_monotonic.rs @@ -15,8 +15,7 @@ mod app { type MyMono2 = hal::Mono2; #[init] - fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { - } + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) {} #[task] fn task1(_: task1::Context) {} @@ -24,4 +23,3 @@ mod app { #[task] fn task2(_: task2::Context) {} } - diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 03bac849e2..1219e14f97 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -104,11 +104,15 @@ 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(); + let monotonic_imports: Vec<_> = app + .monotonics + .iter() + .map(|(_, monotonic)| { + let name = &monotonic.ident; + let ty = &monotonic.ty; + quote!(pub type #name = #ty;) + }) + .collect(); quote!( /// Implementation details diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs index db3ab3a6e8..4a1d7492f4 100644 --- a/macros/src/codegen/hardware_tasks.rs +++ b/macros/src/codegen/hardware_tasks.rs @@ -29,16 +29,6 @@ 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) = (quote!(), quote!()); - let locals_new = if task.locals.is_empty() { quote!() } else { @@ -56,12 +46,10 @@ pub fn codegen( unsafe fn #symbol() { const PRIORITY: u8 = #priority; - #let_instant - rtic::export::run(PRIORITY, || { #app_path::#name( #locals_new - #name::Context::new(&rtic::export::Priority::new(PRIORITY) #instant) + #name::Context::new(&rtic::export::Priority::new(PRIORITY)) ) }); } diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 329a7ddf6d..a201dfe5c4 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -78,7 +78,10 @@ pub fn inputs_ident(task: &Ident) -> Ident { /// Generates an identifier for the `INSTANTS` buffer (`schedule` API) pub fn monotonic_instants_ident(task: &Ident, monotonic: &Ident) -> Ident { - Ident::new(&format!("{}_{}_INSTANTS", task, monotonic), Span::call_site()) + Ident::new( + &format!("{}_{}_INSTANTS", task, monotonic), + Span::call_site(), + ) } pub fn interrupt_ident() -> Ident { From 35b4ec0d0435879cca97536b5c866fc2ac2e9210 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 00:06:50 +0100 Subject: [PATCH 07/36] Reexport embedded-time as rtic::time --- macros/src/codegen/module.rs | 4 ++-- macros/src/codegen/software_tasks.rs | 2 +- src/lib.rs | 2 +- src/tq.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 0f495d9783..2b6042c8c8 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -250,7 +250,7 @@ pub fn codegen( pub mod #m { #(#cfgs)* pub fn spawn_after( - duration: rtic::Duration, + duration: rtic::time::duration::Duration, #(,#args)* ) -> Result<(), #ty> { let instant = <#app_path::#m as rtic::Monotonic>::now(); @@ -260,7 +260,7 @@ pub fn codegen( #(#cfgs)* pub fn spawn_at( - instant: rtic::Instant<#app_path::#m> + instant: rtic::time::Instant<#app_path::#m> #(,#args)* ) -> Result<(), #ty> { unsafe { diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index ebe7bdf48e..53de50b9f7 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -69,7 +69,7 @@ pub fn codegen( #uninit /// Buffer that holds the instants associated to the inputs of a task static mut #instants: - [core::mem::MaybeUninit>; #cap_lit] = + [core::mem::MaybeUninit>; #cap_lit] = [#(#elems,)*]; )); } diff --git a/src/lib.rs b/src/lib.rs index c85090fbd7..0840589156 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,7 @@ use cortex_m::{interrupt::Nr, peripheral::NVIC}; pub use cortex_m_rtic_macros::app; pub use rtic_core::{ - monotonic::{self, Clock, Duration, Instant, Monotonic}, + monotonic::{self, embedded_time as time, Monotonic}, prelude as mutex_prelude, Exclusive, Mutex, }; diff --git a/src/tq.rs b/src/tq.rs index 2bfb651eee..a98eed6f0a 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -1,4 +1,4 @@ -use crate::{Instant, Monotonic}; +use crate::{time::Instant, Monotonic}; use core::cmp::Ordering; use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; From dd52539e32690c5cff73efe40c5d443b770d82a0 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 00:09:44 +0100 Subject: [PATCH 08/36] Less ... hacky? --- src/tq.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tq.rs b/src/tq.rs index a98eed6f0a..88593927ac 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -81,9 +81,10 @@ where Some((nr.task, nr.index)) } - Some(dur) => { + Some(_) => { // TODO: Fix this hack... - let new_instant = *now.duration_since_epoch().integer() + *dur.integer(); + // Extract the compare time + let new_instant = *instant.duration_since_epoch().integer(); M::set_compare(new_instant); // Start counting down from the new reload From 0e134a41b5f53843b5e1c90cd0633ae56b7a3113 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 14:20:28 +0100 Subject: [PATCH 09/36] Double check the compare instant --- src/tq.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/tq.rs b/src/tq.rs index 88593927ac..5903b3f73d 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -84,13 +84,22 @@ where Some(_) => { // TODO: Fix this hack... // Extract the compare time - let new_instant = *instant.duration_since_epoch().integer(); - M::set_compare(new_instant); + M::set_compare(*instant.duration_since_epoch().integer()); + + // Double check that the instant we set is really in the future, else + // dequeue. If the monotonic is fast enough it can happen that from the + // read of now to the set of the compare, the time can overflow. This is to + // guard against this. + if instant.checked_duration_since(&M::now()).is_none() { + let nr = self.0.pop_unchecked(); + + Some((nr.task, nr.index)) + } else { + None + } // Start counting down from the new reload // mem::transmute::<_, SYST>(()).clear_current(); - - None } } } else { From 62771839061aaa7dd518d40969bee609d7d2bda8 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 14:52:16 +0100 Subject: [PATCH 10/36] Now handling SysTick as well --- examples/test_new_monotonic.rs | 2 +- macros/src/codegen.rs | 4 +++- macros/src/codegen/module.rs | 17 ++++++++++++++-- macros/src/codegen/pre_init.rs | 32 +++++++++++++++++++++---------- macros/src/codegen/timer_queue.rs | 12 ++++++++++-- macros/src/codegen/util.rs | 11 ++++++++++- 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/examples/test_new_monotonic.rs b/examples/test_new_monotonic.rs index 3323c09b3b..67883465b6 100644 --- a/examples/test_new_monotonic.rs +++ b/examples/test_new_monotonic.rs @@ -8,7 +8,7 @@ use rtic::app; #[app(device = lm3s6965, dispatchers = [UART])] mod app { - #[monotonic(binds = SomeISR1)] + #[monotonic(binds = SysTick)] type MyMono1 = hal::Mono1; #[monotonic(binds = SomeISR2, default = true)] diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 1219e14f97..bb8aa4e751 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -114,11 +114,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { }) .collect(); + let rt_err = util::rt_err_ident(); + quote!( /// Implementation details pub mod #name { /// 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 #rt_err; #(#monotonic_imports)* diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 2b6042c8c8..bf77c4d9fb 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -246,6 +246,19 @@ pub fn codegen( items.push(quote!(pub use #m::spawn_at;)); } + let (unmask, pend) = if &*m_isr.to_string() == "SysTick" { + ( + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()), + quote!(cortex_m::peripheral::SCB::set_pendst()), + ) + } 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)), + ) + }; + items.push(quote!( pub mod #m { #(#cfgs)* @@ -287,8 +300,8 @@ pub fn codegen( rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( nr, - || rtic::export::NVIC::unmask(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), - || rtic::pend(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr), + || #unmask, + || #pend, )); Ok(()) diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index 26ba558c8f..e7b1b03bc6 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -8,6 +8,8 @@ use crate::{analyze::Analysis, check::Extra, codegen::util}; pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { let mut stmts = vec![]; + let rt_err = util::rt_err_ident(); + // Disable interrupts -- `init` must run with interrupts disabled stmts.push(quote!(rtic::export::interrupt::disable();)); @@ -47,14 +49,14 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec Vec Vec Vec>(); let bound_interrupt = &monotonic.args.binds; + let enable_isr = if &*bound_interrupt.to_string() == "SysTick" { + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).enable_interrupt()) + } else { + quote!(rtic::export::NVIC::mask(#rt_err::#enum_::#bound_interrupt)) + }; items.push(quote!( #[no_mangle] @@ -106,7 +114,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Ident { /// Generates an identifier for the `enum` of `schedule`-able tasks pub fn schedule_t_ident() -> Ident { - Ident::new(&"SCHED_T".to_string(), Span::call_site()) + Ident::new(&"SCHED_T", Span::call_site()) } /// Generates an identifier for the `enum` of `spawn`-able tasks @@ -228,6 +228,7 @@ pub fn spawn_t_ident(priority: u8) -> Ident { Ident::new(&format!("P{}_T", priority), Span::call_site()) } +/// Suffixed identifier pub fn suffixed(name: &str) -> Ident { let span = Span::call_site(); Ident::new(name, span) @@ -237,3 +238,11 @@ pub fn suffixed(name: &str) -> Ident { pub fn tq_ident(name: &str) -> Ident { Ident::new(&format!("TQ_{}", name), Span::call_site()) } + +/// The name to get better RT flag errors +pub fn rt_err_ident() -> Ident { + Ident::new( + &"you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml", + Span::call_site(), + ) +} From aaa92ea2fac23d2679b5efc1178a45d994762bca Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 13 Dec 2020 17:48:11 +0100 Subject: [PATCH 11/36] Cleanup --- macros/src/codegen/module.rs | 7 --- macros/src/codegen/timer_queue.rs | 4 -- src/tq.rs | 99 +++++++++++++++---------------- 3 files changed, 47 insertions(+), 63 deletions(-) diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index bf77c4d9fb..d15b5eca8a 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -204,10 +204,6 @@ pub fn codegen( items.push(quote!( #(#cfgs)* pub fn spawn(#(#args,)*) -> Result<(), #ty> { - // #let_instant // do we need it? - use rtic::Mutex as _; - use rtic::mutex_prelude::*; - let input = #tupled; unsafe { @@ -277,9 +273,6 @@ pub fn codegen( #(,#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 diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index ef0fda37df..99dfa5bf2a 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -68,8 +68,6 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec(pub BinaryHeap, N, Min>) +pub struct TimerQueue(pub BinaryHeap, N, Min>) where - M: Monotonic, - N: ArrayLength>, - T: Copy; + Mono: Monotonic, + N: ArrayLength>, + Task: Copy; -impl TimerQueue +impl TimerQueue where - M: Monotonic, - N: ArrayLength>, - T: Copy, + Mono: Monotonic, + N: ArrayLength>, + Task: Copy, { /// # Safety /// @@ -23,7 +23,7 @@ where #[inline] pub unsafe fn enqueue_unchecked( &mut self, - nr: NotReady, + nr: NotReady, enable_interrupt: F1, pend_handler: F2, ) where @@ -63,44 +63,39 @@ where /// Dequeue a task from the TimerQueue #[inline] - pub fn dequeue(&mut self, disable_interrupt: F) -> Option<(T, u8)> + pub fn dequeue(&mut self, disable_interrupt: F) -> Option<(Task, u8)> where F: FnOnce(), { unsafe { - M::clear_compare(); + Mono::clear_compare(); if let Some(instant) = self.0.peek().map(|p| p.instant) { - let now = M::now(); + if instant < Mono::now() { + // instant < now + // task became ready + let nr = self.0.pop_unchecked(); - match instant.checked_duration_since(&now) { - None => { - // instant < now - // task became ready + Some((nr.task, nr.index)) + } else { + // TODO: Fix this hack... + // Extract the compare time + Mono::set_compare(*instant.duration_since_epoch().integer()); + + // Double check that the instant we set is really in the future, else + // dequeue. If the monotonic is fast enough it can happen that from the + // read of now to the set of the compare, the time can overflow. This is to + // guard against this. + if instant < Mono::now() { let nr = self.0.pop_unchecked(); Some((nr.task, nr.index)) + } else { + None } - Some(_) => { - // TODO: Fix this hack... - // Extract the compare time - M::set_compare(*instant.duration_since_epoch().integer()); - // Double check that the instant we set is really in the future, else - // dequeue. If the monotonic is fast enough it can happen that from the - // read of now to the set of the compare, the time can overflow. This is to - // guard against this. - if instant.checked_duration_since(&M::now()).is_none() { - let nr = self.0.pop_unchecked(); - - Some((nr.task, nr.index)) - } else { - None - } - - // Start counting down from the new reload - // mem::transmute::<_, SYST>(()).clear_current(); - } + // Start counting down from the new reload + // mem::transmute::<_, SYST>(()).clear_current(); } } else { // The queue is empty @@ -113,47 +108,47 @@ where } } -pub struct NotReady +pub struct NotReady where - T: Copy, - M: Monotonic, + Task: Copy, + Mono: Monotonic, { pub index: u8, - pub instant: Instant, - pub task: T, + pub instant: Instant, + pub task: Task, } -impl Eq for NotReady +impl Eq for NotReady where - T: Copy, - M: Monotonic, + Task: Copy, + Mono: Monotonic, { } -impl Ord for NotReady +impl Ord for NotReady where - T: Copy, - M: Monotonic, + Task: Copy, + Mono: Monotonic, { fn cmp(&self, other: &Self) -> Ordering { self.instant.cmp(&other.instant) } } -impl PartialEq for NotReady +impl PartialEq for NotReady where - T: Copy, - M: Monotonic, + Task: Copy, + Mono: Monotonic, { fn eq(&self, other: &Self) -> bool { self.instant == other.instant } } -impl PartialOrd for NotReady +impl PartialOrd for NotReady where - T: Copy, - M: Monotonic, + Task: Copy, + Mono: Monotonic, { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(&other)) From 0658d53843d5452085e7458269e0abebbf431971 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 10 Jan 2021 15:47:25 +0100 Subject: [PATCH 12/36] cleanup --- src/tq.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/tq.rs b/src/tq.rs index be854a5e05..4c89a66c46 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -72,14 +72,13 @@ where if let Some(instant) = self.0.peek().map(|p| p.instant) { if instant < Mono::now() { - // instant < now // task became ready let nr = self.0.pop_unchecked(); Some((nr.task, nr.index)) } else { // TODO: Fix this hack... - // Extract the compare time + // Extract the compare time. Mono::set_compare(*instant.duration_since_epoch().integer()); // Double check that the instant we set is really in the future, else @@ -93,13 +92,9 @@ where } else { None } - - // Start counting down from the new reload - // mem::transmute::<_, SYST>(()).clear_current(); } } else { - // The queue is empty - // mem::transmute::<_, SYST>(()).disable_interrupt(); + // The queue is empty, disable the interrupt. disable_interrupt(); None From 6fb43fa97be75f00553e0026ac06f107ee832dc2 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 4 Feb 2021 20:22:02 +0100 Subject: [PATCH 13/36] Minor fixes --- macros/src/codegen/module.rs | 11 +++++++---- macros/src/codegen/post_init.rs | 4 ++++ macros/src/codegen/timer_queue.rs | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index d15b5eca8a..93fbeaef03 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -135,7 +135,7 @@ pub fn codegen( /// Monotonics used by the system #[allow(non_snake_case)] pub struct Monotonics( - #(#monotonic_types),* + #(pub #monotonic_types),* ); )); } @@ -258,10 +258,13 @@ pub fn codegen( items.push(quote!( pub mod #m { #(#cfgs)* - pub fn spawn_after( - duration: rtic::time::duration::Duration, + pub fn spawn_after( + duration: D, #(,#args)* - ) -> Result<(), #ty> { + ) -> Result<(), #ty> + where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, + D::T: Into<<#app_path::#m as rtic::time::Clock>::T>, + { let instant = <#app_path::#m as rtic::Monotonic>::now(); spawn_at(instant + duration, #(,#untupled)*) diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 9174daebcb..9268e040f1 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -25,6 +25,10 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { } } + for (monotonic, _) in app.monotonics.iter() { + stmts.push(quote!(#monotonic::reset();)); + } + // Forget the monotonics so they won't be dropped. stmts.push(quote!(core::mem::forget(monotonics);)); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 99dfa5bf2a..9a430a0717 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -108,6 +108,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Thu, 18 Feb 2021 19:30:59 +0100 Subject: [PATCH 14/36] Now with new monotonic trait and crate --- Cargo.toml | 1 + macros/src/codegen.rs | 24 +++++++++- macros/src/codegen/init.rs | 2 +- macros/src/codegen/module.rs | 16 ++++--- macros/src/codegen/post_init.rs | 18 ++++--- macros/src/codegen/pre_init.rs | 20 ++++++-- macros/src/codegen/software_tasks.rs | 2 +- macros/src/codegen/timer_queue.rs | 21 +++++++-- macros/src/codegen/util.rs | 10 ++++ src/export.rs | 4 +- src/lib.rs | 6 +-- src/tq.rs | 70 ++++++++++++++++------------ 12 files changed, 135 insertions(+), 59 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2063135079..3729038775 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,7 @@ required-features = ["__v7"] cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } rtic-core = { git = "https://github.com/rtic-rs/rtic-core", branch = "new_monotonic" } +rtic-monotonic = { git = "https://github.com/rtic-rs/rtic-monotonic", branch = "master" } #rtic-core = "0.3.1" heapless = "0.5.0" bare-metal = "1.0.0" diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index bb8aa4e751..bdfcd36dd3 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -104,13 +104,35 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { )); } + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; + let monotonic_imports: Vec<_> = app .monotonics .iter() .map(|(_, monotonic)| { let name = &monotonic.ident; let ty = &monotonic.ty; - quote!(pub type #name = #ty;) + let mangled_name = util::mangle_monotonic_type(&name.to_string()); + let ident = util::monotonic_ident(&name.to_string()); + quote! { + #[doc(hidden)] + pub type #mangled_name = #ty; + + pub mod #name { + pub fn now() -> rtic::time::Instant<#app_path::#mangled_name> { + rtic::export::interrupt::free(|_| { + use rtic::Monotonic as _; + use rtic::time::Clock as _; + if let Ok(v) = unsafe{ (&*#app_path::#ident.as_ptr()).try_now() } { + v + } else { + unreachable!("Your monotonic is not infallible!") + } + }) + } + } + } }) .collect(); diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 66c3bc4e69..aa9adcb064 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -69,7 +69,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult { let app_path = quote! {crate::#app_name}; let locals_new = locals_new.iter(); let call_init = Some( - quote!(let (late, monotonics) = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), + quote!(let (late, mut monotonics) = #app_path::#name(#(#locals_new,)* #name::Context::new(core.into()));), ); root_init.push(module::codegen( diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 93fbeaef03..f0f403b21d 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -126,7 +126,7 @@ pub fn codegen( .monotonics .iter() .map(|(_, monotonic)| { - let mono = &monotonic.ident; + let mono = util::mangle_monotonic_type(&monotonic.ident.to_string()); quote! {#app_path::#mono} }) .collect(); @@ -234,6 +234,7 @@ pub fn codegen( let tq = util::tq_ident(&monotonic.ident.to_string()); let t = util::schedule_t_ident(); let m = &monotonic.ident; + let m_mangled = util::mangle_monotonic_type(&monotonic.ident.to_string()); let m_isr = &monotonic.args.binds; let enum_ = util::interrupt_ident(); @@ -242,9 +243,10 @@ pub fn codegen( items.push(quote!(pub use #m::spawn_at;)); } - let (unmask, pend) = if &*m_isr.to_string() == "SysTick" { + let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" { ( - quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()), + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()) + .enable_interrupt()), quote!(cortex_m::peripheral::SCB::set_pendst()), ) } else { @@ -263,16 +265,16 @@ pub fn codegen( #(,#args)* ) -> Result<(), #ty> where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, - D::T: Into<<#app_path::#m as rtic::time::Clock>::T>, + D::T: Into<<#app_path::#m_mangled as rtic::time::Clock>::T>, { - let instant = <#app_path::#m as rtic::Monotonic>::now(); + let instant = #app_path::#m::now(); spawn_at(instant + duration, #(,#untupled)*) } #(#cfgs)* pub fn spawn_at( - instant: rtic::time::Instant<#app_path::#m> + instant: rtic::time::Instant<#app_path::#m_mangled> #(,#args)* ) -> Result<(), #ty> { unsafe { @@ -296,7 +298,7 @@ pub fn codegen( rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( nr, - || #unmask, + || #enable_interrupt, || #pend, )); diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 9268e040f1..b6cf47c3d8 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -1,6 +1,7 @@ -use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::quote; use rtic_syntax::ast::App; +use syn::Index; use crate::{analyze::Analysis, codegen::util}; @@ -25,12 +26,17 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { } } - for (monotonic, _) in app.monotonics.iter() { - stmts.push(quote!(#monotonic::reset();)); - } + for (i, (monotonic, _)) in app.monotonics.iter().enumerate() { + let idx = Index { + index: i as u32, + span: Span::call_site(), + }; + stmts.push(quote!(monotonics.#idx.reset();)); - // Forget the monotonics so they won't be dropped. - stmts.push(quote!(core::mem::forget(monotonics);)); + // Store the monotonic + let name = util::monotonic_ident(&monotonic.to_string()); + stmts.push(quote!(#name.as_mut_ptr().write(monotonics.#idx);)); + } // Enable the interrupts -- this completes the `init`-ialization phase stmts.push(quote!(rtic::export::interrupt::enable();)); diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index e7b1b03bc6..fbfff3b56e 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -77,14 +77,17 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec(()) + .enable_interrupt(); + } )); } else { // NOTE this also checks that the interrupt exists in the `Interrupt` enumeration @@ -101,10 +110,13 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec Vec); + + items.push(quote!( + #[doc = #doc] + static mut #mono: #mono_ty = core::mem::MaybeUninit::uninit(); + )); } // Timer queue handler @@ -100,8 +112,8 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec>(); let bound_interrupt = &monotonic.args.binds; - let enable_isr = if &*bound_interrupt.to_string() == "SysTick" { - quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).enable_interrupt()) + let disable_isr = if &*bound_interrupt.to_string() == "SysTick" { + quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()) } else { quote!(rtic::export::NVIC::mask(#rt_err::#enum_::#bound_interrupt)) }; @@ -111,7 +123,8 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Ident { Ident::new(&format!("TQ_{}", name), Span::call_site()) } +/// Generates an identifier for monotonic timer storage +pub fn monotonic_ident(name: &str) -> Ident { + Ident::new(&format!("MONOTONIC_STORAGE_{}", name), Span::call_site()) +} + +/// Generates an identifier for monotonic timer storage +pub fn mangle_monotonic_type(name: &str) -> Ident { + Ident::new(&format!("MonotonicMangled{}", name), Span::call_site()) +} + /// The name to get better RT flag errors pub fn rt_err_ident() -> Ident { Ident::new( diff --git a/src/export.rs b/src/export.rs index ab5984e83c..91a4a5efba 100644 --- a/src/export.rs +++ b/src/export.rs @@ -16,7 +16,7 @@ pub use cortex_m::{ use heapless::spsc::SingleCore; pub use heapless::{consts, i::Queue as iQueue, spsc::Queue}; pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap}; -pub use rtic_core::monotonic::Monotonic; +pub use rtic_monotonic as monotonic; pub type SCFQ = Queue; pub type SCRQ = Queue<(T, u8), N, u8, SingleCore>; @@ -116,7 +116,7 @@ where #[inline(always)] pub fn assert_monotonic() where - T: Monotonic, + T: monotonic::Monotonic, { } diff --git a/src/lib.rs b/src/lib.rs index 1d4df65115..16f2e9fac1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,10 +37,8 @@ use cortex_m::{interrupt::InterruptNumber, peripheral::NVIC}; pub use cortex_m_rtic_macros::app; -pub use rtic_core::{ - monotonic::{self, embedded_time as time, Monotonic}, - prelude as mutex_prelude, Exclusive, Mutex, -}; +pub use rtic_core::{prelude as mutex_prelude, Exclusive, Mutex}; +pub use rtic_monotonic::{self, embedded_time as time, Monotonic}; #[doc(hidden)] pub mod export; diff --git a/src/tq.rs b/src/tq.rs index 4c89a66c46..6697f100b2 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -1,4 +1,7 @@ -use crate::{time::Instant, Monotonic}; +use crate::{ + time::{Clock, Instant}, + Monotonic, +}; use core::cmp::Ordering; use heapless::{binary_heap::Min, ArrayLength, BinaryHeap}; @@ -42,7 +45,7 @@ where }) .unwrap_or(true); if if_heap_max_greater_than_nr { - if is_empty { + if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE && is_empty { // mem::transmute::<_, SYST>(()).enable_interrupt(); enable_interrupt(); } @@ -61,44 +64,53 @@ where self.0.is_empty() } + #[inline] + fn unwrapper(val: Result) -> T { + if let Ok(v) = val { + v + } else { + unreachable!("Your monotonic is not infallible") + } + } + /// Dequeue a task from the TimerQueue #[inline] - pub fn dequeue(&mut self, disable_interrupt: F) -> Option<(Task, u8)> + pub fn dequeue(&mut self, disable_interrupt: F, mono: &mut Mono) -> Option<(Task, u8)> where F: FnOnce(), { - unsafe { - Mono::clear_compare(); + mono.clear_compare_flag(); - if let Some(instant) = self.0.peek().map(|p| p.instant) { - if instant < Mono::now() { - // task became ready - let nr = self.0.pop_unchecked(); + if let Some(instant) = self.0.peek().map(|p| p.instant) { + if instant < Self::unwrapper(Clock::try_now(mono)) { + // task became ready + let nr = unsafe { self.0.pop_unchecked() }; + + Some((nr.task, nr.index)) + } else { + // TODO: Fix this hack... + // Extract the compare time. + mono.set_compare(*instant.duration_since_epoch().integer()); + + // Double check that the instant we set is really in the future, else + // dequeue. If the monotonic is fast enough it can happen that from the + // read of now to the set of the compare, the time can overflow. This is to + // guard against this. + if instant < Self::unwrapper(Clock::try_now(mono)) { + let nr = unsafe { self.0.pop_unchecked() }; Some((nr.task, nr.index)) } else { - // TODO: Fix this hack... - // Extract the compare time. - Mono::set_compare(*instant.duration_since_epoch().integer()); - - // Double check that the instant we set is really in the future, else - // dequeue. If the monotonic is fast enough it can happen that from the - // read of now to the set of the compare, the time can overflow. This is to - // guard against this. - if instant < Mono::now() { - let nr = self.0.pop_unchecked(); - - Some((nr.task, nr.index)) - } else { - None - } + None } - } else { - // The queue is empty, disable the interrupt. - disable_interrupt(); - - None } + } else { + // The queue is empty, disable the interrupt. + if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { + disable_interrupt(); + } + + None } } } From d02f9a02411de1bc79490c86541e95879b7b19b8 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 20 Feb 2021 18:32:05 +0100 Subject: [PATCH 15/36] Fixing warnings --- macros/src/codegen.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index bdfcd36dd3..f75a8f2d20 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -107,7 +107,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let app_name = &app.name; let app_path = quote! {crate::#app_name}; - let monotonic_imports: Vec<_> = app + let monotonic_parts: Vec<_> = app .monotonics .iter() .map(|(_, monotonic)| { @@ -116,9 +116,12 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let mangled_name = util::mangle_monotonic_type(&name.to_string()); let ident = util::monotonic_ident(&name.to_string()); quote! { + pub use rtic::Monotonic as _; + #[doc(hidden)] pub type #mangled_name = #ty; + #[allow(non_snake_case)] pub mod #name { pub fn now() -> rtic::time::Instant<#app_path::#mangled_name> { rtic::export::interrupt::free(|_| { @@ -144,7 +147,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { /// Always include the device crate which contains the vector table use #device as #rt_err; - #(#monotonic_imports)* + #(#monotonic_parts)* #(#user_imports)* From 555f36857ec93bed26ff4249593992f500b7c4ab Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 20 Feb 2021 19:22:45 +0100 Subject: [PATCH 16/36] Test fixes --- Cargo.toml | 4 --- examples/baseline.rs | 50 ------------------------------ examples/big-struct-opt.rs | 13 +++++--- examples/binds.rs | 4 +-- examples/capacity.rs | 4 +-- examples/cfg-whole-task.rs | 4 +-- examples/cfg.rs | 4 +-- examples/destructure.rs | 4 +-- examples/double_schedule.rs | 13 ++------ examples/extern_binds.rs | 4 +-- examples/extern_spawn.rs | 4 +-- examples/generics.rs | 4 +-- examples/hardware.rs | 4 +-- examples/idle.rs | 4 +-- examples/init.rs | 4 +-- examples/late.rs | 4 +-- examples/lock.rs | 4 +-- examples/message.rs | 4 +-- examples/multilock.rs | 4 +-- examples/not-sync.rs | 4 +-- examples/only-shared-access.rs | 4 +-- examples/periodic.rs | 6 ++-- examples/peripherals-taken.rs | 4 +-- examples/pool.rs | 4 +-- examples/preempt.rs | 4 +-- examples/ramfunc.rs | 4 +-- examples/resource-user-struct.rs | 4 +-- examples/resource.rs | 4 +-- examples/schedule.rs | 6 ++-- examples/spawn.rs | 4 +-- examples/spawn2.rs | 4 +-- examples/static.rs | 4 +-- examples/t-binds.rs | 4 +-- examples/t-cfg-resources.rs | 17 +++++----- examples/t-cfg.rs | 6 ++-- examples/t-htask-main.rs | 4 +-- examples/t-idle-main.rs | 4 +-- examples/t-init-main.rs | 4 +-- examples/t-late-not-send.rs | 11 ++++--- examples/t-resource.rs | 4 +-- examples/t-schedule-core-stable.rs | 8 ++--- examples/t-schedule.rs | 6 ++-- examples/t-spawn.rs | 4 +-- examples/t-stask-main.rs | 4 +-- examples/task-local-minimal.rs | 4 +-- examples/task-local.rs | 4 +-- examples/task.rs | 4 +-- examples/task_named_main.rs | 4 +-- examples/test_new_monotonic.rs | 25 --------------- examples/types.rs | 7 ++--- 50 files changed, 121 insertions(+), 199 deletions(-) delete mode 100644 examples/baseline.rs delete mode 100644 examples/test_new_monotonic.rs diff --git a/Cargo.toml b/Cargo.toml index 3729038775..550141f67c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,6 @@ version = "0.6.0-alpha.0" [lib] name = "rtic" -[[example]] -name = "baseline" -required-features = ["__v7"] - [[example]] name = "periodic" required-features = ["__v7"] diff --git a/examples/baseline.rs b/examples/baseline.rs deleted file mode 100644 index 17278748d5..0000000000 --- a/examples/baseline.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! examples/baseline.rs - -#![deny(unsafe_code)] -#![deny(warnings)] -#![no_main] -#![no_std] - -use panic_semihosting as _; - -// NOTE: does NOT properly work on QEMU -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] -mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; - - #[init] - fn init(cx: init::Context) -> init::LateResources { - // omitted: initialization of `CYCCNT` - - hprintln!("init(baseline = {:?})", cx.start).unwrap(); - - // `foo` inherits the baseline of `init`: `Instant(0)` - foo::spawn().unwrap(); - - init::LateResources {} - } - - #[task] - fn foo(cx: foo::Context) { - static mut ONCE: bool = true; - - hprintln!("foo(baseline = {:?})", cx.scheduled).unwrap(); - - if *ONCE { - *ONCE = false; - - rtic::pend(Interrupt::UART0); - } else { - debug::exit(debug::EXIT_SUCCESS); - } - } - - #[task(binds = UART0)] - fn uart0(cx: uart0::Context) { - hprintln!("UART0(baseline = {:?})", cx.start).unwrap(); - - // `foo` inherits the baseline of `UART0`: its `start` time - foo::spawn().unwrap(); - } -} diff --git a/examples/big-struct-opt.rs b/examples/big-struct-opt.rs index 85ec5e6144..dc6e72f78d 100644 --- a/examples/big-struct-opt.rs +++ b/examples/big-struct-opt.rs @@ -31,7 +31,7 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { let big_struct = unsafe { static mut BIG_STRUCT: MaybeUninit = MaybeUninit::uninit(); @@ -40,9 +40,12 @@ mod app { &mut *BIG_STRUCT.as_mut_ptr() }; - init::LateResources { - // assign the reference so we can use the resource - big_struct, - } + ( + init::LateResources { + // assign the reference so we can use the resource + big_struct, + }, + init::Monotonics(), + ) } } diff --git a/examples/binds.rs b/examples/binds.rs index f681aa5724..9cbe299486 100644 --- a/examples/binds.rs +++ b/examples/binds.rs @@ -14,12 +14,12 @@ mod app { use lm3s6965::Interrupt; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); hprintln!("init").unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/capacity.rs b/examples/capacity.rs index b25a758446..06bd921ebc 100644 --- a/examples/capacity.rs +++ b/examples/capacity.rs @@ -13,10 +13,10 @@ mod app { use lm3s6965::Interrupt; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task(binds = UART0)] diff --git a/examples/cfg-whole-task.rs b/examples/cfg-whole-task.rs index b19c280c9b..47c3530e17 100644 --- a/examples/cfg-whole-task.rs +++ b/examples/cfg-whole-task.rs @@ -24,11 +24,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn().unwrap(); foo::spawn().unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/cfg.rs b/examples/cfg.rs index d3f2cea126..43c2593cea 100644 --- a/examples/cfg.rs +++ b/examples/cfg.rs @@ -21,11 +21,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn().unwrap(); foo::spawn().unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/destructure.rs b/examples/destructure.rs index d843978b4f..d085e4bf3f 100644 --- a/examples/destructure.rs +++ b/examples/destructure.rs @@ -24,11 +24,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } // Direct destructure diff --git a/examples/double_schedule.rs b/examples/double_schedule.rs index 32477efe9b..77a8e38e91 100644 --- a/examples/double_schedule.rs +++ b/examples/double_schedule.rs @@ -7,20 +7,13 @@ use panic_semihosting as _; -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] +#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { - use rtic::cyccnt::U32Ext; - - #[resources] - struct Resources { - nothing: (), - } - #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { task1::spawn().ok(); - init::LateResources { nothing: () } + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/extern_binds.rs b/examples/extern_binds.rs index 632f4ca02b..3c8786ddb6 100644 --- a/examples/extern_binds.rs +++ b/examples/extern_binds.rs @@ -20,12 +20,12 @@ mod app { use lm3s6965::Interrupt; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); hprintln!("init").unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/extern_spawn.rs b/examples/extern_spawn.rs index 1be3d51295..275ac53996 100644 --- a/examples/extern_spawn.rs +++ b/examples/extern_spawn.rs @@ -22,10 +22,10 @@ mod app { use crate::foo; #[init] - fn init(_c: init::Context) -> init::LateResources { + fn init(_c: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn(1, 2).unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } extern "Rust" { diff --git a/examples/generics.rs b/examples/generics.rs index f3829a0634..eabfff7ece 100644 --- a/examples/generics.rs +++ b/examples/generics.rs @@ -21,11 +21,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task(binds = UART0, resources = [shared])] diff --git a/examples/hardware.rs b/examples/hardware.rs index 99e8da2ec6..3cf988073f 100644 --- a/examples/hardware.rs +++ b/examples/hardware.rs @@ -13,14 +13,14 @@ mod app { use lm3s6965::Interrupt; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { // Pends the UART0 interrupt but its handler won't run until *after* // `init` returns because interrupts are disabled rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend hprintln!("init").unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/idle.rs b/examples/idle.rs index 1aac56c28f..db03dc708a 100644 --- a/examples/idle.rs +++ b/examples/idle.rs @@ -12,10 +12,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { hprintln!("init").unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/init.rs b/examples/init.rs index ca67a2b783..9de7958147 100644 --- a/examples/init.rs +++ b/examples/init.rs @@ -12,7 +12,7 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(cx: init::Context) -> init::LateResources { + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { static mut X: u32 = 0; // Cortex-M peripherals @@ -32,6 +32,6 @@ mod app { debug::exit(debug::EXIT_SUCCESS); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } } diff --git a/examples/late.rs b/examples/late.rs index d4efaba367..e65b6e6971 100644 --- a/examples/late.rs +++ b/examples/late.rs @@ -25,13 +25,13 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { static mut Q: Queue = Queue(i::Queue::new()); let (p, c) = Q.split(); // Initialization of late resources - init::LateResources { p, c } + (init::LateResources { p, c }, init::Monotonics()) } #[idle(resources = [c])] diff --git a/examples/lock.rs b/examples/lock.rs index 2fbf760833..75d47d24fe 100644 --- a/examples/lock.rs +++ b/examples/lock.rs @@ -19,10 +19,10 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::GPIOA); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } // when omitted priority is assumed to be `1` diff --git a/examples/message.rs b/examples/message.rs index 4c5d8997b0..722e73a710 100644 --- a/examples/message.rs +++ b/examples/message.rs @@ -12,10 +12,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn(/* no message */).unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/multilock.rs b/examples/multilock.rs index a6985dfa0c..ad9d72ab59 100644 --- a/examples/multilock.rs +++ b/examples/multilock.rs @@ -25,10 +25,10 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::GPIOA); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } // when omitted priority is assumed to be `1` diff --git a/examples/not-sync.rs b/examples/not-sync.rs index 21c316ae14..8189da51bf 100644 --- a/examples/not-sync.rs +++ b/examples/not-sync.rs @@ -25,10 +25,10 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { debug::exit(debug::EXIT_SUCCESS); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task(resources = [&shared])] diff --git a/examples/only-shared-access.rs b/examples/only-shared-access.rs index 8d42fd4ddd..2c6ad4c4be 100644 --- a/examples/only-shared-access.rs +++ b/examples/only-shared-access.rs @@ -18,11 +18,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources { key: 0xdeadbeef } + (init::LateResources { key: 0xdeadbeef }, init::Monotonics()) } #[task(binds = UART0, resources = [&key])] diff --git a/examples/periodic.rs b/examples/periodic.rs index 3ff9c907cb..29fa6bd999 100644 --- a/examples/periodic.rs +++ b/examples/periodic.rs @@ -8,7 +8,7 @@ use panic_semihosting as _; // NOTE: does NOT work on QEMU! -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] +#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { use cortex_m_semihosting::hprintln; use rtic::cyccnt::{Instant, U32Ext}; @@ -16,12 +16,12 @@ mod app { const PERIOD: u32 = 8_000_000; #[init] - fn init(cx: init::Context) -> init::LateResources { + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { // omitted: initialization of `CYCCNT` foo::schedule(cx.start + PERIOD.cycles()).unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/peripherals-taken.rs b/examples/peripherals-taken.rs index 98f06b08a2..6b4a282b8f 100644 --- a/examples/peripherals-taken.rs +++ b/examples/peripherals-taken.rs @@ -10,10 +10,10 @@ mod app { use cortex_m_semihosting::debug; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { assert!(cortex_m::Peripherals::take().is_none()); debug::exit(debug::EXIT_SUCCESS); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } } diff --git a/examples/pool.rs b/examples/pool.rs index eaad9c09d6..44405b4911 100644 --- a/examples/pool.rs +++ b/examples/pool.rs @@ -25,7 +25,7 @@ mod app { use super::P; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { static mut MEMORY: [u8; 512] = [0; 512]; // Increase the capacity of the memory pool by ~4 @@ -33,7 +33,7 @@ mod app { rtic::pend(Interrupt::I2C0); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task(binds = I2C0, priority = 2)] diff --git a/examples/preempt.rs b/examples/preempt.rs index ee75c46f18..14b3a0a682 100644 --- a/examples/preempt.rs +++ b/examples/preempt.rs @@ -12,10 +12,10 @@ mod app { use lm3s6965::Interrupt; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::GPIOA); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task(binds = GPIOA, priority = 1)] diff --git a/examples/ramfunc.rs b/examples/ramfunc.rs index b5aa17b949..d9c8143fbc 100644 --- a/examples/ramfunc.rs +++ b/examples/ramfunc.rs @@ -19,10 +19,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn().unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[inline(never)] diff --git a/examples/resource-user-struct.rs b/examples/resource-user-struct.rs index a550bb2a38..6ad540b0f9 100644 --- a/examples/resource-user-struct.rs +++ b/examples/resource-user-struct.rs @@ -27,11 +27,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } // `shared` cannot be accessed from this context diff --git a/examples/resource.rs b/examples/resource.rs index 60aa52b098..c8c57bf57a 100644 --- a/examples/resource.rs +++ b/examples/resource.rs @@ -20,11 +20,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } // `shared` cannot be accessed from this context diff --git a/examples/schedule.rs b/examples/schedule.rs index 5f73c5003f..6f6f8cb60b 100644 --- a/examples/schedule.rs +++ b/examples/schedule.rs @@ -8,14 +8,14 @@ use panic_halt as _; // NOTE: does NOT work on QEMU! -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] +#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { use cortex_m::peripheral::DWT; use cortex_m_semihosting::hprintln; use rtic::cyccnt::{Instant, U32Ext as _}; #[init()] - fn init(mut cx: init::Context) -> init::LateResources { + fn init(mut cx: init::Context) -> (init::LateResources, init::Monotonics) { // Initialize (enable) the monotonic timer (CYCCNT) cx.core.DCB.enable_trace(); // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7) @@ -34,7 +34,7 @@ mod app { // Schedule `bar` to run 4e6 cycles in the future bar::schedule(now + 4_000_000.cycles()).unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/spawn.rs b/examples/spawn.rs index 449fcfb9ae..987ebf7d45 100644 --- a/examples/spawn.rs +++ b/examples/spawn.rs @@ -12,10 +12,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_c: init::Context) -> init::LateResources { + fn init(_c: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn(1, 2).unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task()] diff --git a/examples/spawn2.rs b/examples/spawn2.rs index c485b92278..be113f7966 100644 --- a/examples/spawn2.rs +++ b/examples/spawn2.rs @@ -12,10 +12,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_c: init::Context) -> init::LateResources { + fn init(_c: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn(1, 2).unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/static.rs b/examples/static.rs index 7626c71276..cbbc539962 100644 --- a/examples/static.rs +++ b/examples/static.rs @@ -26,13 +26,13 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { static mut Q: Queue = Queue(i::Queue::new()); let (p, c) = Q.split(); // Initialization of late resources - init::LateResources { p, c } + (init::LateResources { p, c }, init::Monotonics()) } #[idle(resources = [c])] diff --git a/examples/t-binds.rs b/examples/t-binds.rs index 8d52f58a3f..60afa35ebe 100644 --- a/examples/t-binds.rs +++ b/examples/t-binds.rs @@ -10,8 +10,8 @@ use panic_halt as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources {} + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + (init::LateResources {}, init::Monotonics()) } // Cortex-M exception diff --git a/examples/t-cfg-resources.rs b/examples/t-cfg-resources.rs index 61eb4c7b10..990b01ff8e 100644 --- a/examples/t-cfg-resources.rs +++ b/examples/t-cfg-resources.rs @@ -18,13 +18,16 @@ mod app { dummy: (), // dummy such that we have at least one late resource } #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources { - // The feature needs to be applied everywhere x is defined or used - #[cfg(feature = "feature_x")] - x: 0, - dummy: (), // dummy such that we have at least one late resource - } + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + ( + init::LateResources { + // The feature needs to be applied everywhere x is defined or used + #[cfg(feature = "feature_x")] + x: 0, + dummy: (), // dummy such that we have at least one late resource + }, + init::Monotonics(), + ) } #[idle] diff --git a/examples/t-cfg.rs b/examples/t-cfg.rs index 5bcef0af84..ff06ee8eee 100644 --- a/examples/t-cfg.rs +++ b/examples/t-cfg.rs @@ -5,7 +5,7 @@ use panic_halt as _; -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0, QEI0])] +#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] mod app { #[resources] struct Resources { @@ -15,11 +15,11 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { #[cfg(never)] static mut BAR: u32 = 0; - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/t-htask-main.rs b/examples/t-htask-main.rs index 57076eca49..2d480d0bbb 100644 --- a/examples/t-htask-main.rs +++ b/examples/t-htask-main.rs @@ -10,10 +10,10 @@ mod app { use cortex_m_semihosting::debug; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(lm3s6965::Interrupt::UART0); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task(binds = UART0)] diff --git a/examples/t-idle-main.rs b/examples/t-idle-main.rs index 42dac904e2..891896fa8b 100644 --- a/examples/t-idle-main.rs +++ b/examples/t-idle-main.rs @@ -10,8 +10,8 @@ mod app { use cortex_m_semihosting::debug; #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources {} + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/t-init-main.rs b/examples/t-init-main.rs index 0456e874c0..b77a7df8bd 100644 --- a/examples/t-init-main.rs +++ b/examples/t-init-main.rs @@ -10,9 +10,9 @@ mod app { use cortex_m_semihosting::debug; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { debug::exit(debug::EXIT_SUCCESS); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } } diff --git a/examples/t-late-not-send.rs b/examples/t-late-not-send.rs index ce3bcbac68..dae0aa99ec 100644 --- a/examples/t-late-not-send.rs +++ b/examples/t-late-not-send.rs @@ -24,10 +24,13 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources { - x: NotSend { _0: PhantomData }, - } + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + ( + init::LateResources { + x: NotSend { _0: PhantomData }, + }, + init::Monotonics(), + ) } #[idle(resources = [x, y])] diff --git a/examples/t-resource.rs b/examples/t-resource.rs index 0a9f3bad5b..164ea841b9 100644 --- a/examples/t-resource.rs +++ b/examples/t-resource.rs @@ -32,8 +32,8 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources {} + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + (init::LateResources {}, init::Monotonics()) } #[idle(resources = [o2, &o4, s1, &s3])] diff --git a/examples/t-schedule-core-stable.rs b/examples/t-schedule-core-stable.rs index 10539014a7..adcc0b695b 100644 --- a/examples/t-schedule-core-stable.rs +++ b/examples/t-schedule-core-stable.rs @@ -7,13 +7,13 @@ use panic_halt as _; -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] +#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { #[init] - fn init(c: init::Context) -> init::LateResources { - let _c: rtic::Peripherals = c.core; + fn init(c: init::Context) -> (init::LateResources, init::Monotonics) { + let _c: cortex_m::Peripherals = c.core; - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs index 9c94d1b427..1771d4195f 100644 --- a/examples/t-schedule.rs +++ b/examples/t-schedule.rs @@ -7,17 +7,17 @@ use panic_halt as _; -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] +#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { use rtic::cyccnt::{Instant, U32Ext as _}; #[init] - fn init(c: init::Context) -> init::LateResources { + fn init(c: init::Context) -> (init::LateResources, init::Monotonics) { let _: Result<(), ()> = foo::schedule(c.start + 10.cycles()); let _: Result<(), u32> = bar::schedule(c.start + 20.cycles(), 0); let _: Result<(), (u32, u32)> = baz::schedule(c.start + 30.cycles(), 0, 1); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/t-spawn.rs b/examples/t-spawn.rs index c9949ef9b9..cc7754e858 100644 --- a/examples/t-spawn.rs +++ b/examples/t-spawn.rs @@ -10,12 +10,12 @@ use panic_halt as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { let _: Result<(), ()> = foo::spawn(); let _: Result<(), u32> = bar::spawn(0); let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/examples/t-stask-main.rs b/examples/t-stask-main.rs index 034ad7c56e..cfc93425be 100644 --- a/examples/t-stask-main.rs +++ b/examples/t-stask-main.rs @@ -10,10 +10,10 @@ mod app { use cortex_m_semihosting::debug; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { taskmain::spawn().ok(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/task-local-minimal.rs b/examples/task-local-minimal.rs index 6e25c10d68..f83493c29d 100644 --- a/examples/task-local-minimal.rs +++ b/examples/task-local-minimal.rs @@ -18,8 +18,8 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources { l: 42 } + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + (init::LateResources { l: 42 }, init::Monotonics()) } // l is task_local diff --git a/examples/task-local.rs b/examples/task-local.rs index e86197a0cb..3020c3b3af 100644 --- a/examples/task-local.rs +++ b/examples/task-local.rs @@ -38,10 +38,10 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources { e2: 2, l2: 2 } + (init::LateResources { e2: 2, l2: 2 }, init::Monotonics()) } // `shared` cannot be accessed from this context diff --git a/examples/task.rs b/examples/task.rs index 5e4769a59b..9d4492f284 100644 --- a/examples/task.rs +++ b/examples/task.rs @@ -12,10 +12,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { foo::spawn().unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/task_named_main.rs b/examples/task_named_main.rs index c3d21b5806..c2c4e62d91 100644 --- a/examples/task_named_main.rs +++ b/examples/task_named_main.rs @@ -12,10 +12,10 @@ mod app { use cortex_m_semihosting::{debug, hprintln}; #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { main::spawn().unwrap(); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[task] diff --git a/examples/test_new_monotonic.rs b/examples/test_new_monotonic.rs deleted file mode 100644 index 67883465b6..0000000000 --- a/examples/test_new_monotonic.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! examples/test_new_monotonic.rs - -#![no_main] -#![no_std] - -use panic_semihosting as _; // panic handler -use rtic::app; - -#[app(device = lm3s6965, dispatchers = [UART])] -mod app { - #[monotonic(binds = SysTick)] - type MyMono1 = hal::Mono1; - - #[monotonic(binds = SomeISR2, default = true)] - type MyMono2 = hal::Mono2; - - #[init] - fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) {} - - #[task] - fn task1(_: task1::Context) {} - - #[task] - fn task2(_: task2::Context) {} -} diff --git a/examples/types.rs b/examples/types.rs index bcdd30a930..8411eecd9c 100644 --- a/examples/types.rs +++ b/examples/types.rs @@ -7,10 +7,9 @@ use panic_semihosting as _; -#[rtic::app(device = lm3s6965, peripherals = true, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])] +#[rtic::app(device = lm3s6965, peripherals = true, dispatchers = [SSI0])] mod app { use cortex_m_semihosting::debug; - use rtic::cyccnt; #[resources] struct Resources { @@ -19,14 +18,14 @@ mod app { } #[init] - fn init(cx: init::Context) -> init::LateResources { + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { let _: cyccnt::Instant = cx.start; let _: rtic::Peripherals = cx.core; let _: lm3s6965::Peripherals = cx.device; debug::exit(debug::EXIT_SUCCESS); - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] From 1a46345a2aa710c4ec5ea8fb6589424bc4450d0f Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 21 Feb 2021 16:15:34 +0100 Subject: [PATCH 17/36] Fixed UB in generated `Monotonic::now()` --- macros/src/codegen.rs | 19 ++++++++++++++----- macros/src/codegen/post_init.rs | 2 +- macros/src/codegen/timer_queue.rs | 17 +++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index f75a8f2d20..b1e87ca837 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -112,9 +112,12 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { .iter() .map(|(_, monotonic)| { let name = &monotonic.ident; + let name_str = &name.to_string(); let ty = &monotonic.ty; - let mangled_name = util::mangle_monotonic_type(&name.to_string()); - let ident = util::monotonic_ident(&name.to_string()); + let mangled_name = util::mangle_monotonic_type(&name_str); + let ident = util::monotonic_ident(&name_str); + let panic_str = &format!("Use of monotonic '{}' before it was passed to the runtime", name_str); + quote! { pub use rtic::Monotonic as _; @@ -123,14 +126,20 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #[allow(non_snake_case)] pub mod #name { + /// Access the global `Monotonic` implementation, not that this will panic + /// before the this `Monotonic` has been passed to the RTIC runtime. pub fn now() -> rtic::time::Instant<#app_path::#mangled_name> { rtic::export::interrupt::free(|_| { use rtic::Monotonic as _; use rtic::time::Clock as _; - if let Ok(v) = unsafe{ (&*#app_path::#ident.as_ptr()).try_now() } { - v + if let Some(m) = unsafe{ #app_path::#ident.as_ref() } { + if let Ok(v) = m.try_now() { + v + } else { + unreachable!("Your monotonic is not infallible!") + } } else { - unreachable!("Your monotonic is not infallible!") + panic!(#panic_str); } }) } diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index b6cf47c3d8..8ebcb12b19 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -35,7 +35,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { // Store the monotonic let name = util::monotonic_ident(&monotonic.to_string()); - stmts.push(quote!(#name.as_mut_ptr().write(monotonics.#idx);)); + stmts.push(quote!(#name = Some(monotonics.#idx);)); } // Enable the interrupts -- this completes the `init`-ialization phase diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 54b2c1f059..65560680ae 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -69,11 +69,11 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let mono_ty = quote!(Option<#m>); items.push(quote!( #[doc = #doc] - static mut #mono: #mono_ty = core::mem::MaybeUninit::uninit(); + static mut #mono: #mono_ty = None; )); } @@ -122,10 +122,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Sun, 21 Feb 2021 21:57:18 +0100 Subject: [PATCH 18/36] Properly call `on_interrupt` --- macros/src/codegen/timer_queue.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 65560680ae..ea2fee6635 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -136,6 +136,10 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Mon, 22 Feb 2021 20:15:13 +0100 Subject: [PATCH 19/36] Of by 1 --- src/tq.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tq.rs b/src/tq.rs index 6697f100b2..541ffcd13b 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -82,7 +82,7 @@ where mono.clear_compare_flag(); if let Some(instant) = self.0.peek().map(|p| p.instant) { - if instant < Self::unwrapper(Clock::try_now(mono)) { + if instant <= Self::unwrapper(Clock::try_now(mono)) { // task became ready let nr = unsafe { self.0.pop_unchecked() }; @@ -96,7 +96,7 @@ where // dequeue. If the monotonic is fast enough it can happen that from the // read of now to the set of the compare, the time can overflow. This is to // guard against this. - if instant < Self::unwrapper(Clock::try_now(mono)) { + if instant <= Self::unwrapper(Clock::try_now(mono)) { let nr = unsafe { self.0.pop_unchecked() }; Some((nr.task, nr.index)) From 82d051e8e967522af735fff47a1738ce4952f950 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 22 Feb 2021 20:59:03 +0100 Subject: [PATCH 20/36] Added enable/disable timer calls --- macros/src/codegen/module.rs | 21 +++++++++++++++------ src/tq.rs | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index f0f403b21d..76641faed4 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -230,11 +230,13 @@ pub fn codegen( // Schedule caller for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); + let monotonic_name = monotonic.ident.to_string(); let tq = util::tq_ident(&monotonic.ident.to_string()); let t = util::schedule_t_ident(); let m = &monotonic.ident; - let m_mangled = util::mangle_monotonic_type(&monotonic.ident.to_string()); + let m_mangled = util::mangle_monotonic_type(&monotonic_name); + let m_ident = util::monotonic_ident(&monotonic_name); let m_isr = &monotonic.args.binds; let enum_ = util::interrupt_ident(); @@ -296,11 +298,18 @@ pub fn codegen( task: #app_path::#t::#name, }; - rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked( - nr, - || #enable_interrupt, - || #pend, - )); + rtic::export::interrupt::free(|_| + if let Some(mono) = #app_path::#m_ident.as_mut() { + #app_path::#tq.enqueue_unchecked( + nr, + || #enable_interrupt, + || #pend, + mono) + } else { + // We can only use the timer queue if `init` has returned, and it + // writes the `Some(monotonic)` we are accessing here. + core::hint::unreachable_unchecked() + }); Ok(()) } else { diff --git a/src/tq.rs b/src/tq.rs index 541ffcd13b..a637007d28 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -29,6 +29,7 @@ where nr: NotReady, enable_interrupt: F1, pend_handler: F2, + mono: &mut Mono, ) where F1: FnOnce(), F2: FnOnce(), @@ -46,7 +47,8 @@ where .unwrap_or(true); if if_heap_max_greater_than_nr { if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE && is_empty { - // mem::transmute::<_, SYST>(()).enable_interrupt(); + // mem::transmute::<_, SYST>(()).enable_interrupt();A + mono.enable_timer(); enable_interrupt(); } @@ -108,6 +110,7 @@ where // The queue is empty, disable the interrupt. if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { disable_interrupt(); + mono.disable_timer(); } None From 56d99c02bd809dfa96d6c1f102e046533c5c631f Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 22 Feb 2021 20:59:23 +0100 Subject: [PATCH 21/36] Updated to new interface --- src/tq.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tq.rs b/src/tq.rs index a637007d28..063bbd8e4a 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -90,9 +90,8 @@ where Some((nr.task, nr.index)) } else { - // TODO: Fix this hack... - // Extract the compare time. - mono.set_compare(*instant.duration_since_epoch().integer()); + // Set compare + mono.set_compare(&instant); // Double check that the instant we set is really in the future, else // dequeue. If the monotonic is fast enough it can happen that from the From 26870ae12ede1a70ca5685a7c0e0113c6bed58dd Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 22 Feb 2021 21:45:22 +0100 Subject: [PATCH 22/36] Use zero time in init for `spawn_after` to not cause panic --- macros/src/codegen/module.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 76641faed4..b0ac65f3ed 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -269,7 +269,12 @@ pub fn codegen( where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, D::T: Into<<#app_path::#m_mangled as rtic::time::Clock>::T>, { - let instant = #app_path::#m::now(); + + let instant = if rtic::export::interrupt::free(|_| unsafe { #app_path::#m_ident.is_none() }) { + rtic::time::Instant::new(0) + } else { + #app_path::#m::now() + }; spawn_at(instant + duration, #(,#untupled)*) } From 210197d07955e760c031e05d1cc79689290335dc Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 23 Feb 2021 19:29:15 +0100 Subject: [PATCH 23/36] Remove flags, updates UI tests --- Cargo.toml | 37 ------------------------- ui/single/exception-systick-used.rs | 7 ----- ui/single/exception-systick-used.stderr | 5 ---- ui/single/local-cfg-task-local-err.rs | 17 +++++++----- ui/single/local-err.rs | 4 +-- ui/single/locals-cfg.rs | 4 +-- ui/single/resources-cfg.rs | 4 +-- ui/single/task-priority-too-high.rs | 4 +-- 8 files changed, 18 insertions(+), 64 deletions(-) delete mode 100644 ui/single/exception-systick-used.rs delete mode 100644 ui/single/exception-systick-used.stderr diff --git a/Cargo.toml b/Cargo.toml index 550141f67c..98bed66006 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,38 +18,6 @@ version = "0.6.0-alpha.0" [lib] name = "rtic" -[[example]] -name = "periodic" -required-features = ["__v7"] - -[[example]] -name = "pool" -required-features = ["__v7"] - -[[example]] -name = "schedule" -required-features = ["__v7"] - -[[example]] -name = "t-cfg" -required-features = ["__v7"] - -[[example]] -name = "t-cfg-resources" -required-features = ["__min_r1_43"] - -[[example]] -name = "t-schedule" -required-features = ["__v7"] - -[[example]] -name = "types" -required-features = ["__v7"] - -[[example]] -name = "double_schedule" -required-features = ["__v7"] - [dependencies] cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } @@ -74,11 +42,6 @@ version = "0.5.2" [target.x86_64-unknown-linux-gnu.dev-dependencies] trybuild = "1" -[features] -# used for testing this crate; do not use in applications -__v7 =[] -__min_r1_43 =[] - [profile.release] codegen-units = 1 lto = true diff --git a/ui/single/exception-systick-used.rs b/ui/single/exception-systick-used.rs deleted file mode 100644 index 9e94c739ba..0000000000 --- a/ui/single/exception-systick-used.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![no_main] - -#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)] -mod app { - #[task(binds = SysTick)] - fn sys_tick(_: sys_tick::Context) {} -} diff --git a/ui/single/exception-systick-used.stderr b/ui/single/exception-systick-used.stderr deleted file mode 100644 index 23b6dc4a10..0000000000 --- a/ui/single/exception-systick-used.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: this exception can't be used because it's being used by the runtime - --> $DIR/exception-systick-used.rs:6:8 - | -6 | fn sys_tick(_: sys_tick::Context) {} - | ^^^^^^^^ diff --git a/ui/single/local-cfg-task-local-err.rs b/ui/single/local-cfg-task-local-err.rs index 412f614226..d4752edf5d 100644 --- a/ui/single/local-cfg-task-local-err.rs +++ b/ui/single/local-cfg-task-local-err.rs @@ -26,15 +26,18 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources { - #[cfg(feature = "feature_l2")] - l2: 2, - #[cfg(not(feature = "feature_l2"))] - l2: 5, - } + ( + init::LateResources { + #[cfg(feature = "feature_l2")] + l2: 2, + #[cfg(not(feature = "feature_l2"))] + l2: 5, + }, + init::Monotonics(), + ) } // l1 ok (task_local) diff --git a/ui/single/local-err.rs b/ui/single/local-err.rs index 0fe98a4b0c..7ebfc0699a 100644 --- a/ui/single/local-err.rs +++ b/ui/single/local-err.rs @@ -39,10 +39,10 @@ mod app { } #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); - init::LateResources { e2: 2, l2: 2 } + (init::LateResources { e2: 2, l2: 2 }, init::Monotonics()) } // `shared` cannot be accessed from this context diff --git a/ui/single/locals-cfg.rs b/ui/single/locals-cfg.rs index 3bfdaa1e0c..72e2acae53 100644 --- a/ui/single/locals-cfg.rs +++ b/ui/single/locals-cfg.rs @@ -4,13 +4,13 @@ use panic_halt as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { #[init] - fn init(_: init::Context) -> init::LateResources { + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { #[cfg(never)] static mut FOO: u32 = 0; FOO; - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle] diff --git a/ui/single/resources-cfg.rs b/ui/single/resources-cfg.rs index 2ba65a048a..c11d2ba45d 100644 --- a/ui/single/resources-cfg.rs +++ b/ui/single/resources-cfg.rs @@ -43,14 +43,14 @@ mod app { } #[init(resources = [o1, o4, o5, o6, s3])] - fn init(c: init::Context) -> init::LateResources { + fn init(c: init::Context) -> (init::LateResources, init::Monotonics) { c.resources.o1; c.resources.o4; c.resources.o5; c.resources.o6; c.resources.s3; - init::LateResources {} + (init::LateResources {}, init::Monotonics()) } #[idle(resources = [o2, &o4, s1, &s3])] diff --git a/ui/single/task-priority-too-high.rs b/ui/single/task-priority-too-high.rs index caa7b8ee24..b1cbfa94ff 100644 --- a/ui/single/task-priority-too-high.rs +++ b/ui/single/task-priority-too-high.rs @@ -3,8 +3,8 @@ #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) -> init::LateResources { - init::LateResources {} + fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + (init::LateResources {}, init::Monotonics()) } #[task(binds = GPIOA, priority = 1)] From 670cdb92d3a22f1e41c9a69912dbfca885fa5de4 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 23 Feb 2021 19:30:54 +0100 Subject: [PATCH 24/36] Test output fix --- ui/single/local-cfg-task-local-err.stderr | 8 ++++---- ui/single/locals-cfg.stderr | 4 ++-- ui/single/resources-cfg.stderr | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/single/local-cfg-task-local-err.stderr b/ui/single/local-cfg-task-local-err.stderr index 9a84ead413..73dfaeb6ab 100644 --- a/ui/single/local-cfg-task-local-err.stderr +++ b/ui/single/local-cfg-task-local-err.stderr @@ -5,15 +5,15 @@ error: task local resource "l2" is used by multiple tasks | ^^ error: task local resource "l2" is used by task "uart0" with priority 1 - --> $DIR/local-cfg-task-local-err.rs:51:39 + --> $DIR/local-cfg-task-local-err.rs:54:39 | -51 | #[cfg(feature = "feature_l2")]l2, +54 | #[cfg(feature = "feature_l2")]l2, | ^^ error: task local resource "l2" is used by task "uart1" with priority 1 - --> $DIR/local-cfg-task-local-err.rs:60:44 + --> $DIR/local-cfg-task-local-err.rs:63:44 | -60 | #[cfg(not(feature = "feature_l2"))]l2 +63 | #[cfg(not(feature = "feature_l2"))]l2 | ^^ warning: unused import: `cortex_m_semihosting::debug` diff --git a/ui/single/locals-cfg.stderr b/ui/single/locals-cfg.stderr index 47992b3e60..200cea20fe 100644 --- a/ui/single/locals-cfg.stderr +++ b/ui/single/locals-cfg.stderr @@ -31,5 +31,5 @@ error[E0425]: cannot find value `FOO` in this scope error: duplicate lang item in crate `panic_halt` (which `$CRATE` depends on): `panic_impl`. | = note: the lang item is first defined in crate `std` (which `$CRATE` depends on) - = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-e12de7683a34c500.rlib - = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-f6dc7d4a3dd7a21d.rmeta + = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-6f77337c1826707d.rlib + = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-ad4cf7fac73711f1.rmeta diff --git a/ui/single/resources-cfg.stderr b/ui/single/resources-cfg.stderr index 39f2c1aaf6..e367c51904 100644 --- a/ui/single/resources-cfg.stderr +++ b/ui/single/resources-cfg.stderr @@ -1,8 +1,8 @@ error: duplicate lang item in crate `panic_halt` (which `$CRATE` depends on): `panic_impl`. | = note: the lang item is first defined in crate `std` (which `$CRATE` depends on) - = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-e12de7683a34c500.rlib - = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-f6dc7d4a3dd7a21d.rmeta + = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-6f77337c1826707d.rlib + = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-ad4cf7fac73711f1.rmeta error[E0609]: no field `o1` on type `initResources<'_>` --> $DIR/resources-cfg.rs:47:21 From cd3484cbab3c4cd7e483e8de19bcdd9498443412 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 23 Feb 2021 19:35:26 +0100 Subject: [PATCH 25/36] GHA update Fmt fixes Spawn_after did not work with parameters Examples working again Revert "GHA update" This reverts commit e0a71d4859966a6c5cf2629d3cb27e88acada9c0. Readd flags Only add DWT based dep with __v7 flag --- Cargo.toml | 42 +++++++++++++++++++++++++++++ examples/double_schedule.rs | 23 +++++++++++++--- examples/periodic.rs | 28 ++++++++++++-------- examples/schedule.rs | 40 ++++++++++++++-------------- examples/t-schedule.rs | 51 ++++++++++++++++-------------------- examples/types.rs | 20 ++++++++++---- macros/src/codegen.rs | 5 +++- macros/src/codegen/module.rs | 4 +-- 8 files changed, 143 insertions(+), 70 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 98bed66006..2b3528ba76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,38 @@ version = "0.6.0-alpha.0" [lib] name = "rtic" +[[example]] +name = "periodic" +required-features = ["__v7"] + +[[example]] +name = "pool" +required-features = ["__v7"] + +[[example]] +name = "schedule" +required-features = ["__v7"] + +[[example]] +name = "t-cfg" +required-features = ["__v7"] + +[[example]] +name = "t-cfg-resources" +required-features = ["__min_r1_43"] + +[[example]] +name = "t-schedule" +required-features = ["__v7"] + +[[example]] +name = "types" +required-features = ["__v7"] + +[[example]] +name = "double_schedule" +required-features = ["__v7"] + [dependencies] cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } @@ -27,6 +59,11 @@ rtic-monotonic = { git = "https://github.com/rtic-rs/rtic-monotonic", branch = " heapless = "0.5.0" bare-metal = "1.0.0" +[dependencies.dwt-systick-monotonic] +git = "https://github.com/rtic-rs/dwt-systick-monotonic" +branch = "master" +optional = true + [build-dependencies] version_check = "0.9" @@ -42,6 +79,11 @@ version = "0.5.2" [target.x86_64-unknown-linux-gnu.dev-dependencies] trybuild = "1" +[features] +# used for testing this crate; do not use in applications +__v7 = ["dwt-systick-monotonic"] +__min_r1_43 = [] + [profile.release] codegen-units = 1 lto = true diff --git a/examples/double_schedule.rs b/examples/double_schedule.rs index 77a8e38e91..403f35830f 100644 --- a/examples/double_schedule.rs +++ b/examples/double_schedule.rs @@ -9,20 +9,35 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { + use dwt_systick_monotonic::{ + consts::{U0, U8}, + DwtSystick, + }; + use rtic::time::duration::Seconds; + + #[monotonic(binds = SysTick, default = true)] + type MyMono = DwtSystick; // 8 MHz + #[init] - fn init(_: init::Context) -> (init::LateResources, init::Monotonics) { + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { task1::spawn().ok(); - (init::LateResources {}, init::Monotonics()) + let mut dcb = cx.core.DCB; + let dwt = cx.core.DWT; + let systick = cx.core.SYST; + + let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000); + + (init::LateResources {}, init::Monotonics(mono)) } #[task] fn task1(_cx: task1::Context) { - task2::schedule(_cx.scheduled + 100.cycles()).ok(); + task2::spawn_after(Seconds(1_u32)).ok(); } #[task] fn task2(_cx: task2::Context) { - task1::schedule(_cx.scheduled + 100.cycles()).ok(); + task1::spawn_after(Seconds(1_u32)).ok(); } } diff --git a/examples/periodic.rs b/examples/periodic.rs index 29fa6bd999..82c21280e1 100644 --- a/examples/periodic.rs +++ b/examples/periodic.rs @@ -10,25 +10,31 @@ use panic_semihosting as _; // NOTE: does NOT work on QEMU! #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::hprintln; - use rtic::cyccnt::{Instant, U32Ext}; + use dwt_systick_monotonic::{ + consts::{U0, U8}, + DwtSystick, + }; + use rtic::time::duration::Seconds; - const PERIOD: u32 = 8_000_000; + #[monotonic(binds = SysTick, default = true)] + type MyMono = DwtSystick; // 8 MHz #[init] fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { - // omitted: initialization of `CYCCNT` + let mut dcb = cx.core.DCB; + let dwt = cx.core.DWT; + let systick = cx.core.SYST; - foo::schedule(cx.start + PERIOD.cycles()).unwrap(); + let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000); - (init::LateResources {}, init::Monotonics()) + foo::spawn_after(Seconds(1_u32)).unwrap(); + + (init::LateResources {}, init::Monotonics(mono)) } #[task] - fn foo(cx: foo::Context) { - let now = Instant::now(); - hprintln!("foo(scheduled = {:?}, now = {:?})", cx.scheduled, now).unwrap(); - - foo::schedule(cx.scheduled + PERIOD.cycles()).unwrap(); + fn foo(_cx: foo::Context) { + // Periodic + foo::spawn_after(Seconds(1_u32)).unwrap(); } } diff --git a/examples/schedule.rs b/examples/schedule.rs index 6f6f8cb60b..cdbdc0dedd 100644 --- a/examples/schedule.rs +++ b/examples/schedule.rs @@ -10,40 +10,42 @@ use panic_halt as _; // NOTE: does NOT work on QEMU! #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { - use cortex_m::peripheral::DWT; use cortex_m_semihosting::hprintln; - use rtic::cyccnt::{Instant, U32Ext as _}; + use dwt_systick_monotonic::{ + consts::{U0, U8}, + DwtSystick, + }; + use rtic::time::duration::Seconds; + + #[monotonic(binds = SysTick, default = true)] + type MyMono = DwtSystick; // 8 MHz #[init()] - fn init(mut cx: init::Context) -> (init::LateResources, init::Monotonics) { - // Initialize (enable) the monotonic timer (CYCCNT) - cx.core.DCB.enable_trace(); - // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7) - DWT::unlock(); - cx.core.DWT.enable_cycle_counter(); + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { + let mut dcb = cx.core.DCB; + let dwt = cx.core.DWT; + let systick = cx.core.SYST; - // semantically, the monotonic timer is frozen at time "zero" during `init` - // NOTE do *not* call `Instant::now` in this context; it will return a nonsense value - let now = cx.start; // the start time of the system + let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000); - hprintln!("init @ {:?}", now).unwrap(); + hprintln!("init").unwrap(); - // Schedule `foo` to run 8e6 cycles (clock cycles) in the future - foo::schedule(now + 8_000_000.cycles()).unwrap(); + // Schedule `foo` to run 1 second in the future + foo::spawn_after(Seconds(1_u32)).unwrap(); - // Schedule `bar` to run 4e6 cycles in the future - bar::schedule(now + 4_000_000.cycles()).unwrap(); + // Schedule `bar` to run 2 seconds in the future + bar::spawn_after(Seconds(2_u32)).unwrap(); - (init::LateResources {}, init::Monotonics()) + (init::LateResources {}, init::Monotonics(mono)) } #[task] fn foo(_: foo::Context) { - hprintln!("foo @ {:?}", Instant::now()).unwrap(); + hprintln!("foo").unwrap(); } #[task] fn bar(_: bar::Context) { - hprintln!("bar @ {:?}", Instant::now()).unwrap(); + hprintln!("bar").unwrap(); } } diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs index 1771d4195f..259b22655f 100644 --- a/examples/t-schedule.rs +++ b/examples/t-schedule.rs @@ -9,48 +9,43 @@ use panic_halt as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { - use rtic::cyccnt::{Instant, U32Ext as _}; + use dwt_systick_monotonic::{ + consts::{U0, U8}, + DwtSystick, + }; + use rtic::time::duration::Seconds; + + #[monotonic(binds = SysTick, default = true)] + type MyMono = DwtSystick; // 8 MHz #[init] - fn init(c: init::Context) -> (init::LateResources, init::Monotonics) { - let _: Result<(), ()> = foo::schedule(c.start + 10.cycles()); - let _: Result<(), u32> = bar::schedule(c.start + 20.cycles(), 0); - let _: Result<(), (u32, u32)> = baz::schedule(c.start + 30.cycles(), 0, 1); + fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { + let mut dcb = cx.core.DCB; + let dwt = cx.core.DWT; + let systick = cx.core.SYST; - (init::LateResources {}, init::Monotonics()) + let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000); + + let _: Result<(), ()> = foo::spawn_after(Seconds(1_u32)); + let _: Result<(), u32> = bar::spawn_after(Seconds(2_u32), 0); + let _: Result<(), (u32, u32)> = baz::spawn_after(Seconds(3_u32), 0, 1); + + (init::LateResources {}, init::Monotonics(mono)) } #[idle] fn idle(_: idle::Context) -> ! { - let _: Result<(), ()> = foo::schedule(Instant::now() + 40.cycles()); - let _: Result<(), u32> = bar::schedule(Instant::now() + 50.cycles(), 0); - let _: Result<(), (u32, u32)> = baz::schedule(Instant::now() + 60.cycles(), 0, 1); + let _: Result<(), ()> = foo::spawn_at(MyMono::now() + Seconds(3_u32)); + let _: Result<(), u32> = bar::spawn_at(MyMono::now() + Seconds(4_u32), 0); + let _: Result<(), (u32, u32)> = baz::spawn_at(MyMono::now() + Seconds(5_u32), 0, 1); loop { cortex_m::asm::nop(); } } - #[task(binds = SVCall)] - fn svcall(c: svcall::Context) { - let _: Result<(), ()> = foo::schedule(c.start + 70.cycles()); - let _: Result<(), u32> = bar::schedule(c.start + 80.cycles(), 0); - let _: Result<(), (u32, u32)> = baz::schedule(c.start + 90.cycles(), 0, 1); - } - - #[task(binds = UART0)] - fn uart0(c: uart0::Context) { - let _: Result<(), ()> = foo::schedule(c.start + 100.cycles()); - let _: Result<(), u32> = bar::schedule(c.start + 110.cycles(), 0); - let _: Result<(), (u32, u32)> = baz::schedule(c.start + 120.cycles(), 0, 1); - } - #[task] - fn foo(c: foo::Context) { - let _: Result<(), ()> = foo::schedule(c.scheduled + 130.cycles()); - let _: Result<(), u32> = bar::schedule(c.scheduled + 140.cycles(), 0); - let _: Result<(), (u32, u32)> = baz::schedule(c.scheduled + 150.cycles(), 0, 1); - } + fn foo(_: foo::Context) {} #[task] fn bar(_: bar::Context, _x: u32) {} diff --git a/examples/types.rs b/examples/types.rs index 8411eecd9c..ff7deb844d 100644 --- a/examples/types.rs +++ b/examples/types.rs @@ -10,6 +10,13 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965, peripherals = true, dispatchers = [SSI0])] mod app { use cortex_m_semihosting::debug; + use dwt_systick_monotonic::{ + consts::{U0, U8}, + DwtSystick, + }; + + #[monotonic(binds = SysTick, default = true)] + type MyMono = DwtSystick; // 8 MHz #[resources] struct Resources { @@ -19,13 +26,18 @@ mod app { #[init] fn init(cx: init::Context) -> (init::LateResources, init::Monotonics) { - let _: cyccnt::Instant = cx.start; - let _: rtic::Peripherals = cx.core; + let _: cortex_m::Peripherals = cx.core; let _: lm3s6965::Peripherals = cx.device; debug::exit(debug::EXIT_SUCCESS); - (init::LateResources {}, init::Monotonics()) + let mut dcb = cx.core.DCB; + let dwt = cx.core.DWT; + let systick = cx.core.SYST; + + let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000); + + (init::LateResources {}, init::Monotonics(mono)) } #[idle] @@ -37,13 +49,11 @@ mod app { #[task(binds = UART0, resources = [shared])] fn uart0(cx: uart0::Context) { - let _: cyccnt::Instant = cx.start; let _: resources::shared = cx.resources.shared; } #[task(priority = 2, resources = [shared])] fn foo(cx: foo::Context) { - let _: cyccnt::Instant = cx.scheduled; let _: resources::shared = cx.resources.shared; let _: foo::Resources = cx.resources; } diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index b1e87ca837..32e7da0543 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -116,7 +116,10 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let ty = &monotonic.ty; let mangled_name = util::mangle_monotonic_type(&name_str); let ident = util::monotonic_ident(&name_str); - let panic_str = &format!("Use of monotonic '{}' before it was passed to the runtime", name_str); + let panic_str = &format!( + "Use of monotonic '{}' before it was passed to the runtime", + name_str + ); quote! { pub use rtic::Monotonic as _; diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index b0ac65f3ed..e480b86559 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -263,7 +263,7 @@ pub fn codegen( pub mod #m { #(#cfgs)* pub fn spawn_after( - duration: D, + duration: D #(,#args)* ) -> Result<(), #ty> where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, @@ -276,7 +276,7 @@ pub fn codegen( #app_path::#m::now() }; - spawn_at(instant + duration, #(,#untupled)*) + spawn_at(instant + duration #(,#untupled)*) } #(#cfgs)* From 70ea278f86fb9ca30ff496fb6235d171520eeafc Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 23 Feb 2021 21:20:21 +0100 Subject: [PATCH 26/36] No need for new rtic-core --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2b3528ba76..5589aa6e89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,9 +53,9 @@ required-features = ["__v7"] [dependencies] cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } -rtic-core = { git = "https://github.com/rtic-rs/rtic-core", branch = "new_monotonic" } +# rtic-core = { git = "https://github.com/rtic-rs/rtic-core", branch = "new_monotonic" } rtic-monotonic = { git = "https://github.com/rtic-rs/rtic-monotonic", branch = "master" } -#rtic-core = "0.3.1" +rtic-core = "0.3.1" heapless = "0.5.0" bare-metal = "1.0.0" From 767d46e05bbc88eb3c236cf468f9432c7fe0ce05 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 25 Feb 2021 17:32:12 +0100 Subject: [PATCH 27/36] Review fixes --- Cargo.toml | 1 - macros/src/codegen.rs | 3 ++- macros/src/codegen/module.rs | 8 ++------ src/lib.rs | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5589aa6e89..0a9645193f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,6 @@ required-features = ["__v7"] [dependencies] cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } -# rtic-core = { git = "https://github.com/rtic-rs/rtic-core", branch = "new_monotonic" } rtic-monotonic = { git = "https://github.com/rtic-rs/rtic-monotonic", branch = "master" } rtic-core = "0.3.1" heapless = "0.5.0" diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 32e7da0543..7885a4a994 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -127,6 +127,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #[doc(hidden)] pub type #mangled_name = #ty; + /// This module holds the static implementation for `#name::now()` #[allow(non_snake_case)] pub mod #name { /// Access the global `Monotonic` implementation, not that this will panic @@ -154,7 +155,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let rt_err = util::rt_err_ident(); quote!( - /// Implementation details + /// The RTIC application module pub mod #name { /// Always include the device crate which contains the vector table use #device as #rt_err; diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index e480b86559..25260bea32 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -53,13 +53,9 @@ pub fn codegen( Context::Idle => {} - Context::HardwareTask(..) => { - // None for now. - } + Context::HardwareTask(_) => {} - Context::SoftwareTask(..) => { - // None for now. - } + Context::SoftwareTask(_) => {} } if ctxt.has_locals(app) { diff --git a/src/lib.rs b/src/lib.rs index 16f2e9fac1..822073999f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ #![deny(missing_docs)] #![deny(rust_2018_compatibility)] #![deny(rust_2018_idioms)] -// #![deny(warnings)] +#![deny(warnings)] #![no_std] use cortex_m::{interrupt::InterruptNumber, peripheral::NVIC}; From d351f55e1c8e60a9bbd69b40b84a39dab5d20051 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 25 Feb 2021 19:05:39 +0100 Subject: [PATCH 28/36] Documentation generation fixes Test fixes --- macros/src/codegen.rs | 42 +++++++++----------------- macros/src/codegen/dispatchers.rs | 24 +++++++++------ macros/src/codegen/locals.rs | 1 + macros/src/codegen/module.rs | 28 ++++++++++++++--- macros/src/codegen/post_init.rs | 3 +- macros/src/codegen/pre_init.rs | 22 ++++++++------ macros/src/codegen/resources.rs | 3 +- macros/src/codegen/resources_struct.rs | 3 +- macros/src/codegen/software_tasks.rs | 21 +++++++------ macros/src/codegen/timer_queue.rs | 24 +++++++++------ macros/src/codegen/util.rs | 9 ++---- ui/single/resources-cfg.stderr | 30 +++++++++--------- 12 files changed, 114 insertions(+), 96 deletions(-) diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 7885a4a994..c5d956877b 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -57,6 +57,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let main = util::suffixed("main"); mains.push(quote!( + #[doc(hidden)] mod rtic_ext { use super::*; #[no_mangle] @@ -88,22 +89,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; - - // Get the list of all tasks - // Currently unused, might be useful - let task_list = analysis.tasks.clone(); - - let mut tasks = vec![]; - - if !task_list.is_empty() { - tasks.push(quote!( - #[allow(non_camel_case_types)] - pub enum Tasks { - #(#task_list),* - } - )); - } - let app_name = &app.name; let app_path = quote! {crate::#app_name}; @@ -114,25 +99,31 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let name = &monotonic.ident; let name_str = &name.to_string(); let ty = &monotonic.ty; - let mangled_name = util::mangle_monotonic_type(&name_str); let ident = util::monotonic_ident(&name_str); + let ident = util::mark_internal_ident(&ident); let panic_str = &format!( "Use of monotonic '{}' before it was passed to the runtime", name_str ); + let doc = &format!( + "This module holds the static implementation for `{}::now()`", + name_str + ); + let user_imports = &app.user_imports; quote! { pub use rtic::Monotonic as _; - #[doc(hidden)] - pub type #mangled_name = #ty; - - /// This module holds the static implementation for `#name::now()` + #[doc = #doc] #[allow(non_snake_case)] pub mod #name { - /// Access the global `Monotonic` implementation, not that this will panic - /// before the this `Monotonic` has been passed to the RTIC runtime. - pub fn now() -> rtic::time::Instant<#app_path::#mangled_name> { + #( + #[allow(unused_imports)] + #user_imports + )* + + /// Read the current time from this monotonic + pub fn now() -> rtic::time::Instant<#ty> { rtic::export::interrupt::free(|_| { use rtic::Monotonic as _; use rtic::time::Clock as _; @@ -182,9 +173,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #(#root_software_tasks)* - /// Unused - #(#tasks)* - /// app module #(#mod_app)* diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index d3adee0d42..dc33b1af60 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -26,15 +26,16 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec>(); - let doc = format!( - "Software tasks to be dispatched at priority level {}", - level, - ); + // let doc = format!( + // "Software tasks to be dispatched at priority level {}", + // level, + // ); let t = util::spawn_t_ident(level); items.push(quote!( #[allow(non_camel_case_types)] #[derive(Clone, Copy)] - #[doc = #doc] + // #[doc = #doc] + #[doc(hidden)] pub enum #t { #(#variants,)* } @@ -42,6 +43,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec), @@ -51,12 +53,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec Result<(), #ty> { let input = #tupled; @@ -226,13 +231,16 @@ pub fn codegen( // Schedule caller for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); + let instants = util::mark_internal_ident(&instants); let monotonic_name = monotonic.ident.to_string(); let tq = util::tq_ident(&monotonic.ident.to_string()); + let tq = util::mark_internal_ident(&tq); let t = util::schedule_t_ident(); let m = &monotonic.ident; - let m_mangled = util::mangle_monotonic_type(&monotonic_name); + let mono_type = &monotonic.ty; let m_ident = util::monotonic_ident(&monotonic_name); + let m_ident = util::mark_internal_ident(&m_ident); let m_isr = &monotonic.args.binds; let enum_ = util::interrupt_ident(); @@ -255,15 +263,24 @@ pub fn codegen( ) }; + let user_imports = &app.user_imports; + items.push(quote!( + /// Holds methods related to this monotonic pub mod #m { + #( + #[allow(unused_imports)] + #user_imports + )* + #(#cfgs)* + /// Spawns the task after a set duration relative to the current time pub fn spawn_after( duration: D #(,#args)* ) -> Result<(), #ty> where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, - D::T: Into<<#app_path::#m_mangled as rtic::time::Clock>::T>, + D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>, { let instant = if rtic::export::interrupt::free(|_| unsafe { #app_path::#m_ident.is_none() }) { @@ -276,8 +293,9 @@ pub fn codegen( } #(#cfgs)* + /// Spawns the task at a fixed time instant pub fn spawn_at( - instant: rtic::time::Instant<#app_path::#m_mangled> + instant: rtic::time::Instant<#app_path::#mono_type> #(,#args)* ) -> Result<(), #ty> { unsafe { diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 8ebcb12b19..96c5df80f9 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -13,7 +13,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { if !analysis.late_resources.is_empty() { // BTreeSet wrapped in a vector for name in analysis.late_resources.first().unwrap() { - let mangled_name = util::mangle_ident(&name); + let mangled_name = util::mark_internal_ident(&name); // If it's live let cfgs = app.late_resources[name].cfgs.clone(); if analysis.locations.get(name).is_some() { @@ -35,6 +35,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { // Store the monotonic let name = util::monotonic_ident(&monotonic.to_string()); + let name = util::mark_internal_ident(&name); stmts.push(quote!(#name = Some(monotonics.#idx);)); } diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index fbfff3b56e..d5105445dd 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -17,6 +17,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec Vec::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { core::mem::transmute::<_, cortex_m::peripheral::SYST>(()) .enable_interrupt(); } @@ -107,13 +109,13 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec::DISABLE_INTERRUPT_ON_EMPTY_QUEUE { + rtic::export::NVIC::unmask(#app_path::#rt_err::#interrupt::#binds); } )); } diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs index 76871e598a..fa52b86db6 100644 --- a/macros/src/codegen/resources.rs +++ b/macros/src/codegen/resources.rs @@ -21,7 +21,7 @@ pub fn codegen( for (name, res, expr, _) in app.resources(analysis) { let cfgs = &res.cfgs; let ty = &res.ty; - let mangled_name = util::mangle_ident(&name); + let mangled_name = util::mark_internal_ident(&name); { let section = if expr.is_none() { @@ -42,6 +42,7 @@ pub fn codegen( let attrs = &res.attrs; mod_app.push(quote!( #[allow(non_upper_case_globals)] + #[doc(hidden)] #(#attrs)* #(#cfgs)* #section diff --git a/macros/src/codegen/resources_struct.rs b/macros/src/codegen/resources_struct.rs index bffe9431a5..8ed8a2912c 100644 --- a/macros/src/codegen/resources_struct.rs +++ b/macros/src/codegen/resources_struct.rs @@ -31,7 +31,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, None }; let ty = &res.ty; - let mangled_name = util::mangle_ident(&name); + let mangled_name = util::mark_internal_ident(&name); // let ownership = &analysis.ownerships[name]; let r_prop = &res.properties; @@ -112,6 +112,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, let doc = format!("Resources `{}` has access to", ctxt.ident(app)); let ident = util::resources_ident(ctxt, app); + let ident = util::mark_internal_ident(&ident); let item = quote!( #[allow(non_snake_case)] #[doc = #doc] diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index a760b06747..a39fe4cc2e 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -37,6 +37,7 @@ pub fn codegen( // Create free queues and inputs / instants buffers let fq = util::fq_ident(name); + let fq = util::mark_internal_ident(&fq); let (fq_ty, fq_expr, mk_uninit): (_, _, Box Option<_>>) = { ( @@ -48,8 +49,9 @@ pub fn codegen( ) }; mod_app.push(quote!( - /// Queue version of a free-list that keeps track of empty slots in - /// the following buffers + // /// Queue version of a free-list that keeps track of empty slots in + // /// the following buffers + #[doc(hidden)] static mut #fq: #fq_ty = #fq_expr; )); @@ -57,28 +59,29 @@ pub fn codegen( .map(|_| quote!(core::mem::MaybeUninit::uninit())) .collect::>(); - let app_name = &app.name; - let app_path = quote! {crate::#app_name}; - for (_, monotonic) in &app.monotonics { let instants = util::monotonic_instants_ident(name, &monotonic.ident); - let m = util::mangle_monotonic_type(&monotonic.ident.to_string()); + let instants = util::mark_internal_ident(&instants); + let mono_type = &monotonic.ty; let uninit = mk_uninit(); mod_app.push(quote!( #uninit - /// Buffer that holds the instants associated to the inputs of a task + // /// Buffer that holds the instants associated to the inputs of a task + #[doc(hidden)] static mut #instants: - [core::mem::MaybeUninit>; #cap_lit] = + [core::mem::MaybeUninit>; #cap_lit] = [#(#elems,)*]; )); } let uninit = mk_uninit(); let inputs_ident = util::inputs_ident(name); + let inputs_ident = util::mark_internal_ident(&inputs_ident); mod_app.push(quote!( #uninit - /// Buffer that holds the inputs of a task + // /// Buffer that holds the inputs of a task + #[doc(hidden)] static mut #inputs_ident: [core::mem::MaybeUninit<#input_ty>; #cap_lit] = [#(#elems,)*]; )); diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index ea2fee6635..82d0ac981e 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -26,9 +26,10 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec>(); - let doc = "Tasks that can be scheduled".to_string(); + // let doc = "Tasks that can be scheduled".to_string(); items.push(quote!( - #[doc = #doc] + // #[doc = #doc] + #[doc(hidden)] #[allow(non_camel_case_types)] #[derive(Clone, Copy)] enum #t { @@ -41,25 +42,27 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let tq_ty = quote!(rtic::export::TimerQueue<#mono_type, #t, #n>); items.push(quote!( - #[doc = #doc] + #[doc(hidden)] static mut #tq: #tq_ty = rtic::export::TimerQueue( rtic::export::BinaryHeap( rtic::export::iBinaryHeap::new() @@ -68,12 +71,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let mono = util::mark_internal_ident(&mono); + // let doc = &format!("Storage for {}", monotonic_name); items.push(quote!( - #[doc = #doc] - static mut #mono: #mono_ty = None; + #[doc(hidden)] + static mut #mono: Option<#mono_type> = None; )); } @@ -89,6 +92,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec bool { ) } -/// Mangle an ident -pub fn mangle_ident(ident: &Ident) -> Ident { +/// Mark an ident as internal +pub fn mark_internal_ident(ident: &Ident) -> Ident { Ident::new( &format!("__rtic_internal_{}", ident.to_string()), Span::call_site(), @@ -244,11 +244,6 @@ pub fn monotonic_ident(name: &str) -> Ident { Ident::new(&format!("MONOTONIC_STORAGE_{}", name), Span::call_site()) } -/// Generates an identifier for monotonic timer storage -pub fn mangle_monotonic_type(name: &str) -> Ident { - Ident::new(&format!("MonotonicMangled{}", name), Span::call_site()) -} - /// The name to get better RT flag errors pub fn rt_err_ident() -> Ident { Ident::new( diff --git a/ui/single/resources-cfg.stderr b/ui/single/resources-cfg.stderr index e367c51904..3bbbd2d9a8 100644 --- a/ui/single/resources-cfg.stderr +++ b/ui/single/resources-cfg.stderr @@ -4,7 +4,7 @@ error: duplicate lang item in crate `panic_halt` (which `$CRATE` depends on): `p = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-6f77337c1826707d.rlib = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-ad4cf7fac73711f1.rmeta -error[E0609]: no field `o1` on type `initResources<'_>` +error[E0609]: no field `o1` on type `__rtic_internal_initResources<'_>` --> $DIR/resources-cfg.rs:47:21 | 47 | c.resources.o1; @@ -12,7 +12,7 @@ error[E0609]: no field `o1` on type `initResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o4` on type `initResources<'_>` +error[E0609]: no field `o4` on type `__rtic_internal_initResources<'_>` --> $DIR/resources-cfg.rs:48:21 | 48 | c.resources.o4; @@ -20,7 +20,7 @@ error[E0609]: no field `o4` on type `initResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o5` on type `initResources<'_>` +error[E0609]: no field `o5` on type `__rtic_internal_initResources<'_>` --> $DIR/resources-cfg.rs:49:21 | 49 | c.resources.o5; @@ -28,7 +28,7 @@ error[E0609]: no field `o5` on type `initResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o6` on type `initResources<'_>` +error[E0609]: no field `o6` on type `__rtic_internal_initResources<'_>` --> $DIR/resources-cfg.rs:50:21 | 50 | c.resources.o6; @@ -36,7 +36,7 @@ error[E0609]: no field `o6` on type `initResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s3` on type `initResources<'_>` +error[E0609]: no field `s3` on type `__rtic_internal_initResources<'_>` --> $DIR/resources-cfg.rs:51:21 | 51 | c.resources.s3; @@ -44,7 +44,7 @@ error[E0609]: no field `s3` on type `initResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o2` on type `idleResources<'_>` +error[E0609]: no field `o2` on type `__rtic_internal_idleResources<'_>` --> $DIR/resources-cfg.rs:58:21 | 58 | c.resources.o2; @@ -52,7 +52,7 @@ error[E0609]: no field `o2` on type `idleResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o4` on type `idleResources<'_>` +error[E0609]: no field `o4` on type `__rtic_internal_idleResources<'_>` --> $DIR/resources-cfg.rs:59:21 | 59 | c.resources.o4; @@ -60,7 +60,7 @@ error[E0609]: no field `o4` on type `idleResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s1` on type `idleResources<'_>` +error[E0609]: no field `s1` on type `__rtic_internal_idleResources<'_>` --> $DIR/resources-cfg.rs:60:21 | 60 | c.resources.s1; @@ -68,7 +68,7 @@ error[E0609]: no field `s1` on type `idleResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s3` on type `idleResources<'_>` +error[E0609]: no field `s3` on type `__rtic_internal_idleResources<'_>` --> $DIR/resources-cfg.rs:61:21 | 61 | c.resources.s3; @@ -76,7 +76,7 @@ error[E0609]: no field `s3` on type `idleResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o3` on type `uart0Resources<'_>` +error[E0609]: no field `o3` on type `__rtic_internal_uart0Resources<'_>` --> $DIR/resources-cfg.rs:68:21 | 68 | c.resources.o3; @@ -84,7 +84,7 @@ error[E0609]: no field `o3` on type `uart0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s1` on type `uart0Resources<'_>` +error[E0609]: no field `s1` on type `__rtic_internal_uart0Resources<'_>` --> $DIR/resources-cfg.rs:69:21 | 69 | c.resources.s1; @@ -92,7 +92,7 @@ error[E0609]: no field `s1` on type `uart0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s2` on type `uart0Resources<'_>` +error[E0609]: no field `s2` on type `__rtic_internal_uart0Resources<'_>` --> $DIR/resources-cfg.rs:70:21 | 70 | c.resources.s2; @@ -100,7 +100,7 @@ error[E0609]: no field `s2` on type `uart0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s3` on type `uart0Resources<'_>` +error[E0609]: no field `s3` on type `__rtic_internal_uart0Resources<'_>` --> $DIR/resources-cfg.rs:71:21 | 71 | c.resources.s3; @@ -108,7 +108,7 @@ error[E0609]: no field `s3` on type `uart0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `s2` on type `uart1Resources<'_>` +error[E0609]: no field `s2` on type `__rtic_internal_uart1Resources<'_>` --> $DIR/resources-cfg.rs:76:21 | 76 | c.resources.s2; @@ -116,7 +116,7 @@ error[E0609]: no field `s2` on type `uart1Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `o5` on type `uart1Resources<'_>` +error[E0609]: no field `o5` on type `__rtic_internal_uart1Resources<'_>` --> $DIR/resources-cfg.rs:77:21 | 77 | c.resources.o5; From 3a64a3e276aebfd65cadf418eea76b2cf55eef06 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 2 Mar 2021 16:30:59 +0100 Subject: [PATCH 29/36] Bump heapless --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 0a9645193f..12b25c432e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } rtic-monotonic = { git = "https://github.com/rtic-rs/rtic-monotonic", branch = "master" } rtic-core = "0.3.1" -heapless = "0.5.0" +heapless = "0.6.1" bare-metal = "1.0.0" [dependencies.dwt-systick-monotonic] From 08a37d6d3d7e7f599c7d5b2723ed15d8355963d1 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Tue, 2 Mar 2021 19:31:47 +0100 Subject: [PATCH 30/36] Updated `spawn_after` docs --- macros/src/codegen/module.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 41f5b22a77..75435b549e 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -275,6 +275,9 @@ pub fn codegen( #(#cfgs)* /// Spawns the task after a set duration relative to the current time + /// + /// 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( duration: D #(,#args)* From 612efaf0c436489e1cf09c2e87b329a7318f71b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 3 Mar 2021 08:53:03 +0100 Subject: [PATCH 31/36] Use panic_semihosting for all examples --- Cargo.toml | 1 - examples/big-struct-opt.rs | 2 +- examples/not-sync.rs | 2 +- examples/schedule.rs | 2 +- examples/t-binds.rs | 2 +- examples/t-cfg-resources.rs | 2 +- examples/t-cfg.rs | 2 +- examples/t-late-not-send.rs | 2 +- examples/t-resource.rs | 2 +- examples/t-schedule-core-stable.rs | 2 +- examples/t-schedule.rs | 2 +- examples/t-spawn.rs | 2 +- 12 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 12b25c432e..dd4633b148 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,6 @@ version_check = "0.9" [dev-dependencies] lm3s6965 = "0.1.3" -panic-halt = "0.2.0" cortex-m-semihosting = "0.3.3" [dev-dependencies.panic-semihosting] diff --git a/examples/big-struct-opt.rs b/examples/big-struct-opt.rs index dc6e72f78d..e6a5c17247 100644 --- a/examples/big-struct-opt.rs +++ b/examples/big-struct-opt.rs @@ -6,7 +6,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; /// Some big struct pub struct BigStruct { diff --git a/examples/not-sync.rs b/examples/not-sync.rs index 8189da51bf..f01d40432a 100644 --- a/examples/not-sync.rs +++ b/examples/not-sync.rs @@ -6,7 +6,7 @@ #![no_std] use core::marker::PhantomData; -use panic_halt as _; +use panic_semihosting as _; pub struct NotSync { _0: PhantomData<*const ()>, diff --git a/examples/schedule.rs b/examples/schedule.rs index cdbdc0dedd..d6d4499877 100644 --- a/examples/schedule.rs +++ b/examples/schedule.rs @@ -5,7 +5,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; // NOTE: does NOT work on QEMU! #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] diff --git a/examples/t-binds.rs b/examples/t-binds.rs index 60afa35ebe..fbc89e88af 100644 --- a/examples/t-binds.rs +++ b/examples/t-binds.rs @@ -5,7 +5,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { diff --git a/examples/t-cfg-resources.rs b/examples/t-cfg-resources.rs index 990b01ff8e..1adcb9054e 100644 --- a/examples/t-cfg-resources.rs +++ b/examples/t-cfg-resources.rs @@ -3,7 +3,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { diff --git a/examples/t-cfg.rs b/examples/t-cfg.rs index ff06ee8eee..ef591c4d3e 100644 --- a/examples/t-cfg.rs +++ b/examples/t-cfg.rs @@ -3,7 +3,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] mod app { diff --git a/examples/t-late-not-send.rs b/examples/t-late-not-send.rs index dae0aa99ec..579f843675 100644 --- a/examples/t-late-not-send.rs +++ b/examples/t-late-not-send.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; -use panic_halt as _; +use panic_semihosting as _; pub struct NotSend { _0: PhantomData<*const ()>, diff --git a/examples/t-resource.rs b/examples/t-resource.rs index 164ea841b9..6e83069d7b 100644 --- a/examples/t-resource.rs +++ b/examples/t-resource.rs @@ -5,7 +5,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { diff --git a/examples/t-schedule-core-stable.rs b/examples/t-schedule-core-stable.rs index adcc0b695b..98d42ce721 100644 --- a/examples/t-schedule-core-stable.rs +++ b/examples/t-schedule-core-stable.rs @@ -5,7 +5,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs index 259b22655f..bd0ab668b3 100644 --- a/examples/t-schedule.rs +++ b/examples/t-schedule.rs @@ -5,7 +5,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { diff --git a/examples/t-spawn.rs b/examples/t-spawn.rs index cc7754e858..ca5c61b2e3 100644 --- a/examples/t-spawn.rs +++ b/examples/t-spawn.rs @@ -5,7 +5,7 @@ #![no_main] #![no_std] -use panic_halt as _; +use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { From a5795a8f45f73099d88817fc8eb6c265689b862e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 3 Mar 2021 08:55:19 +0100 Subject: [PATCH 32/36] Remove keyword single for all tests --- tests/{single.rs => tests.rs} | 0 ui/{single => }/exception-invalid.rs | 0 ui/{single => }/exception-invalid.stderr | 0 ui/{single => }/extern-interrupt-not-enough.rs | 0 ui/{single => }/extern-interrupt-not-enough.stderr | 0 ui/{single => }/extern-interrupt-used.rs | 0 ui/{single => }/extern-interrupt-used.stderr | 0 ui/{single => }/local-cfg-task-local-err.rs | 0 ui/{single => }/local-cfg-task-local-err.stderr | 0 ui/{single => }/local-err.rs | 0 ui/{single => }/local-err.stderr | 0 ui/{single => }/locals-cfg.rs | 0 ui/{single => }/locals-cfg.stderr | 0 ui/{single => }/resources-cfg.rs | 0 ui/{single => }/resources-cfg.stderr | 0 ui/{single => }/task-priority-too-high.rs | 0 ui/{single => }/task-priority-too-high.stderr | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename tests/{single.rs => tests.rs} (100%) rename ui/{single => }/exception-invalid.rs (100%) rename ui/{single => }/exception-invalid.stderr (100%) rename ui/{single => }/extern-interrupt-not-enough.rs (100%) rename ui/{single => }/extern-interrupt-not-enough.stderr (100%) rename ui/{single => }/extern-interrupt-used.rs (100%) rename ui/{single => }/extern-interrupt-used.stderr (100%) rename ui/{single => }/local-cfg-task-local-err.rs (100%) rename ui/{single => }/local-cfg-task-local-err.stderr (100%) rename ui/{single => }/local-err.rs (100%) rename ui/{single => }/local-err.stderr (100%) rename ui/{single => }/locals-cfg.rs (100%) rename ui/{single => }/locals-cfg.stderr (100%) rename ui/{single => }/resources-cfg.rs (100%) rename ui/{single => }/resources-cfg.stderr (100%) rename ui/{single => }/task-priority-too-high.rs (100%) rename ui/{single => }/task-priority-too-high.stderr (100%) diff --git a/tests/single.rs b/tests/tests.rs similarity index 100% rename from tests/single.rs rename to tests/tests.rs diff --git a/ui/single/exception-invalid.rs b/ui/exception-invalid.rs similarity index 100% rename from ui/single/exception-invalid.rs rename to ui/exception-invalid.rs diff --git a/ui/single/exception-invalid.stderr b/ui/exception-invalid.stderr similarity index 100% rename from ui/single/exception-invalid.stderr rename to ui/exception-invalid.stderr diff --git a/ui/single/extern-interrupt-not-enough.rs b/ui/extern-interrupt-not-enough.rs similarity index 100% rename from ui/single/extern-interrupt-not-enough.rs rename to ui/extern-interrupt-not-enough.rs diff --git a/ui/single/extern-interrupt-not-enough.stderr b/ui/extern-interrupt-not-enough.stderr similarity index 100% rename from ui/single/extern-interrupt-not-enough.stderr rename to ui/extern-interrupt-not-enough.stderr diff --git a/ui/single/extern-interrupt-used.rs b/ui/extern-interrupt-used.rs similarity index 100% rename from ui/single/extern-interrupt-used.rs rename to ui/extern-interrupt-used.rs diff --git a/ui/single/extern-interrupt-used.stderr b/ui/extern-interrupt-used.stderr similarity index 100% rename from ui/single/extern-interrupt-used.stderr rename to ui/extern-interrupt-used.stderr diff --git a/ui/single/local-cfg-task-local-err.rs b/ui/local-cfg-task-local-err.rs similarity index 100% rename from ui/single/local-cfg-task-local-err.rs rename to ui/local-cfg-task-local-err.rs diff --git a/ui/single/local-cfg-task-local-err.stderr b/ui/local-cfg-task-local-err.stderr similarity index 100% rename from ui/single/local-cfg-task-local-err.stderr rename to ui/local-cfg-task-local-err.stderr diff --git a/ui/single/local-err.rs b/ui/local-err.rs similarity index 100% rename from ui/single/local-err.rs rename to ui/local-err.rs diff --git a/ui/single/local-err.stderr b/ui/local-err.stderr similarity index 100% rename from ui/single/local-err.stderr rename to ui/local-err.stderr diff --git a/ui/single/locals-cfg.rs b/ui/locals-cfg.rs similarity index 100% rename from ui/single/locals-cfg.rs rename to ui/locals-cfg.rs diff --git a/ui/single/locals-cfg.stderr b/ui/locals-cfg.stderr similarity index 100% rename from ui/single/locals-cfg.stderr rename to ui/locals-cfg.stderr diff --git a/ui/single/resources-cfg.rs b/ui/resources-cfg.rs similarity index 100% rename from ui/single/resources-cfg.rs rename to ui/resources-cfg.rs diff --git a/ui/single/resources-cfg.stderr b/ui/resources-cfg.stderr similarity index 100% rename from ui/single/resources-cfg.stderr rename to ui/resources-cfg.stderr diff --git a/ui/single/task-priority-too-high.rs b/ui/task-priority-too-high.rs similarity index 100% rename from ui/single/task-priority-too-high.rs rename to ui/task-priority-too-high.rs diff --git a/ui/single/task-priority-too-high.stderr b/ui/task-priority-too-high.stderr similarity index 100% rename from ui/single/task-priority-too-high.stderr rename to ui/task-priority-too-high.stderr From 48613f568b31a29e5c615b9ee59432c177d67b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Thu, 21 Jan 2021 10:17:33 +0100 Subject: [PATCH 33/36] Update the tests file to find the tests --- tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.rs b/tests/tests.rs index b5d480c7ae..9fb88a1bba 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -3,5 +3,5 @@ use trybuild::TestCases; #[test] fn ui() { let t = TestCases::new(); - t.compile_fail("ui/single/*.rs"); + t.compile_fail("ui/*.rs"); } From 8ec505c495197fbd5ca216cf1431bda0dd7c1f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Tue, 2 Mar 2021 23:45:22 +0100 Subject: [PATCH 34/36] Update the GHA job to run the tests test --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d9be52008e..e5f9943400 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -474,7 +474,7 @@ jobs: with: use-cross: false command: test - args: --test single --features __v7 + args: --test tests --features __v7 # Run test suite for thumbv6m testv6: @@ -515,7 +515,7 @@ jobs: with: use-cross: false command: test - args: --test single + args: --test tests # Build documentation, check links docs: From 5e5fbf0ee9b254ec7d61f3f820168f11cb6a2c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 3 Mar 2021 09:11:24 +0100 Subject: [PATCH 35/36] Fix the UI tests, remove panic_halt --- ui/locals-cfg.rs | 3 +- ui/locals-cfg.stderr | 26 +++++++--------- ui/resources-cfg.rs | 3 +- ui/resources-cfg.stderr | 66 +++++++++++++++++++---------------------- 4 files changed, 44 insertions(+), 54 deletions(-) diff --git a/ui/locals-cfg.rs b/ui/locals-cfg.rs index 72e2acae53..170d302610 100644 --- a/ui/locals-cfg.rs +++ b/ui/locals-cfg.rs @@ -1,5 +1,6 @@ #![no_main] -use panic_halt as _; + +use panic_semihosting as _; #[rtic::app(device = lm3s6965, dispatchers = [SSI0])] mod app { diff --git a/ui/locals-cfg.stderr b/ui/locals-cfg.stderr index 200cea20fe..33a80754e3 100644 --- a/ui/locals-cfg.stderr +++ b/ui/locals-cfg.stderr @@ -1,35 +1,29 @@ error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:11:9 + --> $DIR/locals-cfg.rs:12:9 | -11 | FOO; +12 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:21:9 + --> $DIR/locals-cfg.rs:22:9 | -21 | FOO; +22 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:31:9 + --> $DIR/locals-cfg.rs:32:9 | -31 | FOO; +32 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:39:9 + --> $DIR/locals-cfg.rs:40:9 | -39 | FOO; +40 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:47:9 + --> $DIR/locals-cfg.rs:48:9 | -47 | FOO; +48 | FOO; | ^^^ not found in this scope - -error: duplicate lang item in crate `panic_halt` (which `$CRATE` depends on): `panic_impl`. - | - = note: the lang item is first defined in crate `std` (which `$CRATE` depends on) - = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-6f77337c1826707d.rlib - = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-ad4cf7fac73711f1.rmeta diff --git a/ui/resources-cfg.rs b/ui/resources-cfg.rs index c11d2ba45d..c802a46f3b 100644 --- a/ui/resources-cfg.rs +++ b/ui/resources-cfg.rs @@ -1,5 +1,6 @@ #![no_main] -use panic_halt as _; + +use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { diff --git a/ui/resources-cfg.stderr b/ui/resources-cfg.stderr index 3bbbd2d9a8..03612de030 100644 --- a/ui/resources-cfg.stderr +++ b/ui/resources-cfg.stderr @@ -1,125 +1,119 @@ -error: duplicate lang item in crate `panic_halt` (which `$CRATE` depends on): `panic_impl`. - | - = note: the lang item is first defined in crate `std` (which `$CRATE` depends on) - = note: first definition in `std` loaded from /usr/share/rust/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-6f77337c1826707d.rlib - = note: second definition in `panic_halt` loaded from $DIR/target/tests/target/x86_64-unknown-linux-gnu/debug/deps/libpanic_halt-ad4cf7fac73711f1.rmeta - error[E0609]: no field `o1` on type `__rtic_internal_initResources<'_>` - --> $DIR/resources-cfg.rs:47:21 + --> $DIR/resources-cfg.rs:48:21 | -47 | c.resources.o1; +48 | c.resources.o1; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o4` on type `__rtic_internal_initResources<'_>` - --> $DIR/resources-cfg.rs:48:21 + --> $DIR/resources-cfg.rs:49:21 | -48 | c.resources.o4; +49 | c.resources.o4; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o5` on type `__rtic_internal_initResources<'_>` - --> $DIR/resources-cfg.rs:49:21 + --> $DIR/resources-cfg.rs:50:21 | -49 | c.resources.o5; +50 | c.resources.o5; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o6` on type `__rtic_internal_initResources<'_>` - --> $DIR/resources-cfg.rs:50:21 + --> $DIR/resources-cfg.rs:51:21 | -50 | c.resources.o6; +51 | c.resources.o6; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s3` on type `__rtic_internal_initResources<'_>` - --> $DIR/resources-cfg.rs:51:21 + --> $DIR/resources-cfg.rs:52:21 | -51 | c.resources.s3; +52 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o2` on type `__rtic_internal_idleResources<'_>` - --> $DIR/resources-cfg.rs:58:21 + --> $DIR/resources-cfg.rs:59:21 | -58 | c.resources.o2; +59 | c.resources.o2; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o4` on type `__rtic_internal_idleResources<'_>` - --> $DIR/resources-cfg.rs:59:21 + --> $DIR/resources-cfg.rs:60:21 | -59 | c.resources.o4; +60 | c.resources.o4; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s1` on type `__rtic_internal_idleResources<'_>` - --> $DIR/resources-cfg.rs:60:21 + --> $DIR/resources-cfg.rs:61:21 | -60 | c.resources.s1; +61 | c.resources.s1; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s3` on type `__rtic_internal_idleResources<'_>` - --> $DIR/resources-cfg.rs:61:21 + --> $DIR/resources-cfg.rs:62:21 | -61 | c.resources.s3; +62 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o3` on type `__rtic_internal_uart0Resources<'_>` - --> $DIR/resources-cfg.rs:68:21 + --> $DIR/resources-cfg.rs:69:21 | -68 | c.resources.o3; +69 | c.resources.o3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s1` on type `__rtic_internal_uart0Resources<'_>` - --> $DIR/resources-cfg.rs:69:21 + --> $DIR/resources-cfg.rs:70:21 | -69 | c.resources.s1; +70 | c.resources.s1; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s2` on type `__rtic_internal_uart0Resources<'_>` - --> $DIR/resources-cfg.rs:70:21 + --> $DIR/resources-cfg.rs:71:21 | -70 | c.resources.s2; +71 | c.resources.s2; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s3` on type `__rtic_internal_uart0Resources<'_>` - --> $DIR/resources-cfg.rs:71:21 + --> $DIR/resources-cfg.rs:72:21 | -71 | c.resources.s3; +72 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s2` on type `__rtic_internal_uart1Resources<'_>` - --> $DIR/resources-cfg.rs:76:21 + --> $DIR/resources-cfg.rs:77:21 | -76 | c.resources.s2; +77 | c.resources.s2; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o5` on type `__rtic_internal_uart1Resources<'_>` - --> $DIR/resources-cfg.rs:77:21 + --> $DIR/resources-cfg.rs:78:21 | -77 | c.resources.o5; +78 | c.resources.o5; | ^^ unknown field | = note: available fields are: `__marker__` From 2e4a4ffd87c8a031f27635c060042019511523dc Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 4 Mar 2021 20:00:03 +0100 Subject: [PATCH 36/36] Preparing release 0.6.0-alpha.1 --- Cargo.toml | 7 +++---- macros/Cargo.toml | 4 ++-- macros/src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dd4633b148..d7c2056b6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ license = "MIT OR Apache-2.0" name = "cortex-m-rtic" readme = "README.md" repository = "https://github.com/rtic-rs/cortex-m-rtic" -version = "0.6.0-alpha.0" +version = "0.6.0-alpha.1" [lib] name = "rtic" @@ -53,14 +53,13 @@ required-features = ["__v7"] [dependencies] cortex-m = "0.7.0" cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.0" } -rtic-monotonic = { git = "https://github.com/rtic-rs/rtic-monotonic", branch = "master" } +rtic-monotonic = "0.1.0-alpha.0" rtic-core = "0.3.1" heapless = "0.6.1" bare-metal = "1.0.0" [dependencies.dwt-systick-monotonic] -git = "https://github.com/rtic-rs/dwt-systick-monotonic" -branch = "master" +version = "0.1.0-alpha.0" optional = true [build-dependencies] diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 6996bef4a1..f14b104655 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0" name = "cortex-m-rtic-macros" readme = "../README.md" repository = "https://github.com/rtic-rs/cortex-m-rtic" -version = "0.6.0-alpha.0" +version = "0.6.0-alpha.1" [lib] proc-macro = true @@ -22,5 +22,5 @@ proc-macro2 = "1" proc-macro-error = "1" quote = "1" syn = "1" -rtic-syntax = { git = "https://github.com/rtic-rs/rtic-syntax", branch = "new_monotonic", version = "0.5.0-alpha.0" } +rtic-syntax = "0.5.0-alpha.1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index c9136e5552..6ac7e2a4ad 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -20,7 +20,7 @@ mod tests; #[proc_macro_attribute] pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { let mut settings = Settings::default(); - settings.optimize_priorities = true; + settings.optimize_priorities = false; settings.parse_binds = true; settings.parse_extern_interrupt = true;