more fixes

This commit is contained in:
Jorge Aparicio 2018-05-07 17:46:26 +02:00
parent cfcf25ef53
commit 0c7a0116a7
25 changed files with 227 additions and 94 deletions

View file

@ -49,6 +49,10 @@ required-features = ["timer-queue"]
name = "periodic" name = "periodic"
required-features = ["timer-queue"] required-features = ["timer-queue"]
[[example]]
name = "user-struct"
required-features = ["timer-queue"]
[dependencies] [dependencies]
cortex-m = "0.4.0" cortex-m = "0.4.0"
cortex-m-rtfm-macros = { path = "macros", version = "0.3.1" } cortex-m-rtfm-macros = { path = "macros", version = "0.3.1" }
@ -60,6 +64,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"
typenum = "1.10.0" typenum = "1.10.0"
[dev-dependencies.stm32f103xx] [dev-dependencies.stm32f103xx]

View file

@ -2,8 +2,8 @@ set -euxo pipefail
main() { main() {
if [ $TARGET = x86_64-unknown-linux-gnu ]; then if [ $TARGET = x86_64-unknown-linux-gnu ]; then
cargo build cargo build --target $TARGET
cargo test --test cfail cargo test --test cfail --target $TARGET
return return
fi fi

View file

@ -52,7 +52,7 @@ app! {
}, },
init: { init: {
async_after: [a], async: [a],
}, },
free_interrupts: [EXTI0], free_interrupts: [EXTI0],
@ -72,7 +72,7 @@ const S: u32 = 1_000 * MS;
fn init(mut ctxt: init::Context) -> init::LateResources { fn init(mut ctxt: init::Context) -> init::LateResources {
iprintln!(&mut ctxt.core.ITM.stim[0], "init"); iprintln!(&mut ctxt.core.ITM.stim[0], "init");
ctxt.async.a.post(&mut ctxt.threshold, 1 * S, ()).ok(); ctxt.async.a.post(&mut ctxt.threshold, ()).ok();
init::LateResources { ITM: ctxt.core.ITM } init::LateResources { ITM: ctxt.core.ITM }
} }

56
examples/user-struct.rs Normal file
View file

@ -0,0 +1,56 @@
#![deny(unsafe_code)]
#![deny(warnings)]
#![feature(proc_macro)]
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort;
extern crate stm32f103xx;
use cortex_m::asm;
use rtfm::app;
pub struct Foo(u32);
app! {
device: stm32f103xx,
resources: {
static FOO: Foo = Foo(0);
static BAR: Foo;
},
free_interrupts: [EXTI0],
init: {
async: [a],
async_after: [b],
},
tasks: {
a: {
input: Foo,
},
b: {
input: Foo,
},
},
}
#[inline(always)]
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

@ -14,7 +14,16 @@ pub fn app(app: &App) -> Context {
let mut free_interrupts = app.free_interrupts.iter().cloned().collect::<Vec<_>>(); let mut free_interrupts = app.free_interrupts.iter().cloned().collect::<Vec<_>>();
async.extend(&app.init.async); async.extend(&app.init.async);
async_after.extend(&app.init.async_after);
for task in &app.init.async_after {
async_after.insert(*task);
// Timer queue
if let Entry::Vacant(entry) = tq.tasks.entry(*task) {
tq.capacity += app.tasks[task].interrupt_or_capacity.right().unwrap();
entry.insert(app.tasks[task].priority);
}
}
// compute dispatchers // compute dispatchers
for (name, task) in &app.tasks { for (name, task) in &app.tasks {
@ -23,9 +32,9 @@ pub fn app(app: &App) -> Context {
triggers.insert(interrupt, (*name, task.priority)); triggers.insert(interrupt, (*name, task.priority));
} }
Either::Right(capacity) => { Either::Right(capacity) => {
let dispatcher = dispatchers.entry(task.priority).or_insert(Dispatcher::new( let dispatcher = dispatchers.entry(task.priority).or_insert_with(|| {
free_interrupts.pop().expect("not enough free interrupts"), Dispatcher::new(free_interrupts.pop().expect("not enough free interrupts"))
)); });
dispatcher.tasks.push(*name); dispatcher.tasks.push(*name);
dispatcher.capacity += capacity; dispatcher.capacity += capacity;
} }

View file

@ -274,7 +274,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
#[allow(unsafe_code)] #[allow(unsafe_code)]
#[export_name = #export_name] #[export_name = #export_name]
pub unsafe extern "C" fn #fn_name() { pub unsafe extern "C" fn #fn_name() {
let _ = #device::Interrupt::#interrupt; // verify that the interrupt exists use #device::Interrupt;
let _ = Interrupt::#interrupt; // verify that the interrupt exists
#name::HANDLER(#name::Context::new(#bl ())) #name::HANDLER(#name::Context::new(#bl ()))
} }
}); });
@ -306,13 +307,24 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
ctxt.ceilings.slot_queues().get(name).cloned() // 0 = owned by init ctxt.ceilings.slot_queues().get(name).cloned() // 0 = owned by init
.unwrap_or(0) .unwrap_or(0)
)); ));
mod_.push(quote! {
let mangled = Ident::from(format!("_ZN{}{}6BUFFERE", name.as_ref().len(), name));
// NOTE must be in the root because of `#input`
root.push(quote! {
#[allow(non_upper_case_globals)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub static mut BUFFER: [#krate::Node<#input>; #capacity] = pub static mut #mangled: [#hidden::#krate::Node<#input>; #capacity] =
unsafe { #krate::uninitialized() }; unsafe { #hidden::#krate::uninitialized() };
});
mod_.push(quote! {
pub use ::#mangled as BUFFER;
pub struct SQ { _0: () } pub struct SQ { _0: () }
#[allow(dead_code)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl SQ { impl SQ {
pub unsafe fn new() -> Self { pub unsafe fn new() -> Self {
@ -351,92 +363,101 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
let qc = Ident::from(format!("U{}", ctxt.ceilings.dispatch_queues()[&priority])); let qc = Ident::from(format!("U{}", ctxt.ceilings.dispatch_queues()[&priority]));
if cfg!(feature = "timer-queue") { if cfg!(feature = "timer-queue") {
root.push(quote! {
#[allow(dead_code)]
#[allow(unsafe_code)]
impl __async::#name {
#[inline]
pub fn post<P>(
&mut self,
t: &mut #hidden::#krate::Threshold<P>,
payload: #ty,
) -> Result<(), #ty>
where
P: #hidden::#krate::Unsigned +
#hidden::#krate::Max<#hidden::#krate::#sqc> +
#hidden::#krate::Max<#hidden::#krate::#qc>,
#hidden::#krate::Maximum<P, #hidden::#krate::#sqc>: #hidden::#krate::Unsigned,
#hidden::#krate::Maximum<P, #hidden::#krate::#qc>: #hidden::#krate::Unsigned,
{
unsafe {
use #hidden::#krate::Resource;
let slot = ::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue());
if let Some(index) = slot {
let task = ::#__priority::Task::#name;
core::ptr::write(
#name::BUFFER.get_unchecked_mut(index as usize),
#hidden::#krate::Node { baseline: self.baseline(), payload }
);
#__priority::Q::new().claim_mut(t, |q, _| {
q.split().0.enqueue_unchecked((task, index));
});
use #device::Interrupt;
#hidden::#krate::set_pending(Interrupt::#interrupt);
Ok(())
} else {
Err(payload)
}
}
}
}
});
quote! { quote! {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct #name { baseline: #krate::Instant } pub struct #name { baseline: #krate::Instant }
#[allow(dead_code)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl #name { impl #name {
pub unsafe fn new(bl: #krate::Instant) -> Self { pub unsafe fn new(bl: #krate::Instant) -> Self {
#name { baseline: bl } #name { baseline: bl }
} }
// XXX or take `self`? pub fn baseline(&self) -> #krate::Instant {
#[inline] self.baseline
pub fn post<P>(
&mut self,
t: &mut #krate::Threshold<P>,
payload: #ty,
) -> Result<(), #ty>
where
P: #krate::Unsigned +
#krate::Max<#krate::#sqc> +
#krate::Max<#krate::#qc>,
#krate::Maximum<P, #krate::#sqc>: #krate::Unsigned,
#krate::Maximum<P, #krate::#qc>: #krate::Unsigned,
{
unsafe {
let slot = ::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue());
if let Some(index) = slot {
let task = ::#__priority::Task::#name;
core::ptr::write(
::#name::BUFFER.get_unchecked_mut(index as usize),
#krate::Node { baseline: self.baseline, payload }
);
::#__priority::Q::new().claim_mut(t, |q, _| {
q.split().0.enqueue_unchecked((task, index));
});
#krate::set_pending(#device::Interrupt::#interrupt);
Ok(())
} else {
Err(payload)
}
}
} }
} }
} }
} else { } else {
quote! { root.push(quote! {
#[allow(non_camel_case_types)] #[allow(dead_code)]
pub struct #name {}
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl #name { impl __async::#name {
pub unsafe fn new() -> Self {
#name {}
}
// XXX or take `self`?
#[inline] #[inline]
pub fn post<P>( pub fn post<P>(
&mut self, &mut self,
t: &mut #krate::Threshold<P>, t: &mut #hidden::#krate::Threshold<P>,
payload: #ty, payload: #ty,
) -> Result<(), #ty> ) -> Result<(), #ty>
where where
P: #krate::Unsigned + P: #hidden::#krate::Unsigned +
#krate::Max<#krate::#sqc> + #hidden::#krate::Max<#hidden::#krate::#sqc> +
#krate::Max<#krate::#qc>, #hidden::#krate::Max<#hidden::#krate::#qc>,
#krate::Maximum<P, #krate::#sqc>: #krate::Unsigned, #hidden::#krate::Maximum<P, #hidden::#krate::#sqc>: #hidden::#krate::Unsigned,
#krate::Maximum<P, #krate::#qc>: #krate::Unsigned, #hidden::#krate::Maximum<P, #hidden::#krate::#qc>: #hidden::#krate::Unsigned,
{ {
unsafe { unsafe {
use #hidden::#krate::Resource;
if let Some(index) = if let Some(index) =
::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()) { ::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()) {
let task = ::#__priority::Task::#name; let task = ::#__priority::Task::#name;
core::ptr::write( core::ptr::write(
::#name::BUFFER.get_unchecked_mut(index as usize), ::#name::BUFFER.get_unchecked_mut(index as usize),
#krate::Node { payload } #hidden::#krate::Node { payload }
); );
::#__priority::Q::new().claim_mut(t, |q, _| { ::#__priority::Q::new().claim_mut(t, |q, _| {
q.split().0.enqueue_unchecked((task, index)); q.split().0.enqueue_unchecked((task, index));
}); });
#krate::set_pending(#device::Interrupt::#interrupt); use #device::Interrupt;
#hidden::#krate::set_pending(Interrupt::#interrupt);
Ok(()) Ok(())
} else { } else {
@ -445,6 +466,19 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
} }
} }
} }
});
quote! {
#[allow(non_camel_case_types)]
pub struct #name {}
#[allow(dead_code)]
#[allow(unsafe_code)]
impl #name {
pub unsafe fn new() -> Self {
#name {}
}
}
} }
} }
}) })
@ -467,44 +501,43 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
let task = &app.tasks[name]; let task = &app.tasks[name];
let ty = &task.input; let ty = &task.input;
let sqc = Ident::from(format!("U{}", ctxt.ceilings.slot_queues()[name])); let sqc = Ident::from(format!(
"U{}",
ctxt.ceilings.slot_queues().get(name).unwrap_or(&0) // 0 = owned by init
));
let tqc = Ident::from(format!("U{}", ctxt.ceilings.timer_queue())); let tqc = Ident::from(format!("U{}", ctxt.ceilings.timer_queue()));
quote! { // NOTE needs to be in the root because of `#ty`
#[allow(non_camel_case_types)] root.push(quote! {
pub struct #name { baseline: #krate::Instant } #[allow(dead_code)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl #name { impl __async_after::#name {
pub unsafe fn new(bl: #krate::Instant) -> Self {
#name { baseline: bl }
}
// XXX or take `self`?
#[inline] #[inline]
pub fn post<P>( pub fn post<P>(
&self, &self,
t: &mut #krate::Threshold<P>, t: &mut #hidden::#krate::Threshold<P>,
after: u32, after: u32,
payload: #ty, payload: #ty,
) -> Result<(), #ty> ) -> Result<(), #ty>
where where
P: #krate::Unsigned + P: #hidden::#krate::Unsigned +
#krate::Max<#krate::#sqc> + #hidden::#krate::Max<#hidden::#krate::#sqc> +
#krate::Max<#krate::#tqc>, #hidden::#krate::Max<#hidden::#krate::#tqc>,
#krate::Maximum<P, #krate::#sqc>: #krate::Unsigned, #hidden::#krate::Maximum<P, #hidden::#krate::#sqc>: #hidden::#krate::Unsigned,
#krate::Maximum<P, #krate::#tqc>: #krate::Unsigned, #hidden::#krate::Maximum<P, #hidden::#krate::#tqc>: #hidden::#krate::Unsigned,
{ {
unsafe { unsafe {
use #hidden::#krate::Resource;
if let Some(index) = if let Some(index) =
::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()) { ::#name::SQ::new().claim_mut(t, |sq, _| sq.dequeue()) {
let bl = self.baseline + after; let bl = self.baseline() + after;
let task = ::__tq::Task::#name; let task = ::__tq::Task::#name;
core::ptr::write( core::ptr::write(
::#name::BUFFER.get_unchecked_mut(index as usize), ::#name::BUFFER.get_unchecked_mut(index as usize),
#krate::Node { baseline: bl, payload }, #hidden::#krate::Node { baseline: bl, payload },
); );
let m = #krate::Message { let m = #hidden::#krate::Message {
baseline: bl, baseline: bl,
index, index,
task, task,
@ -519,6 +552,23 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
} }
} }
} }
});
quote! {
#[allow(non_camel_case_types)]
pub struct #name { baseline: #krate::Instant }
#[allow(dead_code)]
#[allow(unsafe_code)]
impl #name {
pub unsafe fn new(bl: #krate::Instant) -> Self {
#name { baseline: bl }
}
pub fn baseline(&self) -> #krate::Instant {
self.baseline
}
}
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -549,7 +599,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
#__priority::Q::new().claim_mut(t, |q, _| { #__priority::Q::new().claim_mut(t, |q, _| {
q.split().0.enqueue_unchecked((#__priority::Task::#name, index)) q.split().0.enqueue_unchecked((#__priority::Task::#name, index))
}); });
#hidden::#krate::set_pending(#device::Interrupt::#interrupt); use #device::Interrupt;
#hidden::#krate::set_pending(Interrupt::#interrupt);
} }
} }
}) })
@ -588,6 +639,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
pub type Priority = #krate::#priority; pub type Priority = #krate::#priority;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(dead_code)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum Task { #(#tasks,)* } pub enum Task { #(#tasks,)* }
} }
@ -646,6 +698,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(dead_code)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum Task { #(#tasks,)* } pub enum Task { #(#tasks,)* }
} }
@ -819,6 +872,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
pub use ::#device::Peripherals as Device; pub use ::#device::Peripherals as Device;
pub use ::_ZN4init13LateResourcesE as LateResources; pub use ::_ZN4init13LateResourcesE as LateResources;
#[allow(dead_code)]
pub struct Context { pub struct Context {
pub async: Async, pub async: Async,
#baseline_field #baseline_field
@ -890,7 +944,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
let interrupt = dispatcher.interrupt(); let interrupt = dispatcher.interrupt();
post_init.push(quote! { post_init.push(quote! {
let priority = ((1 << #prio_bits) - #priority) << (8 - #prio_bits); let priority = ((1 << #prio_bits) - #priority) << (8 - #prio_bits);
_nvic.set_priority(#device::Interrupt::#interrupt, priority); _nvic.set_priority(Interrupt::#interrupt, priority);
}); });
} }
@ -898,7 +952,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
for (interrupt, (_, priority)) in &ctxt.triggers { for (interrupt, (_, priority)) in &ctxt.triggers {
post_init.push(quote! { post_init.push(quote! {
let priority = ((1 << #prio_bits) - #priority) << (8 - #prio_bits); let priority = ((1 << #prio_bits) - #priority) << (8 - #prio_bits);
_nvic.set_priority(#device::Interrupt::#interrupt, priority); _nvic.set_priority(Interrupt::#interrupt, priority);
}); });
} }
@ -906,14 +960,14 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
for dispatcher in ctxt.dispatchers.values() { for dispatcher in ctxt.dispatchers.values() {
let interrupt = dispatcher.interrupt(); let interrupt = dispatcher.interrupt();
post_init.push(quote! { post_init.push(quote! {
_nvic.enable(#device::Interrupt::#interrupt); _nvic.enable(Interrupt::#interrupt);
}); });
} }
// Enable triggers // Enable triggers
for interrupt in ctxt.triggers.keys() { for interrupt in ctxt.triggers.keys() {
post_init.push(quote! { post_init.push(quote! {
_nvic.enable(#device::Interrupt::#interrupt); _nvic.enable(Interrupt::#interrupt);
}); });
} }
@ -951,6 +1005,7 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
#[allow(unused_imports)] #[allow(unused_imports)]
use self::#krate::Resource; use self::#krate::Resource;
#[allow(dead_code)]
pub struct Context { pub struct Context {
pub resources: Resources, pub resources: Resources,
pub threshold: #krate::Threshold<#krate::U0>, pub threshold: #krate::Threshold<#krate::U0>,
@ -991,6 +1046,8 @@ pub fn app(ctxt: &Context, app: &App) -> Tokens {
fn main() { fn main() {
#[allow(unused_imports)] #[allow(unused_imports)]
use #hidden::#krate::Resource; use #hidden::#krate::Resource;
#[allow(unused_imports)]
use #device::Interrupt;
#[allow(unused_mut)] #[allow(unused_mut)]
unsafe { unsafe {

View file

@ -99,6 +99,7 @@ where
Some((m.task, m.index)) Some((m.task, m.index))
} else { } else {
// set a new timeout
const MAX: u32 = 0x00ffffff; const MAX: u32 = 0x00ffffff;
tq.syst.set_reload(cmp::min(MAX, diff as u32)); tq.syst.set_reload(cmp::min(MAX, diff as u32));

View file

@ -10,8 +10,12 @@ fn cfail() {
let mut config = Config::default(); let mut config = Config::default();
config.mode = Mode::CompileFail; config.mode = Mode::CompileFail;
config.src_base = PathBuf::from(format!("tests/cfail")); config.src_base = PathBuf::from(format!("tests/cfail"));
config.target = "x86_64-unknown-linux-gnu".to_owned();
config.target_rustcflags = config.target_rustcflags =
Some("-C panic=abort -L target/debug -L target/debug/deps ".to_string()); Some("-C panic=abort \
-L target/debug/deps \
-L target/x86_64-unknown-linux-gnu/debug \
-L target/x86_64-unknown-linux-gnu/debug/deps ".to_string());
compiletest::run_tests(&config); compiletest::run_tests(&config);
} }

View file

@ -5,7 +5,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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource}; use rtfm::{app, Resource};

View file

@ -14,7 +14,7 @@ app! { //~ error proc macro panicked
tasks: { tasks: {
a: { a: {
interrupt: EXTI0, //~ error this interrupt is already bound to another task interrupt: EXTI0, //~ error this interrupt is already bound to another task
priority: 1, // priority: 1,
}, },
b: { b: {

View file

@ -4,13 +4,13 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error proc macro panicked app! { //~ no variant named `SYS_TICK` found for type `stm32f103xx::Interrupt`
device: stm32f103xx, //~ no variant named `SYS_TICK` found for type `stm32f103xx::Interrupt` device: stm32f103xx,
tasks: { tasks: {
sys_tick: { sys_tick: {

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -3,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -4,13 +4,14 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { //~ error incorrect number of function parameters app! { //~ error mismatched types
//~^ note expected type `fn(init::Context) -> _ZN4init13LateResourcesE` //~^ incorrect number of function parameters
//~| note expected type `fn(init::Context) -> _ZN4init13LateResourcesE`
device: stm32f103xx, device: stm32f103xx,
} }

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -5,7 +5,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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource}; use rtfm::{app, Resource};

View file

@ -2,7 +2,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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -4,12 +4,12 @@
#![no_std] #![no_std]
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate panic_abort; extern crate panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;
app! { app! { //~ error proc macro panicked
device: stm32f103xx, device: stm32f103xx,
tasks: { tasks: {

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::app; use rtfm::app;

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource}; use rtfm::{app, Resource};

View file

@ -5,7 +5,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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
extern crate typenum; extern crate typenum;

View file

@ -4,7 +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 panic_itm;
extern crate stm32f103xx; extern crate stm32f103xx;
use rtfm::{app, Resource}; use rtfm::{app, Resource};