lpc55_rtic_macros/codegen/
resources.rs1use proc_macro2::TokenStream as TokenStream2;
2use quote::quote;
3use rtic_syntax::{
4 analyze::{Location, Ownership},
5 ast::App,
6};
7
8use crate::{analyze::Analysis, check::Extra, codegen::util};
9
10pub fn codegen(
12 app: &App,
13 analysis: &Analysis,
14 extra: &Extra,
15) -> (
16 Vec<TokenStream2>,
18 TokenStream2,
20) {
21 let mut const_app = vec![];
22 let mut mod_resources = vec![];
23
24 for (name, res, expr, loc) in app.resources(analysis) {
25 let cfgs = &res.cfgs;
26 let ty = &res.ty;
27
28 {
29 let (loc_attr, section) = match loc {
30 Location::Owned {
31 core,
32 cross_initialized: false,
33 } => (
34 util::cfg_core(*core, app.args.cores),
35 if expr.is_none() {
36 util::link_section_uninit(Some(*core))
37 } else {
38 util::link_section("data", *core)
39 },
40 ),
41
42 _ => (
44 if cfg!(feature = "heterogeneous") {
45 Some(quote!(#[rtic::export::shared]))
46 } else {
47 None
48 },
49 if expr.is_none() {
50 util::link_section_uninit(None)
51 } else {
52 None
53 },
54 ),
55 };
56
57 let (ty, expr) = if let Some(expr) = expr {
58 (quote!(#ty), quote!(#expr))
59 } else {
60 (
61 quote!(core::mem::MaybeUninit<#ty>),
62 quote!(core::mem::MaybeUninit::uninit()),
63 )
64 };
65
66 let attrs = &res.attrs;
67 const_app.push(quote!(
68 #[allow(non_upper_case_globals)]
69 #(#attrs)*
70 #(#cfgs)*
71 #loc_attr
72 #section
73 static mut #name: #ty = #expr;
74 ));
75 }
76
77 if let Some(Ownership::Contended { ceiling }) = analysis.ownerships.get(name) {
78 let cfg_core = util::cfg_core(loc.core().expect("UNREACHABLE"), app.args.cores);
79
80 mod_resources.push(quote!(
81 #[allow(non_camel_case_types)]
82 #(#cfgs)*
83 #cfg_core
84 pub struct #name<'a> {
85 priority: &'a Priority,
86 }
87
88 #(#cfgs)*
89 #cfg_core
90 impl<'a> #name<'a> {
91 #[inline(always)]
92 pub unsafe fn new(priority: &'a Priority) -> Self {
93 #name { priority }
94 }
95
96 #[inline(always)]
97 pub unsafe fn priority(&self) -> &Priority {
98 self.priority
99 }
100 }
101 ));
102
103 let ptr = if expr.is_none() {
104 quote!(
105 #(#cfgs)*
106 #name.as_mut_ptr()
107 )
108 } else {
109 quote!(
110 #(#cfgs)*
111 &mut #name
112 )
113 };
114
115 const_app.push(util::impl_mutex(
116 extra,
117 cfgs,
118 cfg_core.as_ref(),
119 true,
120 name,
121 quote!(#ty),
122 *ceiling,
123 ptr,
124 ));
125 }
126 }
127
128 let mod_resources = if mod_resources.is_empty() {
129 quote!()
130 } else {
131 quote!(mod resources {
132 use rtic::export::Priority;
133
134 #(#mod_resources)*
135 })
136 };
137
138 (const_app, mod_resources)
139}