rtic_macros/
analyze.rs

1use core::ops;
2use std::collections::{BTreeMap, BTreeSet};
3
4use crate::syntax::{
5    analyze::{self, Priority},
6    ast::{App, Dispatcher},
7};
8use syn::Ident;
9
10/// Extend the upstream `Analysis` struct with our field
11pub struct Analysis {
12    parent: analyze::Analysis,
13    pub interrupts: BTreeMap<Priority, (Ident, Dispatcher)>,
14    pub max_async_prio: Option<u8>,
15}
16
17impl ops::Deref for Analysis {
18    type Target = analyze::Analysis;
19
20    fn deref(&self) -> &Self::Target {
21        &self.parent
22    }
23}
24
25// Assign an interrupt to each priority level
26pub fn app(analysis: analyze::Analysis, app: &App) -> Analysis {
27    let mut available_dispatchers = app.args.dispatchers.clone();
28
29    // the set of priorities (each priority only once)
30    let priorities = app
31        .software_tasks
32        .values()
33        .map(|task| task.args.priority)
34        .collect::<BTreeSet<_>>();
35
36    // map from priorities to interrupts (holding name and attributes)
37
38    let nonzero_priorities = priorities
39        .iter()
40        // 0 prio tasks are run in main
41        .filter(|prio| **prio > 0);
42    assert!(
43        available_dispatchers.len() >= nonzero_priorities.clone().count(),
44        "The number of dispatchers must be equal to or greater than the number of distinct task priorities."
45    );
46    let interrupts: BTreeMap<Priority, _> = nonzero_priorities
47        .copied()
48        .rev()
49        .map(|p| {
50            (
51                p,
52                available_dispatchers
53                    .pop()
54                    // EXPECT: covered by above assertion
55                    .expect("UNREACHABLE"),
56            )
57        })
58        .collect();
59
60    let max_async_prio = app
61        .hardware_tasks
62        .iter()
63        .map(|(_, task)| task.args.priority)
64        .min()
65        .map(|v| v - 1); // One less than the smallest HW task
66
67    Analysis {
68        parent: analysis,
69        interrupts,
70        max_async_prio,
71    }
72}