From 58d503a77da73204f097fae1f1a2a1ce2cf90600 Mon Sep 17 00:00:00 2001 From: sodo Date: Sun, 10 Dec 2023 01:45:24 +0900 Subject: [PATCH 1/6] add avr support --- embassy-executor-macros/src/lib.rs | 7 +++ embassy-executor-macros/src/macros/main.rs | 14 +++++ embassy-executor/Cargo.toml | 1 + embassy-executor/src/arch/avr.rs | 60 ++++++++++++++++++++++ embassy-executor/src/lib.rs | 3 +- 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 embassy-executor/src/arch/avr.rs diff --git a/embassy-executor-macros/src/lib.rs b/embassy-executor-macros/src/lib.rs index c9d58746a..5461fe04c 100644 --- a/embassy-executor-macros/src/lib.rs +++ b/embassy-executor-macros/src/lib.rs @@ -62,6 +62,13 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { task::run(&args.meta, f).unwrap_or_else(|x| x).into() } +#[proc_macro_attribute] +pub fn main_avr(args: TokenStream, item: TokenStream) -> TokenStream { + let args = syn::parse_macro_input!(args as Args); + let f = syn::parse_macro_input!(item as syn::ItemFn); + main::run(&args.meta, f, main::avr()).unwrap_or_else(|x| x).into() +} + /// Creates a new `executor` instance and declares an application entry point for Cortex-M spawning the corresponding function body as an async task. /// /// The following restrictions apply: diff --git a/embassy-executor-macros/src/macros/main.rs b/embassy-executor-macros/src/macros/main.rs index 3c0d58567..088e64d1c 100644 --- a/embassy-executor-macros/src/macros/main.rs +++ b/embassy-executor-macros/src/macros/main.rs @@ -12,6 +12,20 @@ struct Args { entry: Option, } +pub fn avr() -> TokenStream { + quote! { + #[avr_device::entry] + fn main() -> ! { + let mut executor = ::embassy_executor::Executor::new(); + let executor = unsafe { __make_static(&mut executor) }; + + executor.run(|spawner| { + spawner.must_spawn(__embassy_main(spawner)); + }) + } + } +} + pub fn riscv(args: &[NestedMeta]) -> TokenStream { let maybe_entry = match Args::from_list(args) { Ok(args) => args.entry, diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index ec5aca46d..ade37913b 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -55,6 +55,7 @@ critical-section = { version = "1.1", features = ["std"] } # Architecture _arch = [] # some arch was picked +arch-avr = ["_arch", "dep:portable-atomic"] arch-std = ["_arch", "critical-section/std"] arch-cortex-m = ["_arch", "dep:cortex-m"] arch-riscv32 = ["_arch", "dep:portable-atomic"] diff --git a/embassy-executor/src/arch/avr.rs b/embassy-executor/src/arch/avr.rs new file mode 100644 index 000000000..2c715f297 --- /dev/null +++ b/embassy-executor/src/arch/avr.rs @@ -0,0 +1,60 @@ +#[cfg(feature = "executor-interrupt")] +compile_error!("`executor-interrupt` is not supported with `arch-avr`."); + +#[cfg(feature = "executor-thread")] +pub use thread::*; +#[cfg(feature = "executor-thread")] +mod thread { + use core::marker::PhantomData; + + pub use embassy_executor_macros::main_avr as main; + + use crate::{raw, Spawner}; + + #[export_name = "__pender"] + fn __pender(_context: *mut ()) {} + + /// avr Executor + pub struct Executor { + inner: raw::Executor, + not_send: PhantomData<*mut ()>, + } + + impl Executor { + /// Create a new Executor. + pub fn new() -> Self { + Self { + inner: raw::Executor::new(core::ptr::null_mut()), + not_send: PhantomData, + } + } + + /// Run the executor. + /// + /// The `init` closure is called with a [`Spawner`] that spawns tasks on + /// this executor. Use it to spawn the initial task(s). After `init` returns, + /// the executor starts running the tasks. + /// + /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), + /// for example by passing it as an argument to the initial tasks. + /// + /// This function requires `&'static mut self`. This means you have to store the + /// Executor instance in a place where it'll live forever and grants you mutable + /// access. There's a few ways to do this: + /// + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) + /// - a `static mut` (unsafe) + /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) + /// + /// This function never returns. + pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { + init(self.inner.spawner()); + + loop { + unsafe { + self.inner.poll(); + } + } + } + } +} diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 4c6900a6d..834ebf16a 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -20,9 +20,10 @@ macro_rules! check_at_most_one { check_at_most_one!(@amo [$($f)*] [$($f)*] []); }; } -check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-std", "arch-wasm",); +check_at_most_one!("arch-avr", "arch-cortex-m", "arch-riscv32", "arch-std", "arch-wasm",); #[cfg(feature = "_arch")] +#[cfg_attr(feature = "arch-avr", path = "arch/avr.rs")] #[cfg_attr(feature = "arch-cortex-m", path = "arch/cortex_m.rs")] #[cfg_attr(feature = "arch-riscv32", path = "arch/riscv32.rs")] #[cfg_attr(feature = "arch-std", path = "arch/std.rs")] From 172ed52128e0da519c13b7a354aeb98c492be3c3 Mon Sep 17 00:00:00 2001 From: sodo Date: Tue, 12 Dec 2023 16:51:24 +0900 Subject: [PATCH 2/6] ci.sh: add avr --- ci.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci.sh b/ci.sh index 8a5e206d2..a5ddda3a1 100755 --- a/ci.sh +++ b/ci.sh @@ -207,6 +207,10 @@ cargo batch \ --- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \ $BUILD_EXTRA +# walkaround: "-Z" option not working on cargo batch +cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr +cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr,integrated-timers + rm out/tests/stm32wb55rg/wpan_mac rm out/tests/stm32wb55rg/wpan_ble From b7cd7952c890f585ff876c622482534e5d58d4a4 Mon Sep 17 00:00:00 2001 From: sodo Date: Mon, 1 Jan 2024 21:18:30 +0900 Subject: [PATCH 3/6] avr: support sleep --- ci.sh | 4 ++-- embassy-executor/Cargo.toml | 8 ++++++-- embassy-executor/src/arch/avr.rs | 13 +++++++++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ci.sh b/ci.sh index a5ddda3a1..a804647e1 100755 --- a/ci.sh +++ b/ci.sh @@ -208,8 +208,8 @@ cargo batch \ $BUILD_EXTRA # walkaround: "-Z" option not working on cargo batch -cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr -cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr,integrated-timers +cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr,avr-device/atmega328p +cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr,integrated-timers,avr-device/atmega328p rm out/tests/stm32wb55rg/wpan_mac diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index ade37913b..c937194ce 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -36,10 +36,11 @@ embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macro embassy-time = { version = "0.2", path = "../embassy-time", optional = true} critical-section = "1.1" -# needed for riscv +# needed for riscv and avr # remove when https://github.com/rust-lang/rust/pull/114499 is merged portable-atomic = { version = "1.5", optional = true } + # arch-cortex-m dependencies cortex-m = { version = "0.7.6", optional = true } @@ -47,6 +48,9 @@ cortex-m = { version = "0.7.6", optional = true } wasm-bindgen = { version = "0.2.82", optional = true } js-sys = { version = "0.3", optional = true } +# arch-avr dependencies +avr-device = { version = "0.5.3", optional = true } + [dev-dependencies] critical-section = { version = "1.1", features = ["std"] } @@ -55,7 +59,7 @@ critical-section = { version = "1.1", features = ["std"] } # Architecture _arch = [] # some arch was picked -arch-avr = ["_arch", "dep:portable-atomic"] +arch-avr = ["_arch", "dep:portable-atomic", "dep:avr-device"] arch-std = ["_arch", "critical-section/std"] arch-cortex-m = ["_arch", "dep:cortex-m"] arch-riscv32 = ["_arch", "dep:portable-atomic"] diff --git a/embassy-executor/src/arch/avr.rs b/embassy-executor/src/arch/avr.rs index 2c715f297..fa6afe762 100644 --- a/embassy-executor/src/arch/avr.rs +++ b/embassy-executor/src/arch/avr.rs @@ -8,11 +8,16 @@ mod thread { use core::marker::PhantomData; pub use embassy_executor_macros::main_avr as main; + use portable_atomic::{AtomicBool, Ordering}; use crate::{raw, Spawner}; + static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); + #[export_name = "__pender"] - fn __pender(_context: *mut ()) {} + fn __pender(_context: *mut ()) { + SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); + } /// avr Executor pub struct Executor { @@ -52,7 +57,11 @@ mod thread { loop { unsafe { - self.inner.poll(); + if SIGNAL_WORK_THREAD_MODE.swap(false, Ordering::SeqCst) { + self.inner.poll(); + } else { + avr_device::asm::sleep(); + } } } } From b0071c5070f6b4c932e703f2539c2eef74f09338 Mon Sep 17 00:00:00 2001 From: sodo Date: Tue, 2 Jan 2024 14:48:27 +0900 Subject: [PATCH 4/6] avr: sleep fix --- embassy-executor/src/arch/avr.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/embassy-executor/src/arch/avr.rs b/embassy-executor/src/arch/avr.rs index fa6afe762..11e81ed9a 100644 --- a/embassy-executor/src/arch/avr.rs +++ b/embassy-executor/src/arch/avr.rs @@ -57,10 +57,13 @@ mod thread { loop { unsafe { + avr_device::interrupt::disable(); if SIGNAL_WORK_THREAD_MODE.swap(false, Ordering::SeqCst) { - self.inner.poll(); - } else { + avr_device::interrupt::enable(); avr_device::asm::sleep(); + } else { + avr_device::interrupt::enable(); + self.inner.poll(); } } } From 162f356ece8533d326df4acf918b3c4462bf486c Mon Sep 17 00:00:00 2001 From: sodo Date: Tue, 2 Jan 2024 23:39:06 +0900 Subject: [PATCH 5/6] add avr to ci --- ci-nightly.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci-nightly.sh b/ci-nightly.sh index 1fc9692b5..46b19c5b7 100755 --- a/ci-nightly.sh +++ b/ci-nightly.sh @@ -28,3 +28,6 @@ cargo batch \ --- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread,integrated-timers \ --- build --release --manifest-path examples/nrf52840-rtic/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840-rtic \ +cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr,avr-device/atmega328p +cargo build --release --manifest-path embassy-executor/Cargo.toml --target avr-unknown-gnu-atmega328 -Z build-std=core,alloc --features nightly,arch-avr,integrated-timers,avr-device/atmega328p + From 01dbe9278357296fe9fb99f5e6923e80067c4a98 Mon Sep 17 00:00:00 2001 From: sodo Date: Wed, 3 Jan 2024 12:35:07 +0900 Subject: [PATCH 6/6] fix --- embassy-executor/src/arch/avr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-executor/src/arch/avr.rs b/embassy-executor/src/arch/avr.rs index 11e81ed9a..70085d04d 100644 --- a/embassy-executor/src/arch/avr.rs +++ b/embassy-executor/src/arch/avr.rs @@ -58,7 +58,7 @@ mod thread { loop { unsafe { avr_device::interrupt::disable(); - if SIGNAL_WORK_THREAD_MODE.swap(false, Ordering::SeqCst) { + if !SIGNAL_WORK_THREAD_MODE.swap(false, Ordering::SeqCst) { avr_device::interrupt::enable(); avr_device::asm::sleep(); } else {