From dbb4ca6c33b6601c328fe5682ea1018c29f426fb Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 17 May 2018 23:14:24 +0200 Subject: [PATCH] make idle optional --- examples/event-task.rs | 9 - examples/idle.rs | 48 +++++ examples/minimal.rs | 9 - examples/periodic-payload.rs | 8 - examples/periodic-preemption-payload.rs | 10 +- examples/periodic-preemption.rs | 8 - examples/periodic.rs | 9 - examples/schedule-after-from-event-task.rs | 8 - examples/schedule-after.rs | 12 +- examples/schedule-now-from-event-task.rs | 8 - examples/schedule-now.rs | 9 +- examples/user-struct.rs | 9 - macros/src/analyze.rs | 14 +- macros/src/trans.rs | 200 +++++++++++---------- src/_impl/mod.rs | 4 +- 15 files changed, 173 insertions(+), 192 deletions(-) create mode 100644 examples/idle.rs diff --git a/examples/event-task.rs b/examples/event-task.rs index 3a51c5b4f6..0f51bbfaf3 100644 --- a/examples/event-task.rs +++ b/examples/event-task.rs @@ -4,14 +4,12 @@ #![no_main] #![no_std] -extern crate cortex_m; #[macro_use] extern crate cortex_m_rt as rt; extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use rt::ExceptionFrame; use rtfm::app; @@ -30,13 +28,6 @@ fn init(mut _ctxt: init::Context) -> init::LateResources { init::LateResources {} } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn exti0(_ctxt: exti0::Context) {} exception!(HardFault, hard_fault); diff --git a/examples/idle.rs b/examples/idle.rs new file mode 100644 index 0000000000..e4303b9161 --- /dev/null +++ b/examples/idle.rs @@ -0,0 +1,48 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![feature(proc_macro)] +#![no_main] +#![no_std] + +extern crate cortex_m; +#[macro_use] +extern crate cortex_m_rt; +extern crate cortex_m_rtfm as rtfm; +extern crate panic_semihosting; +extern crate stm32f103xx; + +use cortex_m::asm; +use cortex_m_rt::ExceptionFrame; +use rtfm::app; + +app! { + device: stm32f103xx, + + idle: {}, +} + +#[inline(always)] +fn init(_ctxt: init::Context) -> init::LateResources { + init::LateResources {} +} + +#[inline(always)] +fn idle(_ctxt: idle::Context) -> ! { + loop { + asm::wfi(); + } +} + +exception!(HardFault, hard_fault); + +#[inline(always)] +fn hard_fault(ef: &ExceptionFrame) -> ! { + panic!("HardFault at {:#?}", ef); +} + +exception!(*, default_handler); + +#[inline(always)] +fn default_handler(irqn: i16) { + panic!("Unhandled exception (IRQn = {})", irqn); +} diff --git a/examples/minimal.rs b/examples/minimal.rs index 7c7b0b823d..da76629dc8 100644 --- a/examples/minimal.rs +++ b/examples/minimal.rs @@ -4,14 +4,12 @@ #![no_main] #![no_std] -extern crate cortex_m; #[macro_use] extern crate cortex_m_rt; extern crate cortex_m_rtfm as rtfm; extern crate panic_semihosting; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m_rt::ExceptionFrame; use rtfm::app; @@ -24,13 +22,6 @@ fn init(_ctxt: init::Context) -> init::LateResources { init::LateResources {} } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - exception!(HardFault, hard_fault); #[inline(always)] diff --git a/examples/periodic-payload.rs b/examples/periodic-payload.rs index 9697934fd9..e99001ea58 100644 --- a/examples/periodic-payload.rs +++ b/examples/periodic-payload.rs @@ -46,7 +46,6 @@ extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m::peripheral::{DWT, ITM}; use rt::ExceptionFrame; use rtfm::app; @@ -85,13 +84,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources { init::LateResources { ITM: ctxt.core.ITM } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn a(mut ctxt: a::Context) { let now = DWT::get_cycle_count(); let input = ctxt.input; diff --git a/examples/periodic-preemption-payload.rs b/examples/periodic-preemption-payload.rs index 0207b4546e..1397ac2f98 100644 --- a/examples/periodic-preemption-payload.rs +++ b/examples/periodic-preemption-payload.rs @@ -75,10 +75,9 @@ extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m::peripheral::{DWT, ITM}; use rt::ExceptionFrame; -use rtfm::{app, Resource}; +use rtfm::app; app! { device: stm32f103xx, @@ -122,13 +121,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources { init::LateResources { ITM: ctxt.core.ITM } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn a(mut ctxt: a::Context) { let now = DWT::get_cycle_count(); diff --git a/examples/periodic-preemption.rs b/examples/periodic-preemption.rs index e1e450e69c..3ca458061b 100644 --- a/examples/periodic-preemption.rs +++ b/examples/periodic-preemption.rs @@ -76,7 +76,6 @@ extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m::peripheral::{DWT, ITM}; use rt::ExceptionFrame; use rtfm::{app, Resource}; @@ -121,13 +120,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources { init::LateResources { ITM: ctxt.core.ITM } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn a(mut ctxt: a::Context) { let now = DWT::get_cycle_count(); diff --git a/examples/periodic.rs b/examples/periodic.rs index 90b3abeba6..875d5b896d 100644 --- a/examples/periodic.rs +++ b/examples/periodic.rs @@ -42,10 +42,8 @@ extern crate cortex_m; extern crate cortex_m_rt as rt; extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; -// extern crate panic_itm; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m::peripheral::{DWT, ITM}; use rt::ExceptionFrame; use rtfm::app; @@ -83,13 +81,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources { init::LateResources { ITM: ctxt.core.ITM } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn a(mut ctxt: a::Context) { let now = DWT::get_cycle_count(); diff --git a/examples/schedule-after-from-event-task.rs b/examples/schedule-after-from-event-task.rs index 2e666a7d56..de7da763b8 100644 --- a/examples/schedule-after-from-event-task.rs +++ b/examples/schedule-after-from-event-task.rs @@ -11,7 +11,6 @@ extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m::peripheral::{DWT, ITM}; use rt::ExceptionFrame; use rtfm::app; @@ -47,13 +46,6 @@ fn init(ctxt: init::Context) -> init::LateResources { init::LateResources { ITM: ctxt.core.ITM } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn exti0(mut ctxt: exti0::Context) { let now = DWT::get_cycle_count(); iprintln!( diff --git a/examples/schedule-after.rs b/examples/schedule-after.rs index dc7946b9df..f8a00a1947 100644 --- a/examples/schedule-after.rs +++ b/examples/schedule-after.rs @@ -11,7 +11,6 @@ extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use rt::ExceptionFrame; use rtfm::app; @@ -37,20 +36,11 @@ fn init(_ctxt: init::Context) -> init::LateResources { init::LateResources {} } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn exti0(mut ctxt: exti0::Context) { ctxt.tasks.a.schedule_after(&mut ctxt.priority, 1 * S).ok(); } -fn a(_ctxt: a::Context) { - asm::bkpt(); -} +fn a(_ctxt: a::Context) {} exception!(HardFault, hard_fault); diff --git a/examples/schedule-now-from-event-task.rs b/examples/schedule-now-from-event-task.rs index 98531ddfa3..d900e8fe3c 100644 --- a/examples/schedule-now-from-event-task.rs +++ b/examples/schedule-now-from-event-task.rs @@ -11,7 +11,6 @@ extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use cortex_m::peripheral::{DWT, ITM}; use rt::ExceptionFrame; use rtfm::app; @@ -45,13 +44,6 @@ fn init(ctxt: init::Context) -> init::LateResources { init::LateResources { ITM: ctxt.core.ITM } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn exti0(mut ctxt: exti0::Context) { let now = DWT::get_cycle_count(); iprintln!( diff --git a/examples/schedule-now.rs b/examples/schedule-now.rs index f16539b2b9..c8fca6d51c 100644 --- a/examples/schedule-now.rs +++ b/examples/schedule-now.rs @@ -49,15 +49,8 @@ fn init(mut ctxt: init::Context) -> init::LateResources { init::LateResources {} } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn exti0(mut ctxt: exti0::Context) { - ctxt.tasks.a.schedule_now(&mut ctxt.priority).ok(); + ctxt.tasks.a.schedule_now(&mut ctxt.priority).unwrap(); } fn a(_ctxt: a::Context) { diff --git a/examples/user-struct.rs b/examples/user-struct.rs index 2efb98f32e..9a85eaf30c 100644 --- a/examples/user-struct.rs +++ b/examples/user-struct.rs @@ -4,14 +4,12 @@ #![no_main] #![no_std] -extern crate cortex_m; #[macro_use] extern crate cortex_m_rt as rt; extern crate cortex_m_rtfm as rtfm; extern crate panic_abort; extern crate stm32f103xx; -use cortex_m::asm; use rt::ExceptionFrame; use rtfm::app; @@ -48,13 +46,6 @@ fn init(_ctxt: init::Context) -> init::LateResources { init::LateResources { BAR: Foo(0) } } -#[inline(always)] -fn idle(_ctxt: idle::Context) -> ! { - loop { - asm::wfi(); - } -} - fn a(_ctxt: a::Context) {} fn b(_ctxt: b::Context) {} diff --git a/macros/src/analyze.rs b/macros/src/analyze.rs index c901da9ab2..3bfc72f36b 100644 --- a/macros/src/analyze.rs +++ b/macros/src/analyze.rs @@ -70,11 +70,17 @@ pub fn app(app: &App) -> Context { } // resources - for (priority, resource) in app.idle.resources.iter().map(|res| (0, res)).chain( - app.tasks + let empty = HashSet::new(); + for (priority, resource) in + app.idle + .as_ref() + .map(|idle| &idle.resources) + .unwrap_or(&empty) .iter() - .flat_map(|(name, task)| task.resources.iter().map(move |res| (task.priority, res))), - ) { + .map(|res| (0, res)) + .chain(app.tasks.iter().flat_map(|(name, task)| { + task.resources.iter().map(move |res| (task.priority, res)) + })) { let ceiling = ceilings .resources .entry(*resource) diff --git a/macros/src/trans.rs b/macros/src/trans.rs index 15b6d0af07..7e14fdb7ff 100644 --- a/macros/src/trans.rs +++ b/macros/src/trans.rs @@ -15,6 +15,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { root.push(quote! { extern crate cortex_m_rtfm as #k; + #[allow(unused_imports)] use #k::Resource as _cortex_m_rtfm_Resource; }); @@ -90,9 +91,11 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { } let ty = &resource.ty; - let expr = resource.expr.as_ref().map(|e| quote!(#e)).unwrap_or_else(|| { - quote!(unsafe { #k::_impl::uninitialized() }) - }); + let expr = resource + .expr + .as_ref() + .map(|e| quote!(#e)) + .unwrap_or_else(|| quote!(unsafe { #k::_impl::uninitialized() })); // TODO replace this with a call to `heapless::singleton!` when it doesn't require a feature // gate in the user code @@ -942,7 +945,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { FPU: p.FPU, ITM: p.ITM, MPU: p.MPU, - SCB: p.SCB, + SCB: &mut p.SCB, SYST: p.SYST, TPIU: p.TPIU, } @@ -1010,13 +1013,10 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { }) .collect::>(); - let (bl, lt) = if cfg!(feature = "timer-queue") { - ( - Some(quote!(let _bl = ::#k::_impl::Instant(0);)), - Some(quote!('a)), - ) + let bl = if cfg!(feature = "timer-queue") { + Some(quote!(let _bl = ::#k::_impl::Instant(0);)) } else { - (None, None) + None }; root.push(quote! { #[allow(non_snake_case)] @@ -1032,8 +1032,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { pub use ::_ZN4init13LateResourcesE as LateResources; #[allow(dead_code)] - pub struct Context<#lt> { - pub core: ::#k::_impl::Peripherals<#lt>, + pub struct Context<'a> { + pub core: ::#k::_impl::Peripherals<'a>, pub device: Device, pub resources: Resources, pub tasks: Tasks, @@ -1041,8 +1041,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { } #[allow(unsafe_code)] - impl<#lt> Context<#lt> { - pub unsafe fn new(core: ::#k::_impl::Peripherals<#lt>) -> Self { + impl<'a> Context<'a> { + pub unsafe fn new(core: ::#k::_impl::Peripherals<'a>) -> Self { Context { tasks: Tasks::new(), core, @@ -1138,6 +1138,13 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { }); } + if app.idle.is_none() { + post_init.push(quote! { + // Set SLEEPONEXIT + p.SCB.scr.modify(|r| r | (1 << 1)); + }); + } + if needs_tq { post_init.push(quote! { // Set the system time to zero @@ -1147,99 +1154,112 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens { } /* idle */ - let res_fields = app.idle - .resources - .iter() - .map(|res| { - if ctxt.ceilings.resources()[res].is_owned() { - let ty = &app.resources[res].ty; + if let Some(idle) = app.idle.as_ref() { + let res_fields = idle.resources + .iter() + .map(|res| { + if ctxt.ceilings.resources()[res].is_owned() { + let ty = &app.resources[res].ty; - quote!(pub #res: &'static mut #ty) - } else { - quote!(pub #res: _resource::#res) - } - }) - .collect::>(); + quote!(pub #res: &'static mut #ty) + } else { + quote!(pub #res: _resource::#res) + } + }) + .collect::>(); - let res_exprs = app.idle - .resources - .iter() - .map(|res| { - if ctxt.ceilings.resources()[res].is_owned() { - quote!(#res: _resource::#res::_var()) - } else { - quote!(#res: _resource::#res::new()) - } - }) - .collect::>(); + let res_exprs = idle.resources + .iter() + .map(|res| { + if ctxt.ceilings.resources()[res].is_owned() { + quote!(#res: _resource::#res::_var()) + } else { + quote!(#res: _resource::#res::new()) + } + }) + .collect::>(); - root.push(quote! { - mod idle { - #[allow(unused_imports)] - use ::#k::Resource; + root.push(quote! { + mod idle { + #[allow(unused_imports)] + use ::#k::Resource; - #[allow(dead_code)] - pub struct Context { - pub resources: Resources, - pub priority: ::#k::Priority<::#k::_impl::U0>, - } + #[allow(dead_code)] + pub struct Context { + pub resources: Resources, + pub priority: ::#k::Priority<::#k::_impl::U0>, + } - #[allow(unsafe_code)] - impl Context { - pub unsafe fn new() -> Self { - Context { - resources: Resources::new(), - priority: ::#k::Priority::_new(), + #[allow(unsafe_code)] + impl Context { + pub unsafe fn new() -> Self { + Context { + resources: Resources::new(), + priority: ::#k::Priority::_new(), + } + } + } + + #[allow(non_snake_case)] + pub struct Resources { + #(#res_fields,)* + } + + #[allow(unsafe_code)] + impl Resources { + unsafe fn new() -> Self { + Resources { + #(#res_exprs,)* + } } } } - - #[allow(non_snake_case)] - pub struct Resources { - #(#res_fields,)* - } - - #[allow(unsafe_code)] - impl Resources { - unsafe fn new() -> Self { - Resources { - #(#res_exprs,)* - } - } - } - } - }); + }); + } /* main */ - let idle = &app.idle.path; let init = &app.init.path; + let mut main = vec![quote! { + #[allow(unused_imports)] + use ::#k::Resource; + #[allow(unused_imports)] + use #device::Interrupt; + + let init: fn(init::Context) -> init::LateResources = #init; + + ::#k::_impl::interrupt::disable(); + + let mut p = ::#k::_impl::steal(); + + #(#pre_init)* + + let _lr = init(init::Context::new(#core)); + + #(#post_init)* + + ::#k::_impl::interrupt::enable(); + }]; + + if let Some(idle) = app.idle.as_ref().map(|idle| &idle.path) { + main.push(quote! { + let idle: fn(idle::Context) -> ! = #idle; + idle(idle::Context::new()) + }); + } else { + main.push(quote! { + loop { + #k::_impl::asm::wfi(); + } + }); + } + root.push(quote! { #[allow(unsafe_code)] #[allow(unused_mut)] #[deny(const_err)] #[no_mangle] pub unsafe extern "C" fn main() -> ! { - #[allow(unused_imports)] - use ::#k::Resource; - #[allow(unused_imports)] - use #device::Interrupt; - - let init: fn(init::Context) -> init::LateResources = #init; - let idle: fn(idle::Context) -> ! = #idle; - - ::#k::_impl::interrupt::disable(); - - let mut p = ::#k::_impl::steal(); - - #(#pre_init)* - - let _lr = init(init::Context::new(#core)); - - #(#post_init)* - - ::#k::_impl::interrupt::enable(); - - idle(idle::Context::new()) + #(#main)* } }); diff --git a/src/_impl/mod.rs b/src/_impl/mod.rs index 79bf034320..6739dffd66 100644 --- a/src/_impl/mod.rs +++ b/src/_impl/mod.rs @@ -2,15 +2,15 @@ use core::mem; pub use self::instant::Instant; pub use self::tq::{dispatch, NotReady, TimerQueue}; -pub use cortex_m::interrupt; use cortex_m::interrupt::Nr; pub use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::{CBP, CPUID, DCB, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU}; #[cfg(not(feature = "timer-queue"))] use cortex_m::peripheral::{DWT, SYST}; +pub use cortex_m::{asm, interrupt}; pub use heapless::object_pool::{Singleton, Uninit}; -pub use stable_deref_trait::StableDeref; use heapless::RingBuffer as Queue; +pub use stable_deref_trait::StableDeref; pub use typenum::consts::*; pub use typenum::{Max, Maximum, Unsigned};