make idle optional

This commit is contained in:
Jorge Aparicio 2018-05-17 23:14:24 +02:00
parent b1abd52be2
commit dbb4ca6c33
15 changed files with 173 additions and 192 deletions

View file

@ -4,14 +4,12 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
extern crate cortex_m;
#[macro_use] #[macro_use]
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -30,13 +28,6 @@ fn init(mut _ctxt: init::Context) -> init::LateResources {
init::LateResources {} init::LateResources {}
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn exti0(_ctxt: exti0::Context) {} fn exti0(_ctxt: exti0::Context) {}
exception!(HardFault, hard_fault); exception!(HardFault, hard_fault);

48
examples/idle.rs Normal file
View file

@ -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);
}

View file

@ -4,14 +4,12 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
extern crate cortex_m;
#[macro_use] #[macro_use]
extern crate cortex_m_rt; extern crate cortex_m_rt;
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_semihosting; extern crate panic_semihosting;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m_rt::ExceptionFrame; use cortex_m_rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -24,13 +22,6 @@ fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {} init::LateResources {}
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
exception!(HardFault, hard_fault); exception!(HardFault, hard_fault);
#[inline(always)] #[inline(always)]

View file

@ -46,7 +46,6 @@ extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m::peripheral::{DWT, ITM}; use cortex_m::peripheral::{DWT, ITM};
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -85,13 +84,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources {
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn a(mut ctxt: a::Context) { fn a(mut ctxt: a::Context) {
let now = DWT::get_cycle_count(); let now = DWT::get_cycle_count();
let input = ctxt.input; let input = ctxt.input;

View file

@ -75,10 +75,9 @@ extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m::peripheral::{DWT, ITM}; use cortex_m::peripheral::{DWT, ITM};
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::{app, Resource}; use rtfm::app;
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -122,13 +121,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources {
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn a(mut ctxt: a::Context) { fn a(mut ctxt: a::Context) {
let now = DWT::get_cycle_count(); let now = DWT::get_cycle_count();

View file

@ -76,7 +76,6 @@ extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m::peripheral::{DWT, ITM}; use cortex_m::peripheral::{DWT, ITM};
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::{app, Resource}; use rtfm::{app, Resource};
@ -121,13 +120,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources {
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn a(mut ctxt: a::Context) { fn a(mut ctxt: a::Context) {
let now = DWT::get_cycle_count(); let now = DWT::get_cycle_count();

View file

@ -42,10 +42,8 @@ extern crate cortex_m;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
// extern crate panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m::peripheral::{DWT, ITM}; use cortex_m::peripheral::{DWT, ITM};
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -83,13 +81,6 @@ fn init(mut ctxt: init::Context) -> init::LateResources {
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn a(mut ctxt: a::Context) { fn a(mut ctxt: a::Context) {
let now = DWT::get_cycle_count(); let now = DWT::get_cycle_count();

View file

@ -11,7 +11,6 @@ extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m::peripheral::{DWT, ITM}; use cortex_m::peripheral::{DWT, ITM};
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -47,13 +46,6 @@ fn init(ctxt: init::Context) -> init::LateResources {
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn exti0(mut ctxt: exti0::Context) { fn exti0(mut ctxt: exti0::Context) {
let now = DWT::get_cycle_count(); let now = DWT::get_cycle_count();
iprintln!( iprintln!(

View file

@ -11,7 +11,6 @@ extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -37,20 +36,11 @@ fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {} init::LateResources {}
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn exti0(mut ctxt: exti0::Context) { fn exti0(mut ctxt: exti0::Context) {
ctxt.tasks.a.schedule_after(&mut ctxt.priority, 1 * S).ok(); ctxt.tasks.a.schedule_after(&mut ctxt.priority, 1 * S).ok();
} }
fn a(_ctxt: a::Context) { fn a(_ctxt: a::Context) {}
asm::bkpt();
}
exception!(HardFault, hard_fault); exception!(HardFault, hard_fault);

View file

@ -11,7 +11,6 @@ extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use cortex_m::peripheral::{DWT, ITM}; use cortex_m::peripheral::{DWT, ITM};
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -45,13 +44,6 @@ fn init(ctxt: init::Context) -> init::LateResources {
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn exti0(mut ctxt: exti0::Context) { fn exti0(mut ctxt: exti0::Context) {
let now = DWT::get_cycle_count(); let now = DWT::get_cycle_count();
iprintln!( iprintln!(

View file

@ -49,15 +49,8 @@ fn init(mut ctxt: init::Context) -> init::LateResources {
init::LateResources {} init::LateResources {}
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn exti0(mut ctxt: exti0::Context) { 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) { fn a(_ctxt: a::Context) {

View file

@ -4,14 +4,12 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
extern crate cortex_m;
#[macro_use] #[macro_use]
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use cortex_m::asm;
use rt::ExceptionFrame; use rt::ExceptionFrame;
use rtfm::app; use rtfm::app;
@ -48,13 +46,6 @@ fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources { BAR: Foo(0) } init::LateResources { BAR: Foo(0) }
} }
#[inline(always)]
fn idle(_ctxt: idle::Context) -> ! {
loop {
asm::wfi();
}
}
fn a(_ctxt: a::Context) {} fn a(_ctxt: a::Context) {}
fn b(_ctxt: b::Context) {} fn b(_ctxt: b::Context) {}

View file

@ -70,11 +70,17 @@ pub fn app(app: &App) -> Context {
} }
// resources // resources
for (priority, resource) in app.idle.resources.iter().map(|res| (0, res)).chain( let empty = HashSet::new();
app.tasks for (priority, resource) in
app.idle
.as_ref()
.map(|idle| &idle.resources)
.unwrap_or(&empty)
.iter() .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 let ceiling = ceilings
.resources .resources
.entry(*resource) .entry(*resource)

View file

@ -15,6 +15,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
root.push(quote! { root.push(quote! {
extern crate cortex_m_rtfm as #k; extern crate cortex_m_rtfm as #k;
#[allow(unused_imports)]
use #k::Resource as _cortex_m_rtfm_Resource; 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 ty = &resource.ty;
let expr = resource.expr.as_ref().map(|e| quote!(#e)).unwrap_or_else(|| { let expr = resource
quote!(unsafe { #k::_impl::uninitialized() }) .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 // TODO replace this with a call to `heapless::singleton!` when it doesn't require a feature
// gate in the user code // gate in the user code
@ -942,7 +945,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
FPU: p.FPU, FPU: p.FPU,
ITM: p.ITM, ITM: p.ITM,
MPU: p.MPU, MPU: p.MPU,
SCB: p.SCB, SCB: &mut p.SCB,
SYST: p.SYST, SYST: p.SYST,
TPIU: p.TPIU, TPIU: p.TPIU,
} }
@ -1010,13 +1013,10 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let (bl, lt) = if cfg!(feature = "timer-queue") { let bl = if cfg!(feature = "timer-queue") {
( Some(quote!(let _bl = ::#k::_impl::Instant(0);))
Some(quote!(let _bl = ::#k::_impl::Instant(0);)),
Some(quote!('a)),
)
} else { } else {
(None, None) None
}; };
root.push(quote! { root.push(quote! {
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -1032,8 +1032,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
pub use ::_ZN4init13LateResourcesE as LateResources; pub use ::_ZN4init13LateResourcesE as LateResources;
#[allow(dead_code)] #[allow(dead_code)]
pub struct Context<#lt> { pub struct Context<'a> {
pub core: ::#k::_impl::Peripherals<#lt>, pub core: ::#k::_impl::Peripherals<'a>,
pub device: Device, pub device: Device,
pub resources: Resources, pub resources: Resources,
pub tasks: Tasks, pub tasks: Tasks,
@ -1041,8 +1041,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl<#lt> Context<#lt> { impl<'a> Context<'a> {
pub unsafe fn new(core: ::#k::_impl::Peripherals<#lt>) -> Self { pub unsafe fn new(core: ::#k::_impl::Peripherals<'a>) -> Self {
Context { Context {
tasks: Tasks::new(), tasks: Tasks::new(),
core, 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 { if needs_tq {
post_init.push(quote! { post_init.push(quote! {
// Set the system time to zero // Set the system time to zero
@ -1147,8 +1154,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
} }
/* idle */ /* idle */
let res_fields = app.idle if let Some(idle) = app.idle.as_ref() {
.resources let res_fields = idle.resources
.iter() .iter()
.map(|res| { .map(|res| {
if ctxt.ceilings.resources()[res].is_owned() { if ctxt.ceilings.resources()[res].is_owned() {
@ -1161,8 +1168,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let res_exprs = app.idle let res_exprs = idle.resources
.resources
.iter() .iter()
.map(|res| { .map(|res| {
if ctxt.ceilings.resources()[res].is_owned() { if ctxt.ceilings.resources()[res].is_owned() {
@ -1209,23 +1215,17 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
} }
} }
}); });
}
/* main */ /* main */
let idle = &app.idle.path;
let init = &app.init.path; let init = &app.init.path;
root.push(quote! { let mut main = vec![quote! {
#[allow(unsafe_code)]
#[allow(unused_mut)]
#[deny(const_err)]
#[no_mangle]
pub unsafe extern "C" fn main() -> ! {
#[allow(unused_imports)] #[allow(unused_imports)]
use ::#k::Resource; use ::#k::Resource;
#[allow(unused_imports)] #[allow(unused_imports)]
use #device::Interrupt; use #device::Interrupt;
let init: fn(init::Context) -> init::LateResources = #init; let init: fn(init::Context) -> init::LateResources = #init;
let idle: fn(idle::Context) -> ! = #idle;
::#k::_impl::interrupt::disable(); ::#k::_impl::interrupt::disable();
@ -1238,8 +1238,28 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
#(#post_init)* #(#post_init)*
::#k::_impl::interrupt::enable(); ::#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()) 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() -> ! {
#(#main)*
} }
}); });

View file

@ -2,15 +2,15 @@ use core::mem;
pub use self::instant::Instant; pub use self::instant::Instant;
pub use self::tq::{dispatch, NotReady, TimerQueue}; pub use self::tq::{dispatch, NotReady, TimerQueue};
pub use cortex_m::interrupt;
use cortex_m::interrupt::Nr; use cortex_m::interrupt::Nr;
pub use cortex_m::peripheral::syst::SystClkSource; pub use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::{CBP, CPUID, DCB, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU}; use cortex_m::peripheral::{CBP, CPUID, DCB, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU};
#[cfg(not(feature = "timer-queue"))] #[cfg(not(feature = "timer-queue"))]
use cortex_m::peripheral::{DWT, SYST}; use cortex_m::peripheral::{DWT, SYST};
pub use cortex_m::{asm, interrupt};
pub use heapless::object_pool::{Singleton, Uninit}; pub use heapless::object_pool::{Singleton, Uninit};
pub use stable_deref_trait::StableDeref;
use heapless::RingBuffer as Queue; use heapless::RingBuffer as Queue;
pub use stable_deref_trait::StableDeref;
pub use typenum::consts::*; pub use typenum::consts::*;
pub use typenum::{Max, Maximum, Unsigned}; pub use typenum::{Max, Maximum, Unsigned};