update the cfail tests

This commit is contained in:
Jorge Aparicio 2018-05-01 14:01:51 +02:00
parent 205aa44ed5
commit e34abea704
22 changed files with 258 additions and 187 deletions

View file

@ -24,6 +24,7 @@ compiletest_rs = "0.3.5"
[dev-dependencies] [dev-dependencies]
panic-abort = "0.1.1" panic-abort = "0.1.1"
panic-itm = "0.1.0" panic-itm = "0.1.0"
typenum = "1.10.0"
[dev-dependencies.stm32f103xx] [dev-dependencies.stm32f103xx]
features = ["rt"] features = ["rt"]

View file

@ -59,13 +59,13 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
}); });
resources.push(quote! { resources.push(quote! {
pub struct #name { _0: () } pub struct #name { _not_send_or_sync: PhantomData<*const ()> }
#[allow(dead_code)] #[allow(dead_code)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl #name { impl #name {
pub unsafe fn new() -> Self { pub unsafe fn new() -> Self {
#name { _0: () } #name { _not_send_or_sync: PhantomData }
} }
} }
}); });
@ -75,6 +75,9 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
mod __resource { mod __resource {
extern crate #krate; extern crate #krate;
#[allow(unused_imports)]
use core::marker::PhantomData;
#(#resources)* #(#resources)*
} }
}); });
@ -776,16 +779,26 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
.resources .resources
.iter() .iter()
.map(|res| { .map(|res| {
let ty = &app.resources[res].ty; if ctxt.ceilings.resources()[res].is_owned() {
let ty = &app.resources[res].ty;
quote!(pub #res: &'static mut #ty) quote!(pub #res: &'static mut #ty)
} else {
quote!(pub #res: __resource::#res)
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let res_exprs = app.idle let res_exprs = app.idle
.resources .resources
.iter() .iter()
.map(|res| quote!(#res: __resource::#res::get())) .map(|res| {
if ctxt.ceilings.resources()[res].is_owned() {
quote!(#res: __resource::#res::get())
} else {
quote!(#res: __resource::#res::new())
}
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
root.push(quote! { root.push(quote! {
@ -797,6 +810,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
pub struct Context { pub struct Context {
pub resources: Resources, pub resources: Resources,
pub threshold: #krate::Threshold<#krate::U0>,
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -804,6 +818,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
pub unsafe fn new() -> Self { pub unsafe fn new() -> Self {
Context { Context {
resources: Resources::new(), resources: Resources::new(),
threshold: #krate::Threshold::new(),
} }
} }
} }
@ -829,6 +844,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
let init = &app.init.path; let init = &app.init.path;
root.push(quote! { root.push(quote! {
#[allow(unsafe_code)] #[allow(unsafe_code)]
#[deny(const_err)]
fn main() { fn main() {
#[allow(unused_imports)] #[allow(unused_imports)]
use #hidden::#krate::Resource; use #hidden::#krate::Resource;

View file

@ -91,6 +91,25 @@ impl Core {
} }
} }
pub fn atomic<R, P, F>(t: &mut Threshold<P>, f: F) -> R
where
F: FnOnce(&mut Threshold<U255>) -> R,
P: Unsigned,
{
unsafe {
debug_assert!(P::to_u8() <= 255);
if P::to_u8() < 255 {
interrupt::disable();
let r = f(&mut Threshold::new());
interrupt::enable();
r
} else {
f(&mut Threshold::new())
}
}
}
#[doc(hidden)] #[doc(hidden)]
pub const unsafe fn uninitialized<T>() -> T { pub const unsafe fn uninitialized<T>() -> T {
#[allow(unions_with_drop_fields)] #[allow(unions_with_drop_fields)]
@ -102,6 +121,7 @@ pub const unsafe fn uninitialized<T>() -> T {
U { none: () }.some U { none: () }.some
} }
#[doc(hidden)]
pub unsafe fn set_pending<I>(interrupt: I) pub unsafe fn set_pending<I>(interrupt: I)
where where
I: Nr, I: Nr,

View file

@ -3,7 +3,8 @@ use core::marker::PhantomData;
#[cfg(not(armv6m))] #[cfg(not(armv6m))]
use cortex_m::register::basepri; use cortex_m::register::basepri;
use typenum::{Max, Maximum, Unsigned}; use typenum::type_operators::IsGreaterOrEqual;
use typenum::{Max, Maximum, True, Unsigned};
pub struct Threshold<N> pub struct Threshold<N>
where where
@ -34,11 +35,17 @@ pub unsafe trait Resource {
#[doc(hidden)] #[doc(hidden)]
unsafe fn get() -> &'static mut Self::Data; unsafe fn get() -> &'static mut Self::Data;
fn borrow<'cs>(&'cs self, _t: &'cs Threshold<Self::Ceiling>) -> &'cs Self::Data { fn borrow<'cs, P>(&'cs self, _t: &'cs Threshold<P>) -> &'cs Self::Data
where
P: IsGreaterOrEqual<Self::Ceiling, Output = True> + Unsigned,
{
unsafe { Self::get() } unsafe { Self::get() }
} }
fn borrow_mut<'cs>(&'cs mut self, _t: &'cs Threshold<Self::Ceiling>) -> &'cs mut Self::Data { fn borrow_mut<'cs, P>(&'cs mut self, _t: &'cs Threshold<P>) -> &'cs mut Self::Data
where
P: IsGreaterOrEqual<Self::Ceiling, Output = True> + Unsigned,
{
unsafe { Self::get() } unsafe { Self::get() }
} }

View file

@ -5,9 +5,10 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource, Threshold}; use rtfm::{app, Resource};
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -21,23 +22,27 @@ app! {
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
priority: 1,
resources: [ON], resources: [ON],
}, },
}, },
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle(mut ctxt: idle::Context) -> ! {
let t = &mut ctxt.threshold;
let on = ctxt.resources.ON;
fn idle(t: &mut Threshold, r: idle::Resources) -> ! {
let state = rtfm::atomic(t, |t| { let state = rtfm::atomic(t, |t| {
// ERROR borrow can't escape this *global* critical section // ERROR borrow can't escape this *global* critical section
r.ON.borrow(t) //~ error cannot infer an appropriate lifetime on.borrow(t) //~ error cannot infer an appropriate lifetime
}); });
let state = r.ON.claim(t, |state, _t| { let state = on.claim(t, |state, _t| {
// ERROR borrow can't escape this critical section // ERROR borrow can't escape this critical section
state //~ error cannot infer an appropriate lifetime state //~ error cannot infer an appropriate lifetime
}); });
@ -45,4 +50,4 @@ fn idle(t: &mut Threshold, r: idle::Resources) -> ! {
loop {} loop {}
} }
fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {} fn exti0(_ctxt: exti0::Context) {}

View file

@ -8,21 +8,22 @@ extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { app! { //~ error proc macro panicked
//~^ error proc macro panicked
device: stm32f103xx, device: stm32f103xx,
tasks: { tasks: {
SYS_TICK: { a: {
interrupt: EXTI0, //~ error this interrupt is already bound to another task
priority: 1, priority: 1,
}, },
SYS_TICK: { b: {
interrupt: EXTI0,
priority: 2, priority: 2,
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {}
fn idle() -> ! {} fn idle(_ctxt: idle::Context) -> ! {}

View file

@ -4,24 +4,27 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error proc macro panicked app! { //~ error proc macro panicked
device: stm32f103xx, device: stm32f103xx, //~ no variant named `SYS_TICK` found for type `stm32f103xx::Interrupt`
tasks: { tasks: {
// ERROR exceptions can't be enabled / disabled here sys_tick: {
SYS_TICK: { interrupt: SYS_TICK, // ERROR can't bind to exception
enabled: true,
priority: 1,
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn sys_tick(_ctxt: sys_tick::Context) {}

View file

@ -4,15 +4,18 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error mismatched types app! { //~ mismatched types
device: stm32f103xx, device: stm32f103xx,
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
// ERROR `idle` must be a diverging function // ERROR `idle` must be a diverging function
fn idle() {} fn idle(_ctxt: idle::Context) {}

View file

@ -3,6 +3,7 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
@ -24,8 +25,10 @@ app! { //~ proc macro panicked
}, },
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle(_r: init::Resources) -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }

View file

@ -1,8 +1,10 @@
#![deny(unsafe_code)]
#![deny(warnings)] #![deny(warnings)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
@ -19,18 +21,20 @@ app! { //~ proc macro panicked
}, },
tasks: { tasks: {
SYS_TICK: { exti0: {
path: sys_tick, interrupt: EXTI0,
resources: [BUFFER], resources: [BUFFER],
//~^ error: this resource is owned by `init` and can't be shared //~^ error: this resource is owned by `init` and can't be shared
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn sys_tick() {} fn exti0(_ctxt: exti0::Context) {}

View file

@ -4,17 +4,19 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error mismatched types app! { //~ error incorrect number of function parameters
//~^ note expected type `fn(init::Context) -> _ZN4init13LateResourcesE`
device: stm32f103xx, device: stm32f103xx,
} }
// ERROR `init` must have signature `fn (init::Peripherals)` // ERROR `init` must have signature `fn (init::Peripherals)`
fn init() {} fn init() {}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }

View file

@ -4,24 +4,27 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error no variant named `EXTI33` found for type app! { //~ error no variant named `EXTI33` found for type `stm32f103xx::Interrupt`
device: stm32f103xx, device: stm32f103xx,
tasks: { tasks: {
EXTI33: { exti33: {
path: exti33, interrupt: EXTI33,
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn exti33() {} fn exti33(_ctxt: exti33::Context) {}

View file

@ -4,9 +4,10 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Threshold}; use rtfm::app;
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -17,34 +18,32 @@ app! {
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
priority: 1, // priority: 1,
resources: [A, LATE], resources: [A, LATE],
}, },
EXTI1: { exti1: {
path: exti1, interrupt: EXTI1,
priority: 2, priority: 2,
resources: [A, LATE], resources: [A, LATE],
}, },
}, },
} }
fn init(_p: init::Peripherals, r: init::Resources) -> init::LateResources { fn init(ctxt: init::Context) -> init::LateResources {
// Try to use a resource that's not yet initialized: // Tried to use a resource that's not yet initialized:
r.LATE; let _late = ctxt.resources.LATE;
//~^ error: no field `LATE` //~^ error: no field `LATE` on type `init::Resources`
init::LateResources { init::LateResources { LATE: 0 }
LATE: 0,
}
} }
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {} fn exti0(_ctxt: exti0::Context) {}
fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {} fn exti1(_ctxt: exti1::Context) {}

View file

@ -5,9 +5,10 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource, Threshold}; use rtfm::{app, Resource};
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -15,54 +16,62 @@ app! {
resources: { resources: {
static ON: bool = false; static ON: bool = false;
static MAX: u8 = 0; static MAX: u8 = 0;
static OWNED: bool = false;
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
priority: 1, // priority: 1,
resources: [MAX, ON], resources: [MAX, ON],
}, },
EXTI1: { exti1: {
path: exti1, interrupt: EXTI1,
priority: 2, priority: 2,
resources: [ON], resources: [ON, OWNED],
}, },
EXTI2: { exti2: {
path: exti2, interrupt: EXTI2,
priority: 16, priority: 16,
resources: [MAX], resources: [MAX],
}, },
}, },
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn exti0(mut t: &mut Threshold, mut r: EXTI0::Resources) { #[allow(non_snake_case)]
fn exti0(mut ctxt: exti0::Context) {
let exti0::Resources { ON, mut MAX } = ctxt.resources;
let t = &mut ctxt.threshold;
// ERROR need to lock to access the resource because priority < ceiling // ERROR need to lock to access the resource because priority < ceiling
if *r.ON { {
//~^ error type `EXTI0::ON` cannot be dereferenced let _on = ON.borrow(t);
//~^ error type mismatch resolving
} }
// OK need to lock to access the resource // OK need to lock to access the resource
if r.ON.claim(&mut t, |on, _| *on) {} if ON.claim(t, |on, _| *on) {}
// OK can claim a resource with maximum ceiling // OK can claim a resource with maximum ceiling
r.MAX.claim_mut(&mut t, |max, _| *max += 1); MAX.claim_mut(t, |max, _| *max += 1);
} }
fn exti1(mut t: &mut Threshold, r: EXTI1::Resources) { #[allow(non_snake_case)]
// OK to directly access the resource because priority == ceiling fn exti1(ctxt: exti1::Context) {
if *r.ON {} let exti1::Resources { OWNED, .. } = ctxt.resources;
// though the resource can still be claimed -- the claim is a no-op // OK to directly access the resource because this task is the only owner
if r.ON.claim(&mut t, |on, _| *on) {} if *OWNED {}
} }
fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) {} fn exti2(_ctxt: exti2::Context) {}

View file

@ -1,28 +0,0 @@
#![deny(unsafe_code)]
#![deny(warnings)]
#![feature(proc_macro)]
#![no_std]
extern crate cortex_m_rtfm as rtfm;
extern crate stm32f103xx;
use rtfm::app;
app! { //~ error proc macro panicked
device: stm32f103xx,
tasks: {
EXTI0: {
enabled: true,
priority: 1,
// ERROR peripheral appears twice in this list
resources: [GPIOA, GPIOA],
},
},
}
fn init(_p: init::Peripherals) {}
fn idle() -> ! {
loop {}
}

View file

@ -1,30 +1,30 @@
#![deny(unsafe_code)]
#![deny(warnings)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error attempt to subtract with overflow app! { //~ error attempt to subtract with overflow
//~^ error constant evaluation error
device: stm32f103xx, device: stm32f103xx,
tasks: { tasks: {
SYS_TICK: { exti0: {
path: sys_tick, interrupt: EXTI0,
// ERROR priority must be in the range [1, 16] // ERROR priority must be in the range [1, 16]
priority: 17, priority: 17,
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn sys_tick() {} fn exti0(_ctxt: exti0::Context) {}

View file

@ -4,27 +4,26 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error attempt to subtract with overflow app! {
//~^ error constant evaluation error
device: stm32f103xx, device: stm32f103xx,
tasks: { tasks: {
SYS_TICK: { exti0: {
path: sys_tick, interrupt: EXTI0,
// ERROR priority must be in the range [1, 16] priority: 0, //~ error this value is outside the valid range of `(1, 255)`
priority: 0,
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn sys_tick() {} fn exti0(_ctxt: exti0::Context) {}

View file

@ -4,6 +4,7 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
@ -12,21 +13,23 @@ app! { //~ error proc macro panicked
device: stm32f103xx, device: stm32f103xx,
resources: { resources: {
// resource `MAX` listed twice static MAX: u8 = 0;
MAX: u8 = 0; static MAX: u16 = 0; //~ error this resource name appears more than once in this list
MAX: u16 = 0;
}, },
tasks: { tasks: {
EXTI0: { exti0: {
enabled: true, interrupt: EXTI0,
priority: 1, resources: [
MAX,
MAX, //~ error this resource name appears more than once in this list
],
}, },
}, },
} }
fn init(_p: init::Peripherals) {} fn init(_ctxt: init::Context) -> init::LateResources {}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }

View file

@ -1,13 +1,13 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
#![deny(warnings)] #![deny(warnings)]
#![feature(const_fn)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Threshold}; use rtfm::app;
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -17,38 +17,47 @@ app! {
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
priority: 1, // priority: 1,
resources: [SHARED], resources: [SHARED],
}, },
EXTI1: { exti1: {
path: exti1, interrupt: EXTI1,
priority: 2, priority: 2,
resources: [SHARED], resources: [SHARED],
}, },
}, },
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn is_send<T>(_: &T) where T: Send {} fn is_send<T>(_: &T)
fn is_sync<T>(_: &T) where T: Sync {} where
T: Send,
{
}
fn is_sync<T>(_: &T)
where
T: Sync,
{
}
fn exti0(_t: &mut Threshold, r: EXTI0::Resources) { fn exti0(ctxt: exti0::Context) {
// ERROR resource proxies can't be shared between tasks // ERROR resource proxies can't be shared between tasks
is_sync(&r.SHARED); is_sync(&ctxt.resources.SHARED);
//~^ error `*const ()` cannot be shared between threads safely //~^ error `*const ()` cannot be shared between threads safely
// ERROR resource proxies are not `Send`able across tasks // ERROR resource proxies are not `Send`able across tasks
is_send(&r.SHARED); is_send(&ctxt.resources.SHARED);
//~^ error the trait bound `*const (): core::marker::Send` is not satisfied //~^ error the trait bound `*const (): core::marker::Send` is not satisfied
} }
fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) { fn exti1(_ctxt: exti1::Context) {}
}

View file

@ -1,13 +1,13 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
#![deny(warnings)] #![deny(warnings)]
#![feature(const_fn)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource, Threshold}; use rtfm::{app, Resource};
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -17,30 +17,33 @@ app! {
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
priority: 1, // priority: 1,
resources: [STATE], resources: [STATE],
}, },
EXTI1: { exti1: {
path: exti1, interrupt: EXTI1,
priority: 2, priority: 2,
resources: [STATE], resources: [STATE],
}, },
}, },
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn exti0(mut t: &mut Threshold, r: EXTI0::Resources) { fn exti0(ctxt: exti0::Context) {
// ERROR token should not outlive the critical section // ERROR token should not outlive the critical section
let t = r.STATE.claim(&mut t, |_state, t| t); let t = &mut ctxt.threshold;
let t = ctxt.resources.STATE.claim(t, |_state, t| t);
//~^ error cannot infer an appropriate lifetime //~^ error cannot infer an appropriate lifetime
} }
fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {} fn exti1(_ctxt: exti1::Context) {}

View file

@ -5,15 +5,18 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
extern crate typenum;
use rtfm::{app, Threshold}; use rtfm::{app, Threshold};
use typenum::consts::U1;
app! { //~ error bound `*const (): core::marker::Send` is not satisfied app! { //~ error bound `*const (): core::marker::Send` is not satisfied
device: stm32f103xx, device: stm32f103xx,
resources: { resources: {
static TOKEN: Option<Threshold> = None; static TOKEN: Option<Threshold<U1>> = None;
}, },
idle: { idle: {
@ -21,17 +24,17 @@ app! { //~ error bound `*const (): core::marker::Send` is not satisfied
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
resources: [TOKEN], resources: [TOKEN],
}, },
} }
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) {}
fn idle(_t: &mut Threshold, _r: idle::Resources) -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {} fn exti0(_ctxt: exti0::Context) {}

View file

@ -4,9 +4,10 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource, Threshold}; use rtfm::{app, Resource};
app! { app! {
device: stm32f103xx, device: stm32f103xx,
@ -17,32 +18,37 @@ app! {
}, },
tasks: { tasks: {
EXTI0: { exti0: {
path: exti0, interrupt: EXTI0,
priority: 1, // priority: 1,
resources: [A, B], resources: [A, B],
}, },
EXTI1: { exti1: {
path: exti1, interrupt: EXTI1,
priority: 2, priority: 2,
resources: [A, B], resources: [A, B],
}, },
}, },
} }
fn init(_p: init::Peripherals, _r: init::Resources) {} fn init(_ctxt: init::Context) -> init::LateResources {
init::LateResources {}
}
fn idle() -> ! { fn idle(_ctxt: idle::Context) -> ! {
loop {} loop {}
} }
fn exti0(mut ot: &mut Threshold, r: EXTI0::Resources) { fn exti0(mut ctxt: exti0::Context) {
r.A.claim(&mut ot, |_a, mut _it| { let ot = &mut ctxt.threshold;
//~^ error cannot borrow `ot` as mutable more than once at a time let exti0::Resources { A, B } = ctxt.resources;
A.claim(ot, |_a, _it| {
//~^ error closure requires unique access to `ot` but `*ot` is already borrowed
// ERROR must use inner token `it` instead of the outer one (`ot`) // ERROR must use inner token `it` instead of the outer one (`ot`)
r.B.claim(&mut ot, |_b, _| {}) B.claim(ot, |_b, _| {})
}); });
} }
fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {} fn exti1(_ctxt: exti1::Context) {}