mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-01 16:04:33 +01:00
make task.$T.enabled optional
and move the logic that differentiates interrupts from exceptions from the crate to the procedural macro logic
This commit is contained in:
parent
ad2a523cf9
commit
d396da5950
17 changed files with 112 additions and 92 deletions
|
@ -37,7 +37,9 @@ app! {
|
||||||
},
|
},
|
||||||
|
|
||||||
TIM2: {
|
TIM2: {
|
||||||
enabled: true,
|
// tasks are enabled, between `init` and `idle`, by default but they
|
||||||
|
// can start disabled if `false` is specified here
|
||||||
|
enabled: false,
|
||||||
path: tim2,
|
path: tim2,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [CO_OWNED],
|
resources: [CO_OWNED],
|
||||||
|
|
|
@ -15,14 +15,12 @@ app! {
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [GPIOA, SPI1],
|
resources: [GPIOA, SPI1],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI1: {
|
EXTI1: {
|
||||||
enabled: true,
|
|
||||||
path: exti1,
|
path: exti1,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
resources: [GPIOA, SPI1],
|
resources: [GPIOA, SPI1],
|
||||||
|
|
|
@ -31,14 +31,11 @@ app! {
|
||||||
tasks: {
|
tasks: {
|
||||||
SYS_TICK: {
|
SYS_TICK: {
|
||||||
path: tasks::sys_tick,
|
path: tasks::sys_tick,
|
||||||
priority: 1,
|
|
||||||
resources: [CO_OWNED, ON, SHARED],
|
resources: [CO_OWNED, ON, SHARED],
|
||||||
},
|
},
|
||||||
|
|
||||||
TIM2: {
|
TIM2: {
|
||||||
enabled: true,
|
|
||||||
path: tasks::tim2,
|
path: tasks::tim2,
|
||||||
priority: 1,
|
|
||||||
resources: [CO_OWNED],
|
resources: [CO_OWNED],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,21 +24,18 @@ app! {
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [LOW, HIGH],
|
resources: [LOW, HIGH],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI1: {
|
EXTI1: {
|
||||||
enabled: true,
|
|
||||||
path: exti1,
|
path: exti1,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
resources: [LOW],
|
resources: [LOW],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI2: {
|
EXTI2: {
|
||||||
enabled: true,
|
|
||||||
path: exti2,
|
path: exti2,
|
||||||
priority: 3,
|
priority: 3,
|
||||||
resources: [HIGH],
|
resources: [HIGH],
|
||||||
|
|
|
@ -25,7 +25,6 @@ app! {
|
||||||
},
|
},
|
||||||
|
|
||||||
TIM2: {
|
TIM2: {
|
||||||
enabled: true,
|
|
||||||
path: tim2,
|
path: tim2,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [COUNTER],
|
resources: [COUNTER],
|
||||||
|
|
|
@ -33,7 +33,6 @@ app! {
|
||||||
// For interrupts the `enabled` field must be specified. It
|
// For interrupts the `enabled` field must be specified. It
|
||||||
// indicates if the interrupt will be enabled or disabled once
|
// indicates if the interrupt will be enabled or disabled once
|
||||||
// `idle` starts
|
// `idle` starts
|
||||||
enabled: true,
|
|
||||||
path: tim2,
|
path: tim2,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [COUNTER],
|
resources: [COUNTER],
|
||||||
|
|
|
@ -16,8 +16,39 @@ pub struct App {
|
||||||
|
|
||||||
pub type Tasks = HashMap<Ident, Task>;
|
pub type Tasks = HashMap<Ident, Task>;
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum Exception {
|
||||||
|
PENDSV,
|
||||||
|
SVCALL,
|
||||||
|
SYS_TICK,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Exception {
|
||||||
|
pub fn from(s: &str) -> Option<Self> {
|
||||||
|
Some(match s {
|
||||||
|
"PENDSV" => Exception::PENDSV,
|
||||||
|
"SVCALL" => Exception::SVCALL,
|
||||||
|
"SYS_TICK" => Exception::SYS_TICK,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nr(&self) -> usize {
|
||||||
|
match *self {
|
||||||
|
Exception::PENDSV => 14,
|
||||||
|
Exception::SVCALL => 11,
|
||||||
|
Exception::SYS_TICK => 15,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Kind {
|
||||||
|
Exception(Exception),
|
||||||
|
Interrupt { enabled: bool },
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub enabled: Option<bool>,
|
pub kind: Kind,
|
||||||
pub path: Option<Path>,
|
pub path: Option<Path>,
|
||||||
pub priority: u8,
|
pub priority: u8,
|
||||||
pub resources: Idents,
|
pub resources: Idents,
|
||||||
|
@ -31,8 +62,13 @@ pub fn app(app: check::App) -> Result<App> {
|
||||||
resources: app.resources,
|
resources: app.resources,
|
||||||
tasks: app.tasks
|
tasks: app.tasks
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, v)| (k, ::check::task(v)))
|
.map(|(k, v)| {
|
||||||
.collect(),
|
let v = ::check::task(k.as_ref(), v)
|
||||||
|
.chain_err(|| format!("checking task `{}`", k))?;
|
||||||
|
|
||||||
|
Ok((k, v))
|
||||||
|
})
|
||||||
|
.collect::<Result<_>>()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
::check::resources(&app)
|
::check::resources(&app)
|
||||||
|
@ -60,11 +96,34 @@ fn resources(app: &App) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn task(task: syntax::check::Task) -> Task {
|
fn task(name: &str, task: syntax::check::Task) -> Result<Task> {
|
||||||
Task {
|
let kind = match Exception::from(name) {
|
||||||
enabled: task.enabled,
|
Some(e) => {
|
||||||
|
ensure!(
|
||||||
|
task.enabled.is_none(),
|
||||||
|
"`enabled` field is not valid for exceptions"
|
||||||
|
);
|
||||||
|
|
||||||
|
Kind::Exception(e)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if task.enabled == Some(true) {
|
||||||
|
bail!(
|
||||||
|
"`enabled: true` is the default value; this line can be \
|
||||||
|
omitted"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Kind::Interrupt {
|
||||||
|
enabled: task.enabled.unwrap_or(true),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Task {
|
||||||
|
kind,
|
||||||
path: task.path,
|
path: task.path,
|
||||||
priority: task.priority.unwrap_or(1),
|
priority: task.priority.unwrap_or(1),
|
||||||
resources: task.resources,
|
resources: task.resources,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use quote::{Ident, Tokens};
|
||||||
use syn::{Lit, StrStyle};
|
use syn::{Lit, StrStyle};
|
||||||
|
|
||||||
use analyze::{Ownership, Ownerships};
|
use analyze::{Ownership, Ownerships};
|
||||||
use check::App;
|
use check::{App, Kind};
|
||||||
|
|
||||||
fn krate() -> Ident {
|
fn krate() -> Ident {
|
||||||
Ident::from("rtfm")
|
Ident::from("rtfm")
|
||||||
|
@ -236,7 +236,23 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
||||||
let mut exceptions = vec![];
|
let mut exceptions = vec![];
|
||||||
let mut interrupts = vec![];
|
let mut interrupts = vec![];
|
||||||
for (name, task) in &app.tasks {
|
for (name, task) in &app.tasks {
|
||||||
if let Some(enabled) = task.enabled {
|
match task.kind {
|
||||||
|
Kind::Exception(ref e) => {
|
||||||
|
if exceptions.is_empty() {
|
||||||
|
exceptions.push(quote! {
|
||||||
|
let scb = &*#device::SCB.get();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let nr = e.nr();
|
||||||
|
let priority = task.priority;
|
||||||
|
exceptions.push(quote! {
|
||||||
|
let prio_bits = #device::NVIC_PRIO_BITS;
|
||||||
|
let hw = ((1 << prio_bits) - #priority) << (8 - prio_bits);
|
||||||
|
scb.shpr[#nr - 4].write(hw);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Kind::Interrupt { enabled } => {
|
||||||
// Interrupt. These can be enabled / disabled through the NVIC
|
// Interrupt. These can be enabled / disabled through the NVIC
|
||||||
if interrupts.is_empty() {
|
if interrupts.is_empty() {
|
||||||
interrupts.push(quote! {
|
interrupts.push(quote! {
|
||||||
|
@ -260,20 +276,7 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
|
||||||
nvic.disable(#device::Interrupt::#name);
|
nvic.disable(#device::Interrupt::#name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Exception
|
|
||||||
if exceptions.is_empty() {
|
|
||||||
exceptions.push(quote! {
|
|
||||||
let scb = &*#device::SCB.get();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let priority = task.priority;
|
|
||||||
exceptions.push(quote! {
|
|
||||||
let prio_bits = #device::NVIC_PRIO_BITS;
|
|
||||||
let hw = ((1 << prio_bits) - #priority) << (8 - prio_bits);
|
|
||||||
scb.shpr[#krate::Exception::#name.nr() - 4].write(hw);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -140,25 +140,3 @@ where
|
||||||
let nvic = unsafe { &*cortex_m::peripheral::NVIC.get() };
|
let nvic = unsafe { &*cortex_m::peripheral::NVIC.get() };
|
||||||
nvic.set_pending(interrupt);
|
nvic.set_pending(interrupt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub enum Exception {
|
|
||||||
/// System service call via SWI instruction
|
|
||||||
SVCALL,
|
|
||||||
/// Pendable request for system service
|
|
||||||
PENDSV,
|
|
||||||
/// System tick timer
|
|
||||||
SYS_TICK,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Exception {
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn nr(&self) -> usize {
|
|
||||||
match *self {
|
|
||||||
Exception::SVCALL => 11,
|
|
||||||
Exception::PENDSV => 14,
|
|
||||||
Exception::SYS_TICK => 15,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ app! {
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [ON],
|
resources: [ON],
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rtfm::app;
|
||||||
|
|
||||||
app! {
|
app! {
|
||||||
//~^ error proc macro panicked
|
//~^ error proc macro panicked
|
||||||
//~| help parsing
|
|
||||||
device: stm32f103xx,
|
device: stm32f103xx,
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
|
|
|
@ -7,9 +7,7 @@ extern crate stm32f103xx;
|
||||||
|
|
||||||
use rtfm::app;
|
use rtfm::app;
|
||||||
|
|
||||||
app! {
|
app! { //~ error proc macro panicked
|
||||||
//~^ error no associated item named `SYS_TICK` found for type
|
|
||||||
//~| error no associated item named `SYS_TICK` found for type
|
|
||||||
device: stm32f103xx,
|
device: stm32f103xx,
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
|
|
|
@ -7,14 +7,14 @@ extern crate stm32f103xx;
|
||||||
|
|
||||||
use rtfm::app;
|
use rtfm::app;
|
||||||
|
|
||||||
app! { //~ error no associated item named `EXTI0` found for type
|
app! {
|
||||||
|
//~^ error no associated item named `EXTI33` found for type
|
||||||
|
//~| error no associated item named `EXTI33` found for type
|
||||||
device: stm32f103xx,
|
device: stm32f103xx,
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
// ERROR `enabled` needs to be specified for interrupts
|
// ERROR this interrupt doesn't exist
|
||||||
EXTI0: {
|
EXTI33: {},
|
||||||
priority: 1,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,21 +18,18 @@ app! {
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [MAX, ON],
|
resources: [MAX, ON],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI1: {
|
EXTI1: {
|
||||||
enabled: true,
|
|
||||||
path: exti1,
|
path: exti1,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
resources: [ON],
|
resources: [ON],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI2: {
|
EXTI2: {
|
||||||
enabled: true,
|
|
||||||
path: exti2,
|
path: exti2,
|
||||||
priority: 16,
|
priority: 16,
|
||||||
resources: [MAX],
|
resources: [MAX],
|
||||||
|
|
|
@ -17,14 +17,12 @@ app! {
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [STATE],
|
resources: [STATE],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI1: {
|
EXTI1: {
|
||||||
enabled: true,
|
|
||||||
path: exti1,
|
path: exti1,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
resources: [STATE],
|
resources: [STATE],
|
||||||
|
|
|
@ -17,7 +17,6 @@ app! { //~ error bound `rtfm::Threshold: core::marker::Send` is not satisfied
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [TOKEN],
|
resources: [TOKEN],
|
||||||
|
|
|
@ -18,14 +18,12 @@ app! {
|
||||||
|
|
||||||
tasks: {
|
tasks: {
|
||||||
EXTI0: {
|
EXTI0: {
|
||||||
enabled: true,
|
|
||||||
path: exti0,
|
path: exti0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
resources: [A, B],
|
resources: [A, B],
|
||||||
},
|
},
|
||||||
|
|
||||||
EXTI1: {
|
EXTI1: {
|
||||||
enabled: true,
|
|
||||||
path: exti1,
|
path: exti1,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
resources: [A, B],
|
resources: [A, B],
|
||||||
|
|
Loading…
Reference in a new issue