From a330dedf3723086b1e1629066013ec8014635de9 Mon Sep 17 00:00:00 2001 From: Lasse Dalegaard Date: Mon, 18 Mar 2024 13:15:41 +0100 Subject: [PATCH] rtic-macros: fix #[cfg] for hardware and software tasks Disabling hardware and software tasks via `#[cfg]` flags was broken. Added test case to verify, and fixed codegen to output missing cfgs. --- ci/expected/lm3s6965/t-cfg-tasks.run | 0 examples/lm3s6965/Cargo.lock | 2 +- examples/lm3s6965/examples/t-cfg-tasks.rs | 35 ++++++++++++++++++++ rtic-macros/CHANGELOG.md | 4 +++ rtic-macros/src/codegen/async_dispatchers.rs | 12 ++++--- rtic-macros/src/codegen/hardware_tasks.rs | 2 ++ rtic-macros/src/codegen/main.rs | 11 ++++-- rtic/CHANGELOG.md | 4 +++ 8 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 ci/expected/lm3s6965/t-cfg-tasks.run create mode 100644 examples/lm3s6965/examples/t-cfg-tasks.rs diff --git a/ci/expected/lm3s6965/t-cfg-tasks.run b/ci/expected/lm3s6965/t-cfg-tasks.run new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/examples/lm3s6965/Cargo.lock b/examples/lm3s6965/Cargo.lock index 696c606ea2b6..47b35c20119f 100644 --- a/examples/lm3s6965/Cargo.lock +++ b/examples/lm3s6965/Cargo.lock @@ -354,7 +354,7 @@ dependencies = [ [[package]] name = "rtic" -version = "2.1.0" +version = "2.1.1" dependencies = [ "atomic-polyfill", "bare-metal 1.0.0", diff --git a/examples/lm3s6965/examples/t-cfg-tasks.rs b/examples/lm3s6965/examples/t-cfg-tasks.rs new file mode 100644 index 000000000000..bea5f76e1f52 --- /dev/null +++ b/examples/lm3s6965/examples/t-cfg-tasks.rs @@ -0,0 +1,35 @@ +//! [compile-pass] check that `#[cfg]` attributes applied on tasks work + +#![no_main] +#![no_std] +#![deny(warnings)] +#![deny(unsafe_code)] +#![deny(missing_docs)] + +use panic_semihosting as _; + +#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +mod app { + use cortex_m_semihosting::debug; + + #[shared] + struct Shared {} + + #[local] + struct Local {} + + #[init] + fn init(_: init::Context) -> (Shared, Local) { + debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + + (Shared {}, Local {}) + } + + #[cfg(feature = "feature_x")] + #[task] + async fn opt_sw_task(cx: opt_sw_task::Context) {} + + #[cfg(feature = "feature_x")] + #[task(binds = UART0)] + fn opt_hw_task(cx: opt_hw_task::Context) {} +} diff --git a/rtic-macros/CHANGELOG.md b/rtic-macros/CHANGELOG.md index a0d761bb2eb1..f5bf9372e162 100644 --- a/rtic-macros/CHANGELOG.md +++ b/rtic-macros/CHANGELOG.md @@ -7,6 +7,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top! ## [Unreleased] +### Fixed + +- Fixed `#[cfg]` tags on hardware and software tasks. + ## [v2.1.0] - 2024-02-27 ### Added diff --git a/rtic-macros/src/codegen/async_dispatchers.rs b/rtic-macros/src/codegen/async_dispatchers.rs index 3d166ca136d6..cc31a4ea45de 100644 --- a/rtic-macros/src/codegen/async_dispatchers.rs +++ b/rtic-macros/src/codegen/async_dispatchers.rs @@ -16,10 +16,12 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { let interrupts = &analysis.interrupts; // Generate executor definition and priority in global scope - for (name, _) in app.software_tasks.iter() { + for (name, task) in app.software_tasks.iter() { let exec_name = util::internal_task_ident(name, "EXEC"); + let cfgs = &task.cfgs; items.push(quote!( + #(#cfgs)* #[allow(non_upper_case_globals)] static #exec_name: rtic::export::executor::AsyncTaskExecutorPtr = rtic::export::executor::AsyncTaskExecutorPtr::new(); @@ -46,15 +48,15 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { for name in channel.tasks.iter() { let exec_name = util::internal_task_ident(name, "EXEC"); + let task = &app.software_tasks[name]; + let cfgs = &task.cfgs; let from_ptr_n_args = util::from_ptr_n_args_ident(app.software_tasks[name].inputs.len()); - // TODO: Fix cfg - // let task = &app.software_tasks[name]; - // let cfgs = &task.cfgs; - stmts.push(quote!( + #(#cfgs)* let exec = rtic::export::executor::AsyncTaskExecutor::#from_ptr_n_args(#name, &#exec_name); + #(#cfgs)* exec.poll(|| { let exec = rtic::export::executor::AsyncTaskExecutor::#from_ptr_n_args(#name, &#exec_name); exec.set_pending(); diff --git a/rtic-macros/src/codegen/hardware_tasks.rs b/rtic-macros/src/codegen/hardware_tasks.rs index ee85f59f3351..e1bc4720adf5 100644 --- a/rtic-macros/src/codegen/hardware_tasks.rs +++ b/rtic-macros/src/codegen/hardware_tasks.rs @@ -73,10 +73,12 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { if !task.is_extern { let attrs = &task.attrs; + let cfgs = &task.cfgs; let context = &task.context; let stmts = &task.stmts; user_tasks.push(quote!( #(#attrs)* + #(#cfgs)* #[allow(non_snake_case)] fn #name(#context: #name::Context) { use rtic::Mutex as _; diff --git a/rtic-macros/src/codegen/main.rs b/rtic-macros/src/codegen/main.rs index 80f2cf6b8a73..76bddf2332d1 100644 --- a/rtic-macros/src/codegen/main.rs +++ b/rtic-macros/src/codegen/main.rs @@ -30,14 +30,19 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 { let mut executor_allocations = Vec::new(); - for (name, _) in app.software_tasks.iter() { + for (name, task) in app.software_tasks.iter() { let exec_name = util::internal_task_ident(name, "EXEC"); let new_n_args = util::new_n_args_ident(app.software_tasks[name].inputs.len()); + let cfgs = &task.cfgs; executor_allocations.push(quote!( + #(#cfgs)* let executor = ::core::mem::ManuallyDrop::new(rtic::export::executor::AsyncTaskExecutor::#new_n_args(#name)); - executors_size += ::core::mem::size_of_val(&executor); - #exec_name.set_in_main(&executor); + #(#cfgs)* + { + executors_size += ::core::mem::size_of_val(&executor); + #exec_name.set_in_main(&executor); + } )); } diff --git a/rtic/CHANGELOG.md b/rtic/CHANGELOG.md index c2cd678a78f3..ccf6983594db 100644 --- a/rtic/CHANGELOG.md +++ b/rtic/CHANGELOG.md @@ -7,6 +7,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top! ## [Unreleased] +### Fixed + +- Fixed `#[cfg]` tags on hardware and software tasks. + ## [v2.1.1] - 2024-03-13 ### Fixed