2017-07-15 01:54:54 +02:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2017-07-18 23:49:59 +02:00
|
|
|
use syn::{Ident, Path};
|
2018-04-08 18:23:27 +02:00
|
|
|
use syntax::check::{self, Idents, Idle, Init, Statics};
|
|
|
|
use syntax::{self, Result};
|
2017-07-15 01:54:54 +02:00
|
|
|
|
|
|
|
pub struct App {
|
2017-07-18 23:49:59 +02:00
|
|
|
pub device: Path,
|
2017-07-15 01:54:54 +02:00
|
|
|
pub idle: Idle,
|
|
|
|
pub init: Init,
|
|
|
|
pub resources: Statics,
|
|
|
|
pub tasks: Tasks,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type Tasks = HashMap<Ident, Task>;
|
|
|
|
|
2017-07-28 00:08:42 +02:00
|
|
|
#[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 },
|
|
|
|
}
|
|
|
|
|
2017-07-15 01:54:54 +02:00
|
|
|
pub struct Task {
|
2017-07-28 00:08:42 +02:00
|
|
|
pub kind: Kind,
|
2017-07-28 02:39:18 +02:00
|
|
|
pub path: Path,
|
2017-07-15 01:54:54 +02:00
|
|
|
pub priority: u8,
|
2018-04-08 18:23:27 +02:00
|
|
|
pub resources: Idents,
|
2017-07-15 01:54:54 +02:00
|
|
|
}
|
|
|
|
|
2017-07-15 03:47:06 +02:00
|
|
|
pub fn app(app: check::App) -> Result<App> {
|
2017-07-15 01:54:54 +02:00
|
|
|
let app = App {
|
|
|
|
device: app.device,
|
|
|
|
idle: app.idle,
|
|
|
|
init: app.init,
|
|
|
|
resources: app.resources,
|
2017-07-15 03:47:06 +02:00
|
|
|
tasks: app.tasks
|
|
|
|
.into_iter()
|
2017-07-28 00:08:42 +02:00
|
|
|
.map(|(k, v)| {
|
2018-04-08 18:23:27 +02:00
|
|
|
let v = ::check::task(k.as_ref(), v)?;
|
2017-07-28 00:08:42 +02:00
|
|
|
|
|
|
|
Ok((k, v))
|
|
|
|
})
|
|
|
|
.collect::<Result<_>>()?,
|
2017-07-15 01:54:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(app)
|
|
|
|
}
|
|
|
|
|
2017-07-28 00:08:42 +02:00
|
|
|
fn task(name: &str, task: syntax::check::Task) -> Result<Task> {
|
|
|
|
let kind = match Exception::from(name) {
|
|
|
|
Some(e) => {
|
|
|
|
ensure!(
|
|
|
|
task.enabled.is_none(),
|
|
|
|
"`enabled` field is not valid for exceptions"
|
|
|
|
);
|
|
|
|
|
|
|
|
Kind::Exception(e)
|
|
|
|
}
|
2018-04-08 18:23:27 +02:00
|
|
|
None => Kind::Interrupt {
|
|
|
|
enabled: task.enabled.unwrap_or(true),
|
|
|
|
},
|
2017-07-28 00:08:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Task {
|
|
|
|
kind,
|
2018-04-08 18:23:27 +02:00
|
|
|
path: task.path,
|
2017-07-27 19:11:22 +02:00
|
|
|
priority: task.priority.unwrap_or(1),
|
|
|
|
resources: task.resources,
|
2017-07-28 00:08:42 +02:00
|
|
|
})
|
2017-07-04 18:26:11 +02:00
|
|
|
}
|