1#![doc = include_str!("../README.md")]
2extern crate proc_macro;
3
4use proc_macro::TokenStream;
5
6mod macros;
7mod util;
8use macros::*;
9
10/// Declares an async task that can be run by `embassy-executor`. The optional `pool_size` parameter can be used to specify how
11/// many concurrent tasks can be spawned (default is 1) for the function.
12///
13///
14/// The following restrictions apply:
15///
16/// * The function must be declared `async`.
17/// * The function must not use generics.
18/// * The optional `pool_size` attribute must be 1 or greater.
19///
20///
21/// ## Examples
22///
23/// Declaring a task taking no arguments:
24///
25/// ``` rust
26/// #[embassy_executor::task]
27/// async fn mytask() {
28/// // Function body
29/// }
30/// ```
31///
32/// Declaring a task with a given pool size:
33///
34/// ``` rust
35/// #[embassy_executor::task(pool_size = 4)]
36/// async fn mytask() {
37/// // Function body
38/// }
39/// ```
40#[proc_macro_attribute]
41pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
42 task::run(args.into(), item.into()).into()
43}
44
45#[proc_macro_attribute]
46pub fn main_avr(args: TokenStream, item: TokenStream) -> TokenStream {
47 main::run(args.into(), item.into(), &main::ARCH_AVR).into()
48}
49
50/// Creates a new `executor` instance and declares an application entry point for Cortex-M spawning the corresponding function body as an async task.
51///
52/// The following restrictions apply:
53///
54/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
55/// * The function must be declared `async`.
56/// * The function must not use generics.
57/// * Only a single `main` task may be declared.
58///
59/// ## Examples
60/// Spawning a task:
61///
62/// ``` rust
63/// #[embassy_executor::main]
64/// async fn main(_s: embassy_executor::Spawner) {
65/// // Function body
66/// }
67/// ```
68#[proc_macro_attribute]
69pub fn main_cortex_m(args: TokenStream, item: TokenStream) -> TokenStream {
70 main::run(args.into(), item.into(), &main::ARCH_CORTEX_M).into()
71}
72
73/// Creates a new `executor` instance and declares an architecture agnostic application entry point spawning
74/// the corresponding function body as an async task.
75///
76/// The following restrictions apply:
77///
78/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
79/// * The function must be declared `async`.
80/// * The function must not use generics.
81/// * Only a single `main` task may be declared.
82///
83/// A user-defined entry macro must provided via the `entry` argument
84///
85/// ## Examples
86/// Spawning a task:
87/// ``` rust
88/// #[embassy_executor::main(entry = "qingke_rt::entry")]
89/// async fn main(_s: embassy_executor::Spawner) {
90/// // Function body
91/// }
92/// ```
93#[proc_macro_attribute]
94pub fn main_spin(args: TokenStream, item: TokenStream) -> TokenStream {
95 main::run(args.into(), item.into(), &main::ARCH_SPIN).into()
96}
97
98/// Creates a new `executor` instance and declares an application entry point for RISC-V spawning the corresponding function body as an async task.
99///
100/// The following restrictions apply:
101///
102/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
103/// * The function must be declared `async`.
104/// * The function must not use generics.
105/// * Only a single `main` task may be declared.
106///
107/// A user-defined entry macro can be optionally provided via the `entry` argument to override the default of `riscv_rt::entry`.
108///
109/// ## Examples
110/// Spawning a task:
111///
112/// ``` rust
113/// #[embassy_executor::main]
114/// async fn main(_s: embassy_executor::Spawner) {
115/// // Function body
116/// }
117/// ```
118///
119/// Spawning a task using a custom entry macro:
120/// ``` rust
121/// #[embassy_executor::main(entry = "esp_riscv_rt::entry")]
122/// async fn main(_s: embassy_executor::Spawner) {
123/// // Function body
124/// }
125/// ```
126#[proc_macro_attribute]
127pub fn main_riscv(args: TokenStream, item: TokenStream) -> TokenStream {
128 main::run(args.into(), item.into(), &main::ARCH_RISCV).into()
129}
130
131/// Creates a new `executor` instance and declares an application entry point for STD spawning the corresponding function body as an async task.
132///
133/// The following restrictions apply:
134///
135/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
136/// * The function must be declared `async`.
137/// * The function must not use generics.
138/// * Only a single `main` task may be declared.
139///
140/// ## Examples
141/// Spawning a task:
142///
143/// ``` rust
144/// #[embassy_executor::main]
145/// async fn main(_s: embassy_executor::Spawner) {
146/// // Function body
147/// }
148/// ```
149#[proc_macro_attribute]
150pub fn main_std(args: TokenStream, item: TokenStream) -> TokenStream {
151 main::run(args.into(), item.into(), &main::ARCH_STD).into()
152}
153
154/// Creates a new `executor` instance and declares an application entry point for WASM spawning the corresponding function body as an async task.
155///
156/// The following restrictions apply:
157///
158/// * The function must accept exactly 1 parameter, an `embassy_executor::Spawner` handle that it can use to spawn additional tasks.
159/// * The function must be declared `async`.
160/// * The function must not use generics.
161/// * Only a single `main` task may be declared.
162///
163/// ## Examples
164/// Spawning a task:
165///
166/// ``` rust
167/// #[embassy_executor::main]
168/// async fn main(_s: embassy_executor::Spawner) {
169/// // Function body
170/// }
171/// ```
172#[proc_macro_attribute]
173pub fn main_wasm(args: TokenStream, item: TokenStream) -> TokenStream {
174 main::run(args.into(), item.into(), &main::ARCH_WASM).into()
175}
176