diff options
| author | Henrik Tjäder <henrik@tjaders.com> | 2023-02-04 16:47:17 +0100 |
|---|---|---|
| committer | Henrik Tjäder <henrik@tjaders.com> | 2023-03-01 00:35:13 +0100 |
| commit | 9e445b3583c15c7701f3167eaa8dfe4afd541691 (patch) | |
| tree | 167565d51598f42c0454d60b34e1170589ae1056 /rtic-macros/src/check.rs | |
| parent | 4124fbdd61ff823c6217a2a16ebb4d813146116c (diff) | |
Move rtic macros to repo root, tune xtask
Diffstat (limited to 'rtic-macros/src/check.rs')
| -rw-r--r-- | rtic-macros/src/check.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/rtic-macros/src/check.rs b/rtic-macros/src/check.rs new file mode 100644 index 0000000..a05c82e --- /dev/null +++ b/rtic-macros/src/check.rs @@ -0,0 +1,70 @@ +use std::collections::HashSet; + +use crate::syntax::ast::App; +use syn::parse; + +pub fn app(app: &App) -> parse::Result<()> { + // Check that external (device-specific) interrupts are not named after known (Cortex-M) + // exceptions + for name in app.args.dispatchers.keys() { + let name_s = name.to_string(); + + match &*name_s { + "NonMaskableInt" | "HardFault" | "MemoryManagement" | "BusFault" | "UsageFault" + | "SecureFault" | "SVCall" | "DebugMonitor" | "PendSV" | "SysTick" => { + return Err(parse::Error::new( + name.span(), + "Cortex-M exceptions can't be used as `extern` interrupts", + )); + } + + _ => {} + } + } + + // Check that there are enough external interrupts to dispatch the software tasks and the timer + // queue handler + let mut first = None; + let priorities = app + .software_tasks + .iter() + .map(|(name, task)| { + first = Some(name); + task.args.priority + }) + .filter(|prio| *prio > 0) + .collect::<HashSet<_>>(); + + let need = priorities.len(); + let given = app.args.dispatchers.len(); + if need > given { + let s = { + format!( + "not enough interrupts to dispatch \ + all software tasks (need: {need}; given: {given})" + ) + }; + + // If not enough tasks and first still is None, may cause + // "custom attribute panicked" due to unwrap on None + return Err(parse::Error::new(first.unwrap().span(), s)); + } + + // Check that all exceptions are valid; only exceptions with configurable priorities are + // accepted + for (name, task) in &app.hardware_tasks { + let name_s = task.args.binds.to_string(); + match &*name_s { + "NonMaskableInt" | "HardFault" => { + return Err(parse::Error::new( + name.span(), + "only exceptions with configurable priority can be used as hardware tasks", + )); + } + + _ => {} + } + } + + Ok(()) +} |
