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_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);

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_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)]

View file

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

View file

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

View file

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

View file

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

View file

@ -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!(

View file

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

View file

@ -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!(

View file

@ -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) {

View file

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

View file

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

View file

@ -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::<Vec<_>>();
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::<Vec<_>>();
quote!(pub #res: &'static mut #ty)
} else {
quote!(pub #res: _resource::#res)
}
})
.collect::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
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)*
}
});

View file

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