diff options
Diffstat (limited to 'embassy-executor-macros/src')
| -rw-r--r-- | embassy-executor-macros/src/lib.rs | 29 | ||||
| -rw-r--r-- | embassy-executor-macros/src/macros/main.rs | 29 |
2 files changed, 57 insertions, 1 deletions
diff --git a/embassy-executor-macros/src/lib.rs b/embassy-executor-macros/src/lib.rs index 5461fe04c..61d388b9e 100644 --- a/embassy-executor-macros/src/lib.rs +++ b/embassy-executor-macros/src/lib.rs | |||
| @@ -94,6 +94,35 @@ pub fn main_cortex_m(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 94 | main::run(&args.meta, f, main::cortex_m()).unwrap_or_else(|x| x).into() | 94 | main::run(&args.meta, f, main::cortex_m()).unwrap_or_else(|x| x).into() |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | /// Creates a new `executor` instance and declares an architecture agnostic application entry point spawning | ||
| 98 | /// 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 must provided via the `entry` argument | ||
| 108 | /// | ||
| 109 | /// ## Examples | ||
| 110 | /// Spawning a task: | ||
| 111 | /// ``` rust | ||
| 112 | /// #[embassy_executor::main(entry = "qingke_rt::entry")] | ||
| 113 | /// async fn main(_s: embassy_executor::Spawner) { | ||
| 114 | /// // Function body | ||
| 115 | /// } | ||
| 116 | /// ``` | ||
| 117 | #[proc_macro_attribute] | ||
| 118 | pub fn main_spin(args: TokenStream, item: TokenStream) -> TokenStream { | ||
| 119 | let args = syn::parse_macro_input!(args as Args); | ||
| 120 | let f = syn::parse_macro_input!(item as syn::ItemFn); | ||
| 121 | main::run(&args.meta, f, main::spin(&args.meta)) | ||
| 122 | .unwrap_or_else(|x| x) | ||
| 123 | .into() | ||
| 124 | } | ||
| 125 | |||
| 97 | /// Creates a new `executor` instance and declares an application entry point for RISC-V spawning the corresponding function body as an async task. | 126 | /// Creates a new `executor` instance and declares an application entry point for RISC-V spawning the corresponding function body as an async task. |
| 98 | /// | 127 | /// |
| 99 | /// The following restrictions apply: | 128 | /// The following restrictions apply: |
diff --git a/embassy-executor-macros/src/macros/main.rs b/embassy-executor-macros/src/macros/main.rs index 26dfa2397..66a3965d0 100644 --- a/embassy-executor-macros/src/macros/main.rs +++ b/embassy-executor-macros/src/macros/main.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use darling::export::NestedMeta; | 1 | use darling::export::NestedMeta; |
| 2 | use darling::FromMeta; | 2 | use darling::{Error, FromMeta}; |
| 3 | use proc_macro2::TokenStream; | 3 | use proc_macro2::TokenStream; |
| 4 | use quote::quote; | 4 | use quote::quote; |
| 5 | use syn::{Expr, ReturnType, Type}; | 5 | use syn::{Expr, ReturnType, Type}; |
| @@ -50,6 +50,33 @@ pub fn riscv(args: &[NestedMeta]) -> TokenStream { | |||
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | pub fn spin(args: &[NestedMeta]) -> TokenStream { | ||
| 54 | let maybe_entry = match Args::from_list(args) { | ||
| 55 | Ok(args) => args.entry, | ||
| 56 | Err(e) => return e.write_errors(), | ||
| 57 | }; | ||
| 58 | |||
| 59 | let entry = match maybe_entry { | ||
| 60 | Some(str) => str, | ||
| 61 | None => return Error::missing_field("entry").write_errors(), | ||
| 62 | }; | ||
| 63 | let entry = match Expr::from_string(&entry) { | ||
| 64 | Ok(expr) => expr, | ||
| 65 | Err(e) => return e.write_errors(), | ||
| 66 | }; | ||
| 67 | |||
| 68 | quote! { | ||
| 69 | #[#entry] | ||
| 70 | fn main() -> ! { | ||
| 71 | let mut executor = ::embassy_executor::Executor::new(); | ||
| 72 | let executor = unsafe { __make_static(&mut executor) }; | ||
| 73 | executor.run(|spawner| { | ||
| 74 | spawner.must_spawn(__embassy_main(spawner)); | ||
| 75 | }) | ||
| 76 | } | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 53 | pub fn cortex_m() -> TokenStream { | 80 | pub fn cortex_m() -> TokenStream { |
| 54 | quote! { | 81 | quote! { |
| 55 | #[cortex_m_rt::entry] | 82 | #[cortex_m_rt::entry] |
