cortex_m_rtic_macros/codegen/
idle.rs

1use proc_macro2::TokenStream as TokenStream2;
2use quote::quote;
3use rtic_syntax::{ast::App, Context};
4
5use crate::{
6    analyze::Analysis,
7    check::Extra,
8    codegen::{local_resources_struct, module, shared_resources_struct},
9};
10
11/// Generates support code for `#[idle]` functions
12pub fn codegen(
13    app: &App,
14    analysis: &Analysis,
15    extra: &Extra,
16) -> (
17    // mod_app_idle -- the `${idle}Resources` constructor
18    Vec<TokenStream2>,
19    // root_idle -- items that must be placed in the root of the crate:
20    // - the `${idle}Locals` struct
21    // - the `${idle}Resources` struct
22    // - the `${idle}` module, which contains types like `${idle}::Context`
23    Vec<TokenStream2>,
24    // user_idle
25    Option<TokenStream2>,
26    // call_idle
27    TokenStream2,
28) {
29    if let Some(idle) = &app.idle {
30        let mut shared_needs_lt = false;
31        let mut local_needs_lt = false;
32        let mut mod_app = vec![];
33        let mut root_idle = vec![];
34
35        let name = &idle.name;
36
37        if !idle.args.shared_resources.is_empty() {
38            let (item, constructor) =
39                shared_resources_struct::codegen(Context::Idle, &mut shared_needs_lt, app);
40
41            root_idle.push(item);
42            mod_app.push(constructor);
43        }
44
45        if !idle.args.local_resources.is_empty() {
46            let (item, constructor) =
47                local_resources_struct::codegen(Context::Idle, &mut local_needs_lt, app);
48
49            root_idle.push(item);
50
51            mod_app.push(constructor);
52        }
53
54        root_idle.push(module::codegen(
55            Context::Idle,
56            shared_needs_lt,
57            local_needs_lt,
58            app,
59            analysis,
60            extra,
61        ));
62        let idle_doc = " User provided idle function".to_string();
63
64        let attrs = &idle.attrs;
65        let context = &idle.context;
66        let stmts = &idle.stmts;
67        let user_idle = Some(quote!(
68            #(#attrs)*
69            #[doc = #idle_doc]
70            #[allow(non_snake_case)]
71            fn #name(#context: #name::Context) -> ! {
72                use rtic::Mutex as _;
73                use rtic::mutex::prelude::*;
74
75                #(#stmts)*
76            }
77        ));
78
79        let call_idle = quote!(#name(
80            #name::Context::new(&rtic::export::Priority::new(0))
81        ));
82
83        (mod_app, root_idle, user_idle, call_idle)
84    } else {
85        (
86            vec![],
87            vec![],
88            None,
89            quote!(loop {
90                rtic::export::nop()
91            }),
92        )
93    }
94}