rtic_macros/codegen/
hardware_tasks.rs
1use crate::syntax::{ast::App, Context};
2use crate::{
3 analyze::Analysis,
4 codegen::{
5 bindings::{interrupt_entry, interrupt_exit, handler_config},
6 local_resources_struct, module, shared_resources_struct,
7 },
8};
9use proc_macro2::TokenStream as TokenStream2;
10use quote::quote;
11
12pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
14 let mut mod_app = vec![];
15 let mut root = vec![];
16 let mut user_tasks = vec![];
17
18 for (name, task) in &app.hardware_tasks {
19 let symbol = task.args.binds.clone();
20 let priority = task.args.priority;
21 let cfgs = &task.cfgs;
22 let attrs = &task.attrs;
23 let entry_stmts = interrupt_entry(app, analysis);
24 let exit_stmts = interrupt_exit(app, analysis);
25 let config = handler_config(app, analysis, symbol.clone());
26
27 mod_app.push(quote!(
28 #[allow(non_snake_case)]
29 #[no_mangle]
30 #(#attrs)*
31 #(#cfgs)*
32 #(#config)*
33 unsafe fn #symbol() {
34 #(#entry_stmts)*
35
36 const PRIORITY: u8 = #priority;
37
38 rtic::export::run(PRIORITY, || {
39 #name(
40 #name::Context::new()
41 )
42 });
43
44 #(#exit_stmts)*
45 }
46 ));
47
48 if !task.args.local_resources.is_empty() {
50 let (item, constructor) =
51 local_resources_struct::codegen(Context::HardwareTask(name), app);
52
53 root.push(item);
54
55 mod_app.push(constructor);
56 }
57
58 if !task.args.shared_resources.is_empty() {
60 let (item, constructor) =
61 shared_resources_struct::codegen(Context::HardwareTask(name), app);
62
63 root.push(item);
64
65 mod_app.push(constructor);
66 }
67
68 root.push(module::codegen(Context::HardwareTask(name), app, analysis));
71
72 if !task.is_extern {
75 let attrs = &task.attrs;
76 let context = &task.context;
77 let stmts = &task.stmts;
78 user_tasks.push(quote!(
79 #(#attrs)*
80 #[allow(non_snake_case)]
81 fn #name(#context: #name::Context) {
82 use rtic::Mutex as _;
83 use rtic::mutex::prelude::*;
84
85 #(#stmts)*
86 }
87 ));
88 }
89 }
90
91 quote!(
92 #(#mod_app)*
93
94 #(#root)*
95
96 #(#user_tasks)*
97 )
98}