From 1a3d5ce5ecf2974a2c804096284b72523ae95f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 7 Jan 2025 15:26:53 +0100 Subject: [PATCH] Provide a looping executor for stable async tests --- hil-test/Cargo.toml | 7 ++-- hil-test/src/lib.rs | 39 ++++++++++++++++++++ hil-test/tests/delay_async.rs | 2 +- hil-test/tests/embassy_interrupt_executor.rs | 2 +- hil-test/tests/embassy_interrupt_spi_dma.rs | 2 +- hil-test/tests/embassy_timers_executors.rs | 2 +- hil-test/tests/gpio.rs | 32 ++++++++++------ hil-test/tests/gpio_custom_handler.rs | 2 +- hil-test/tests/i2s.rs | 2 +- hil-test/tests/lcd_cam_i8080_async.rs | 2 +- hil-test/tests/parl_io_tx_async.rs | 2 +- hil-test/tests/rsa_async.rs | 2 +- hil-test/tests/spi_full_duplex.rs | 2 +- hil-test/tests/spi_slave.rs | 2 +- hil-test/tests/uart_async.rs | 2 +- hil-test/tests/uart_tx_rx_async.rs | 2 +- 16 files changed, 75 insertions(+), 29 deletions(-) diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml index 690be83f528..8e3a074d2b1 100644 --- a/hil-test/Cargo.toml +++ b/hil-test/Cargo.toml @@ -197,6 +197,7 @@ cfg-if = "1.0.0" critical-section = "1.1.3" defmt = "0.3.8" defmt-rtt = { version = "0.4.1", optional = true } +embassy-executor = "0.6.0" embassy-futures = "0.1.1" embassy-sync = "0.6.0" embassy-time = "0.3.2" @@ -220,7 +221,7 @@ digest = { version = "0.10.7", default-features = false } elliptic-curve = { version = "0.13.8", default-features = false, features = ["sec1"] } embassy-executor = { version = "0.6.0", default-features = false } # Add the `embedded-test/defmt` feature for more verbose testing -embedded-test = { version = "0.5.0", git = "https://github.com/probe-rs/embedded-test.git", rev = "7109473", default-features = false } +embedded-test = { version = "0.5.0", git = "https://github.com/probe-rs/embedded-test.git", rev = "7109473", default-features = false, features = ["embassy", "external-executor"] } fugit = "0.3.7" hex-literal = "0.4.1" nb = "1.1.0" @@ -234,7 +235,7 @@ esp-build = { path = "../esp-build" } esp-metadata = { path = "../esp-metadata" } [features] -default = ["embassy"] +default = [] unstable = ["esp-hal/unstable"] defmt = ["dep:defmt-rtt", "esp-hal/defmt", "embedded-test/defmt"] @@ -287,8 +288,6 @@ esp32s3 = [ ] # Async & Embassy: embassy = [ - "embedded-test/embassy", - "embedded-test/external-executor", "dep:esp-hal-embassy", ] generic-queue = [ diff --git a/hil-test/src/lib.rs b/hil-test/src/lib.rs index 660e8697cbe..1ce1a1b444b 100644 --- a/hil-test/src/lib.rs +++ b/hil-test/src/lib.rs @@ -82,3 +82,42 @@ macro_rules! unconnected_pin { } }}; } + +// A simple looping executor to test async code without esp-hal-embassy (which +// needs `esp-hal/unstable`). +#[cfg(not(feature = "embassy"))] +mod executor { + use core::marker::PhantomData; + + use embassy_executor::{raw, Spawner}; + + #[export_name = "__pender"] + fn __pender(_: *mut ()) {} + + pub struct Executor { + inner: raw::Executor, + not_send: PhantomData<*mut ()>, + } + + impl Executor { + pub fn new() -> Self { + Self { + inner: raw::Executor::new(core::ptr::null_mut()), + not_send: PhantomData, + } + } + + pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { + init(self.inner.spawner()); + + loop { + unsafe { self.inner.poll() }; + } + } + } +} + +#[cfg(feature = "embassy")] +pub use esp_hal_embassy::Executor; +#[cfg(not(feature = "embassy"))] +pub use executor::Executor; diff --git a/hil-test/tests/delay_async.rs b/hil-test/tests/delay_async.rs index d0d58bbd1cd..6bb4706e043 100644 --- a/hil-test/tests/delay_async.rs +++ b/hil-test/tests/delay_async.rs @@ -70,7 +70,7 @@ async fn test_async_delay_ms(mut timer: impl DelayNs, duration: u32) { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 2, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 2, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/embassy_interrupt_executor.rs b/hil-test/tests/embassy_interrupt_executor.rs index cc79b52e247..80cc8a9bfd2 100644 --- a/hil-test/tests/embassy_interrupt_executor.rs +++ b/hil-test/tests/embassy_interrupt_executor.rs @@ -48,7 +48,7 @@ struct Context { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod test { use super::*; diff --git a/hil-test/tests/embassy_interrupt_spi_dma.rs b/hil-test/tests/embassy_interrupt_spi_dma.rs index 4b7ffbd334e..94a90427bb7 100644 --- a/hil-test/tests/embassy_interrupt_spi_dma.rs +++ b/hil-test/tests/embassy_interrupt_spi_dma.rs @@ -75,7 +75,7 @@ async fn interrupt_driven_task(mut i2s_tx: esp_hal::i2s::master::I2sTx<'static, } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod test { use super::*; diff --git a/hil-test/tests/embassy_timers_executors.rs b/hil-test/tests/embassy_timers_executors.rs index e0fa188bfdd..cc8672557ff 100644 --- a/hil-test/tests/embassy_timers_executors.rs +++ b/hil-test/tests/embassy_timers_executors.rs @@ -122,7 +122,7 @@ fn set_up_embassy_with_systimer(peripherals: Peripherals) { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod test { use super::*; use crate::test_cases::*; diff --git a/hil-test/tests/gpio.rs b/hil-test/tests/gpio.rs index ae0d4649650..a2ee0b31228 100644 --- a/hil-test/tests/gpio.rs +++ b/hil-test/tests/gpio.rs @@ -1,7 +1,8 @@ //! GPIO Test //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 -//% FEATURES: unstable generic-queue +//% FEATURES: unstable embassy generic-queue +//% FEATURES(stable): #![no_std] #![no_main] @@ -9,14 +10,22 @@ use core::cell::RefCell; use critical_section::Mutex; +#[cfg(feature = "unstable")] +use embassy_time::{Duration, Timer}; use esp_hal::{ delay::Delay, - gpio::{AnyPin, Input, Io, Level, Output, Pin, Pull}, - interrupt::InterruptConfigurable, + gpio::{AnyPin, Input, Level, Output, OutputOpenDrain, Pin, Pull}, macros::handler, +}; +#[cfg(feature = "unstable")] +use esp_hal::{ + gpio::{Event, Flex, Io}, + interrupt::InterruptConfigurable, timer::timg::TimerGroup, }; use hil_test as _; +#[cfg(feature = "unstable")] +use portable_atomic::{AtomicUsize, Ordering}; static COUNTER: Mutex> = Mutex::new(RefCell::new(0)); static INPUT_PIN: Mutex>> = Mutex::new(RefCell::new(None)); @@ -39,27 +48,25 @@ pub fn interrupt_handler() { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { - use embassy_time::{Duration, Timer}; - use esp_hal::gpio::{Event, Flex, OutputOpenDrain}; - use portable_atomic::{AtomicUsize, Ordering}; - use super::*; #[init] fn init() -> Context { let peripherals = esp_hal::init(esp_hal::Config::default()); - let mut io = Io::new(peripherals.IO_MUX); - io.set_interrupt_handler(interrupt_handler); - let delay = Delay::new(); let (gpio1, gpio2) = hil_test::common_test_pins!(peripherals); #[cfg(feature = "unstable")] { + // Interrupts are unstable + let mut io = Io::new(peripherals.IO_MUX); + io.set_interrupt_handler(interrupt_handler); + + // Timers are unstable let timg0 = TimerGroup::new(peripherals.TIMG0); esp_hal_embassy::init(timg0.timer0); } @@ -72,6 +79,7 @@ mod tests { } #[test] + #[cfg(feature = "unstable")] // Timers are unstable async fn async_edge(ctx: Context) { let counter = AtomicUsize::new(0); let Context { @@ -198,7 +206,7 @@ mod tests { } #[test] - #[cfg(feature = "unstable")] + #[cfg(feature = "unstable")] // Interrupts are unstable fn gpio_interrupt(ctx: Context) { let mut test_gpio1 = Input::new(ctx.test_gpio1, Pull::Down); let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low); diff --git a/hil-test/tests/gpio_custom_handler.rs b/hil-test/tests/gpio_custom_handler.rs index dff5ec2e840..718b81df2fa 100644 --- a/hil-test/tests/gpio_custom_handler.rs +++ b/hil-test/tests/gpio_custom_handler.rs @@ -66,7 +66,7 @@ async fn drive_pins(gpio1: impl Into, gpio2: impl Into) -> usize } #[cfg(test)] -#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/i2s.rs b/hil-test/tests/i2s.rs index 8eafd7b301d..c36f299e6ff 100644 --- a/hil-test/tests/i2s.rs +++ b/hil-test/tests/i2s.rs @@ -97,7 +97,7 @@ fn enable_loopback() { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/lcd_cam_i8080_async.rs b/hil-test/tests/lcd_cam_i8080_async.rs index 91dfa7f43fd..0616ae708bc 100644 --- a/hil-test/tests/lcd_cam_i8080_async.rs +++ b/hil-test/tests/lcd_cam_i8080_async.rs @@ -28,7 +28,7 @@ struct Context<'d> { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/parl_io_tx_async.rs b/hil-test/tests/parl_io_tx_async.rs index 21fbb129549..76a8f9da281 100644 --- a/hil-test/tests/parl_io_tx_async.rs +++ b/hil-test/tests/parl_io_tx_async.rs @@ -43,7 +43,7 @@ struct Context { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { use defmt::info; diff --git a/hil-test/tests/rsa_async.rs b/hil-test/tests/rsa_async.rs index 0c74c1384d3..c9b1a132a60 100644 --- a/hil-test/tests/rsa_async.rs +++ b/hil-test/tests/rsa_async.rs @@ -49,7 +49,7 @@ const fn compute_mprime(modulus: &U512) -> u32 { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 5, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 5, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/spi_full_duplex.rs b/hil-test/tests/spi_full_duplex.rs index cbc7a6d1901..a1b9c032151 100644 --- a/hil-test/tests/spi_full_duplex.rs +++ b/hil-test/tests/spi_full_duplex.rs @@ -48,7 +48,7 @@ struct Context { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/spi_slave.rs b/hil-test/tests/spi_slave.rs index 1fc169d8e27..3f6fa7441e0 100644 --- a/hil-test/tests/spi_slave.rs +++ b/hil-test/tests/spi_slave.rs @@ -95,7 +95,7 @@ impl BitbangSpi { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 10, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 10, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/uart_async.rs b/hil-test/tests/uart_async.rs index bc320f26bfe..2b697d9c3e9 100644 --- a/hil-test/tests/uart_async.rs +++ b/hil-test/tests/uart_async.rs @@ -17,7 +17,7 @@ struct Context { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { use super::*; diff --git a/hil-test/tests/uart_tx_rx_async.rs b/hil-test/tests/uart_tx_rx_async.rs index 6a70473100d..3fe3d3dbec5 100644 --- a/hil-test/tests/uart_tx_rx_async.rs +++ b/hil-test/tests/uart_tx_rx_async.rs @@ -18,7 +18,7 @@ struct Context { } #[cfg(test)] -#[embedded_test::tests(default_timeout = 3, executor = esp_hal_embassy::Executor::new())] +#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())] mod tests { use super::*;