rtic_syntax/
ast.rs

1//! Abstract Syntax Tree
2
3use syn::{Attribute, Expr, Ident, Item, ItemUse, Pat, PatType, Path, Stmt, Type};
4
5use crate::Map;
6
7/// The `#[app]` attribute
8#[derive(Debug)]
9#[non_exhaustive]
10pub struct App {
11    /// The arguments to the `#[app]` attribute
12    pub args: AppArgs,
13
14    /// The name of the `const` item on which the `#[app]` attribute has been placed
15    pub name: Ident,
16
17    /// The `#[init]` function
18    pub init: Init,
19
20    /// The `#[idle]` function
21    pub idle: Option<Idle>,
22
23    /// Monotonic clocks
24    pub monotonics: Map<Monotonic>,
25
26    /// Resources shared between tasks defined in `#[shared]`
27    pub shared_resources: Map<SharedResource>,
28
29    /// Task local resources defined in `#[local]`
30    pub local_resources: Map<LocalResource>,
31
32    /// User imports
33    pub user_imports: Vec<ItemUse>,
34
35    /// User code
36    pub user_code: Vec<Item>,
37
38    /// Hardware tasks: `#[task(binds = ..)]`s
39    pub hardware_tasks: Map<HardwareTask>,
40
41    /// Software tasks: `#[task]`
42    pub software_tasks: Map<SoftwareTask>,
43}
44
45/// Interrupts used to dispatch software tasks
46pub type ExternInterrupts = Map<ExternInterrupt>;
47
48/// Interrupt that could be used to dispatch software tasks
49#[derive(Debug, Clone)]
50#[non_exhaustive]
51pub struct ExternInterrupt {
52    /// Attributes that will apply to this interrupt handler
53    pub attrs: Vec<Attribute>,
54}
55
56/// The arguments of the `#[app]` attribute
57#[derive(Debug)]
58pub struct AppArgs {
59    /// Device
60    pub device: Option<Path>,
61
62    /// Peripherals
63    pub peripherals: bool,
64
65    /// Interrupts used to dispatch software tasks
66    pub extern_interrupts: ExternInterrupts,
67}
68
69/// The `init`-ialization function
70#[derive(Debug)]
71#[non_exhaustive]
72pub struct Init {
73    /// `init` context metadata
74    pub args: InitArgs,
75
76    /// Attributes that will apply to this `init` function
77    pub attrs: Vec<Attribute>,
78
79    /// The name of the `#[init]` function
80    pub name: Ident,
81
82    /// The context argument
83    pub context: Box<Pat>,
84
85    /// The statements that make up this `init` function
86    pub stmts: Vec<Stmt>,
87
88    /// The name of the user provided shared resources struct
89    pub user_shared_struct: Ident,
90
91    /// The name of the user provided local resources struct
92    pub user_local_struct: Ident,
93}
94
95/// `init` context metadata
96#[derive(Debug)]
97#[non_exhaustive]
98pub struct InitArgs {
99    /// Local resources that can be accessed from this context
100    pub local_resources: LocalResources,
101}
102
103impl Default for InitArgs {
104    fn default() -> Self {
105        Self {
106            local_resources: LocalResources::new(),
107        }
108    }
109}
110
111/// The `idle` context
112#[derive(Debug)]
113#[non_exhaustive]
114pub struct Idle {
115    /// `idle` context metadata
116    pub args: IdleArgs,
117
118    /// Attributes that will apply to this `idle` function
119    pub attrs: Vec<Attribute>,
120
121    /// The name of the `#[idle]` function
122    pub name: Ident,
123
124    /// The context argument
125    pub context: Box<Pat>,
126
127    /// The statements that make up this `idle` function
128    pub stmts: Vec<Stmt>,
129}
130
131/// `idle` context metadata
132#[derive(Debug)]
133#[non_exhaustive]
134pub struct IdleArgs {
135    /// Local resources that can be accessed from this context
136    pub local_resources: LocalResources,
137
138    /// Shared resources that can be accessed from this context
139    pub shared_resources: SharedResources,
140}
141
142impl Default for IdleArgs {
143    fn default() -> Self {
144        Self {
145            local_resources: LocalResources::new(),
146            shared_resources: SharedResources::new(),
147        }
148    }
149}
150
151/// Shared resource properties
152#[derive(Debug)]
153pub struct SharedResourceProperties {
154    /// A lock free (exclusive resource)
155    pub lock_free: bool,
156}
157
158/// A shared resource, defined in `#[shared]`
159#[derive(Debug)]
160#[non_exhaustive]
161pub struct SharedResource {
162    /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
163    pub cfgs: Vec<Attribute>,
164
165    /// `#[doc]` attributes like `/// this is a docstring`
166    pub docs: Vec<Attribute>,
167
168    /// Attributes that will apply to this resource
169    pub attrs: Vec<Attribute>,
170
171    /// The type of this resource
172    pub ty: Box<Type>,
173
174    /// Shared resource properties
175    pub properties: SharedResourceProperties,
176}
177
178/// A local resource, defined in `#[local]`
179#[derive(Debug)]
180#[non_exhaustive]
181pub struct LocalResource {
182    /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
183    pub cfgs: Vec<Attribute>,
184
185    /// `#[doc]` attributes like `/// this is a docstring`
186    pub docs: Vec<Attribute>,
187
188    /// Attributes that will apply to this resource
189    pub attrs: Vec<Attribute>,
190
191    /// The type of this resource
192    pub ty: Box<Type>,
193}
194
195/// Monotonic
196#[derive(Debug)]
197#[non_exhaustive]
198pub struct Monotonic {
199    /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
200    pub cfgs: Vec<Attribute>,
201
202    /// The identifier of the monotonic
203    pub ident: Ident,
204
205    /// The type of this monotonic
206    pub ty: Box<Type>,
207
208    /// Monotonic args
209    pub args: MonotonicArgs,
210}
211
212/// Monotonic metadata
213#[derive(Debug)]
214#[non_exhaustive]
215pub struct MonotonicArgs {
216    /// The interrupt or exception that this monotonic is bound to
217    pub binds: Ident,
218
219    /// The priority of this monotonic
220    pub priority: Option<u8>,
221
222    /// If this is the default monotonic
223    pub default: bool,
224}
225
226/// A software task
227#[derive(Debug)]
228#[non_exhaustive]
229pub struct SoftwareTask {
230    /// Software task metadata
231    pub args: SoftwareTaskArgs,
232
233    /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
234    pub cfgs: Vec<Attribute>,
235
236    /// Attributes that will apply to this interrupt handler
237    pub attrs: Vec<Attribute>,
238
239    /// The context argument
240    pub context: Box<Pat>,
241
242    /// The inputs of this software task
243    pub inputs: Vec<PatType>,
244
245    /// The statements that make up the task handler
246    pub stmts: Vec<Stmt>,
247
248    /// The task is declared externally
249    pub is_extern: bool,
250}
251
252/// Software task metadata
253#[derive(Debug)]
254#[non_exhaustive]
255pub struct SoftwareTaskArgs {
256    /// The task capacity: the maximum number of pending messages that can be queued
257    pub capacity: u8,
258
259    /// The priority of this task
260    pub priority: u8,
261
262    /// Local resources that can be accessed from this context
263    pub local_resources: LocalResources,
264
265    /// Shared resources that can be accessed from this context
266    pub shared_resources: SharedResources,
267}
268
269impl Default for SoftwareTaskArgs {
270    fn default() -> Self {
271        Self {
272            capacity: 1,
273            priority: 1,
274            local_resources: LocalResources::new(),
275            shared_resources: SharedResources::new(),
276        }
277    }
278}
279
280/// A hardware task
281#[derive(Debug)]
282#[non_exhaustive]
283pub struct HardwareTask {
284    /// Hardware task metadata
285    pub args: HardwareTaskArgs,
286
287    /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
288    pub cfgs: Vec<Attribute>,
289
290    /// Attributes that will apply to this interrupt handler
291    pub attrs: Vec<Attribute>,
292
293    /// The context argument
294    pub context: Box<Pat>,
295
296    /// The statements that make up the task handler
297    pub stmts: Vec<Stmt>,
298
299    /// The task is declared externally
300    pub is_extern: bool,
301}
302
303/// Hardware task metadata
304#[derive(Debug)]
305#[non_exhaustive]
306pub struct HardwareTaskArgs {
307    /// The interrupt or exception that this task is bound to
308    pub binds: Ident,
309
310    /// The priority of this task
311    pub priority: u8,
312
313    /// Local resources that can be accessed from this context
314    pub local_resources: LocalResources,
315
316    /// Shared resources that can be accessed from this context
317    pub shared_resources: SharedResources,
318}
319
320/// A `static mut` variable local to and owned by a context
321#[derive(Debug)]
322#[non_exhaustive]
323pub struct Local {
324    /// Attributes like `#[link_section]`
325    pub attrs: Vec<Attribute>,
326
327    /// `#[cfg]` attributes like `#[cfg(debug_assertions)]`
328    pub cfgs: Vec<Attribute>,
329
330    /// Type
331    pub ty: Box<Type>,
332
333    /// Initial value
334    pub expr: Box<Expr>,
335}
336
337/// A wrapper of the 2 kinds of locals that tasks can have
338#[derive(Debug)]
339#[non_exhaustive]
340pub enum TaskLocal {
341    /// The local is declared externally (i.e. `#[local]` struct)
342    External,
343    /// The local is declared in the task
344    Declared(Local),
345}
346
347/// Resource access
348#[derive(Clone, Copy, Debug, Eq, PartialEq)]
349pub enum Access {
350    /// `[x]`, a mutable resource
351    Exclusive,
352
353    /// `[&x]`, a static non-mutable resource
354    Shared,
355}
356
357impl Access {
358    /// Is this enum in the `Exclusive` variant?
359    pub fn is_exclusive(&self) -> bool {
360        *self == Access::Exclusive
361    }
362
363    /// Is this enum in the `Shared` variant?
364    pub fn is_shared(&self) -> bool {
365        *self == Access::Shared
366    }
367}
368
369/// Shared resource access list in task attribute
370pub type SharedResources = Map<Access>;
371
372/// Local resource access/declaration list in task attribute
373pub type LocalResources = Map<TaskLocal>;