mpfs_hal_procmacros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemFn};
4
5//-------------------------------------------------------------
6// (Non-embassy) Entry point macros
7/*
8Macro usage:
9#[hart1_main]
10fn hart1_main() {
11    <main_body>
12}
13
14Expands to:
15#[no_mangle]
16pub fn __hart1_entry() {
17    <main_body>
18}
19*/
20
21#[proc_macro_attribute]
22pub fn hart1_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
23    let input_fn = parse_macro_input!(item as ItemFn);
24    let fn_body = &input_fn.block;
25
26    let expanded = quote! {
27        #[no_mangle]
28        pub fn __hart1_entry() {
29            #fn_body
30        }
31    };
32
33    expanded.into()
34}
35
36#[proc_macro_attribute]
37pub fn hart2_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
38    let input_fn = parse_macro_input!(item as ItemFn);
39    let fn_body = &input_fn.block;
40
41    let expanded = quote! {
42        #[no_mangle]
43        pub fn __hart2_entry() {
44            #fn_body
45        }
46    };
47
48    expanded.into()
49}
50
51#[proc_macro_attribute]
52pub fn hart3_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
53    let input_fn = parse_macro_input!(item as ItemFn);
54    let fn_body = &input_fn.block;
55
56    let expanded = quote! {
57        #[no_mangle]
58        pub fn __hart3_entry() {
59            #fn_body
60        }
61    };
62
63    expanded.into()
64}
65
66#[proc_macro_attribute]
67pub fn hart4_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
68    let input_fn = parse_macro_input!(item as ItemFn);
69    let fn_body = &input_fn.block;
70
71    let expanded = quote! {
72        #[no_mangle]
73        pub fn __hart4_entry() {
74            #fn_body
75        }
76    };
77
78    expanded.into()
79}
80
81#[proc_macro_attribute]
82pub fn init_once(_attr: TokenStream, item: TokenStream) -> TokenStream {
83    let input_fn = parse_macro_input!(item as ItemFn);
84    let fn_body = &input_fn.block;
85    let expanded = quote! {
86        #[no_mangle]
87        pub fn __init_once() {
88            #fn_body
89        }
90    };
91
92    expanded.into()
93}
94
95//-------------------------------------------------------------
96// Embassy macros
97/*
98// Macro usage:
99#[embassy_hart1_main]
100async fn hart1_main(_spawner: embassy_executor::Spawner) {
101    <task_body>
102}
103
104
105 // Expands to:
106#[no_mangle]
107fn __hart1_entry() {
108    static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
109    EXECUTOR1.init(Executor::new()).run(|spawner| {
110        spawner.must_spawn(hart1_main(spawner));
111    });
112}
113
114#[embassy_executor::task]
115async fn hart1_main(_spawner: embassy_executor::Spawner) {
116    <task_body>
117}
118 */
119
120#[cfg(feature = "embassy")]
121#[proc_macro_attribute]
122pub fn embassy_hart1_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
123    // Parse the input function
124    let input_fn = parse_macro_input!(item as ItemFn);
125
126    // Extract the original function name and body
127    let fn_name = &input_fn.sig.ident;
128    let fn_body = &input_fn.block;
129    let fn_inputs = &input_fn.sig.inputs;
130
131    // Generate the expanded code
132    let expanded = quote! {
133        #[no_mangle]
134        fn __hart1_entry() {
135            static EXECUTOR1: ::mpfs_hal_embassy::static_cell::StaticCell<::mpfs_hal_embassy::Executor> =
136                ::mpfs_hal_embassy::static_cell::StaticCell::new();
137
138            EXECUTOR1
139                .init(::mpfs_hal_embassy::Executor::new())
140                .run(|spawner| {
141                    spawner.must_spawn(#fn_name(spawner));
142                });
143        }
144
145        #[::embassy_executor::task]
146        async fn #fn_name(#fn_inputs) #fn_body
147    };
148
149    expanded.into()
150}
151
152#[cfg(feature = "embassy")]
153#[proc_macro_attribute]
154pub fn embassy_hart2_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
155    // Parse the input function
156    let input_fn = parse_macro_input!(item as ItemFn);
157
158    // Extract the original function name and body
159    let fn_name = &input_fn.sig.ident;
160    let fn_body = &input_fn.block;
161    let fn_inputs = &input_fn.sig.inputs;
162
163    // Generate the expanded code
164    let expanded = quote! {
165        #[no_mangle]
166        fn __hart2_entry() {
167            static EXECUTOR1: ::mpfs_hal_embassy::static_cell::StaticCell<::mpfs_hal_embassy::Executor> =
168                ::mpfs_hal_embassy::static_cell::StaticCell::new();
169
170            EXECUTOR1
171                .init(::mpfs_hal_embassy::Executor::new())
172                .run(|spawner| {
173                    spawner.must_spawn(#fn_name(spawner));
174                });
175        }
176
177        #[::embassy_executor::task]
178        async fn #fn_name(#fn_inputs) #fn_body
179    };
180
181    expanded.into()
182}
183
184#[cfg(feature = "embassy")]
185#[proc_macro_attribute]
186pub fn embassy_hart3_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
187    // Parse the input function
188    let input_fn = parse_macro_input!(item as ItemFn);
189
190    // Extract the original function name and body
191    let fn_name = &input_fn.sig.ident;
192    let fn_body = &input_fn.block;
193    let fn_inputs = &input_fn.sig.inputs;
194
195    // Generate the expanded code
196    let expanded = quote! {
197        #[no_mangle]
198        fn __hart3_entry() {
199            static EXECUTOR1: ::mpfs_hal_embassy::static_cell::StaticCell<::mpfs_hal_embassy::Executor> =
200                ::mpfs_hal_embassy::static_cell::StaticCell::new();
201
202            EXECUTOR1
203                .init(::mpfs_hal_embassy::Executor::new())
204                .run(|spawner| {
205                    spawner.must_spawn(#fn_name(spawner));
206                });
207        }
208
209        #[::embassy_executor::task]
210        async fn #fn_name(#fn_inputs) #fn_body
211    };
212
213    expanded.into()
214}
215
216#[cfg(feature = "embassy")]
217#[proc_macro_attribute]
218pub fn embassy_hart4_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
219    // Parse the input function
220    let input_fn = parse_macro_input!(item as ItemFn);
221
222    // Extract the original function name and body
223    let fn_name = &input_fn.sig.ident;
224    let fn_body = &input_fn.block;
225    let fn_inputs = &input_fn.sig.inputs;
226
227    // Generate the expanded code
228    let expanded = quote! {
229        #[no_mangle]
230        fn __hart4_entry() {
231            static EXECUTOR1: ::mpfs_hal_embassy::static_cell::StaticCell<::mpfs_hal_embassy::Executor> =
232                ::mpfs_hal_embassy::static_cell::StaticCell::new();
233
234            EXECUTOR1
235                .init(::mpfs_hal_embassy::Executor::new())
236                .run(|spawner| {
237                    spawner.must_spawn(#fn_name(spawner));
238                });
239        }
240
241        #[::embassy_executor::task]
242        async fn #fn_name(#fn_inputs) #fn_body
243    };
244
245    expanded.into()
246}