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>;