From 9e445b3583c15c7701f3167eaa8dfe4afd541691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Sat, 4 Feb 2023 16:47:17 +0100 Subject: Move rtic macros to repo root, tune xtask --- rtic-macros/src/codegen/async_dispatchers.rs | 89 ++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 rtic-macros/src/codegen/async_dispatchers.rs (limited to 'rtic-macros/src/codegen/async_dispatchers.rs') diff --git a/rtic-macros/src/codegen/async_dispatchers.rs b/rtic-macros/src/codegen/async_dispatchers.rs new file mode 100644 index 0000000..a12ad32 --- /dev/null +++ b/rtic-macros/src/codegen/async_dispatchers.rs @@ -0,0 +1,89 @@ +use crate::syntax::ast::App; +use crate::{analyze::Analysis, codegen::util}; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +/// Generates task dispatchers +pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { + let mut items = vec![]; + + let interrupts = &analysis.interrupts; + + // Generate executor definition and priority in global scope + for (name, _) in app.software_tasks.iter() { + let type_name = util::internal_task_ident(name, "F"); + let exec_name = util::internal_task_ident(name, "EXEC"); + + items.push(quote!( + #[allow(non_camel_case_types)] + type #type_name = impl core::future::Future; + #[allow(non_upper_case_globals)] + static #exec_name: rtic::export::executor::AsyncTaskExecutor<#type_name> = + rtic::export::executor::AsyncTaskExecutor::new(); + )); + } + + for (&level, channel) in &analysis.channels { + let mut stmts = vec![]; + + let dispatcher_name = if level > 0 { + util::suffixed(&interrupts.get(&level).expect("UNREACHABLE").0.to_string()) + } else { + util::zero_prio_dispatcher_ident() + }; + + let pend_interrupt = if level > 0 { + let device = &app.args.device; + let enum_ = util::interrupt_ident(); + + quote!(rtic::pend(#device::#enum_::#dispatcher_name);) + } else { + // For 0 priority tasks we don't need to pend anything + quote!() + }; + + for name in channel.tasks.iter() { + let exec_name = util::internal_task_ident(name, "EXEC"); + // TODO: Fix cfg + // let task = &app.software_tasks[name]; + // let cfgs = &task.cfgs; + + stmts.push(quote!( + #exec_name.poll(|| { + #exec_name.set_pending(); + #pend_interrupt + }); + )); + } + + if level > 0 { + let doc = format!("Interrupt handler to dispatch async tasks at priority {level}"); + let attribute = &interrupts.get(&level).expect("UNREACHABLE").1.attrs; + items.push(quote!( + #[allow(non_snake_case)] + #[doc = #doc] + #[no_mangle] + #(#attribute)* + unsafe fn #dispatcher_name() { + /// The priority of this interrupt handler + const PRIORITY: u8 = #level; + + rtic::export::run(PRIORITY, || { + #(#stmts)* + }); + } + )); + } else { + items.push(quote!( + #[allow(non_snake_case)] + unsafe fn #dispatcher_name() -> ! { + loop { + #(#stmts)* + } + } + )); + } + } + + quote!(#(#items)*) +} -- cgit v1.2.3 From e8cebff69e3fd78ade613829c10dd2328495fa44 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Mon, 20 Feb 2023 10:49:09 +0100 Subject: Added support for adding codegen to intrrupt entry and exit (needed for RISC-V) --- rtic-macros/src/codegen/async_dispatchers.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'rtic-macros/src/codegen/async_dispatchers.rs') diff --git a/rtic-macros/src/codegen/async_dispatchers.rs b/rtic-macros/src/codegen/async_dispatchers.rs index a12ad32..bdbfeaa 100644 --- a/rtic-macros/src/codegen/async_dispatchers.rs +++ b/rtic-macros/src/codegen/async_dispatchers.rs @@ -1,5 +1,11 @@ use crate::syntax::ast::App; -use crate::{analyze::Analysis, codegen::util}; +use crate::{ + analyze::Analysis, + codegen::{ + bindings::{interrupt_entry, interrupt_exit}, + util, + }, +}; use proc_macro2::TokenStream as TokenStream2; use quote::quote; @@ -59,18 +65,25 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { if level > 0 { let doc = format!("Interrupt handler to dispatch async tasks at priority {level}"); let attribute = &interrupts.get(&level).expect("UNREACHABLE").1.attrs; + let entry_stmts = interrupt_entry(app, analysis); + let exit_stmts = interrupt_exit(app, analysis); + items.push(quote!( #[allow(non_snake_case)] #[doc = #doc] #[no_mangle] #(#attribute)* unsafe fn #dispatcher_name() { + #(#entry_stmts)* + /// The priority of this interrupt handler const PRIORITY: u8 = #level; rtic::export::run(PRIORITY, || { #(#stmts)* }); + + #(#exit_stmts)* } )); } else { -- cgit v1.2.3