mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 21:00:59 +00:00
Further clean up timers/executors test (#1953)
* Further clean up embassy_timers_executors * Do not delay for so long * Print timer values on assert failure * Clean up some more * Retry test a few times to counteract probe-rs halting us * Fix formatting
This commit is contained in:
parent
a10f86dbaa
commit
6127f5df11
@ -1,23 +1,4 @@
|
||||
//! Embassy timer and executor Test
|
||||
//!
|
||||
//! Description of implemented tests:
|
||||
//! - run_test_one_shot_timg(): Tests Timg configured as OneShotTimer
|
||||
//! - run_test_periodic_timg(): Tests Timg configured as PeriodicTimer
|
||||
//! - run_test_one_shot_systimer(): Tests systimer configured as OneShotTimer
|
||||
//! - run_test_periodic_systimer(): Tests systimer configured as PeriodicTimer
|
||||
//! - run_test_periodic_oneshot_timg(): Tests Timg configured as PeriodicTimer
|
||||
//! and then reconfigured as OneShotTimer
|
||||
//! - run_test_periodic_oneshot_systimer(): Tests systimer configured as
|
||||
//! PeriodicTimer and then reconfigured as OneShotTimer
|
||||
//! - run_test_join_timg(): Tests Timg configured as OneShotTimer and wait on
|
||||
//! two different timeouts via join
|
||||
//! - run_test_join_systimer(): Tests systimer configured as OneShotTimer and
|
||||
//! wait on two different timeouts via join
|
||||
//! - run_test_interrupt_executor(): Tests InterruptExecutor and Thread
|
||||
//! (default) executor in parallel
|
||||
//! - run_tick_test_timg(): Tests Timg configured as OneShotTimer if it fires
|
||||
//! immediately in the case of the time scheduling was already in the past
|
||||
//! (timestamp being too big)
|
||||
|
||||
// esp32c2 is disabled currently as it fails
|
||||
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s3
|
||||
@ -29,7 +10,7 @@ use defmt_rtt as _;
|
||||
use embassy_time::{Duration, Ticker, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
clock::{ClockControl, Clocks},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -49,207 +30,104 @@ macro_rules! mk_static {
|
||||
}};
|
||||
}
|
||||
|
||||
unsafe fn __make_static<T>(t: &mut T) -> &'static mut T {
|
||||
::core::mem::transmute(t)
|
||||
}
|
||||
|
||||
// we need to tell the test framework somehow, if the async test passed or
|
||||
// failed, this mod is the list of functions that are spawned as an actual tests
|
||||
mod task_invokers {
|
||||
use test_helpers::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn test_one_shot_timg_invoker() {
|
||||
let outcome = test_helpers::test_one_shot_timg().await;
|
||||
|
||||
embedded_test::export::check_outcome(outcome);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
pub async fn test_one_shot_systimer_invoker() {
|
||||
let outcome = task_invokers::test_one_shot_systimer().await;
|
||||
|
||||
embedded_test::export::check_outcome(outcome);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn test_join_timg_invoker() {
|
||||
let outcome = test_join_timg().await;
|
||||
|
||||
embedded_test::export::check_outcome(outcome);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
pub async fn test_join_systimer_invoker() {
|
||||
let outcome = test_join_systimer().await;
|
||||
|
||||
embedded_test::export::check_outcome(outcome);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
pub async fn test_interrupt_executor_invoker() {
|
||||
let outcome = test_interrupt_executor().await;
|
||||
|
||||
embedded_test::export::check_outcome(outcome);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn test_tick_and_increment_invoker() {
|
||||
let outcome = tick_and_increment().await;
|
||||
|
||||
embedded_test::export::check_outcome(outcome);
|
||||
}
|
||||
}
|
||||
|
||||
// List of the functions that are ACTUALLY TESTS but are called in the invokers
|
||||
mod test_helpers {
|
||||
use super::*;
|
||||
|
||||
pub async fn test_one_shot_timg() {
|
||||
let peripherals = unsafe { Peripherals::steal() };
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
let timer0: ErasedTimer = timg0.timer0.into();
|
||||
let timers = [OneShotTimer::new(timer0)];
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
|
||||
esp_hal_embassy::init(&clocks, timers);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
Timer::after_millis(500).await;
|
||||
task300ms().await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 500u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
pub async fn test_one_shot_systimer() {
|
||||
let peripherals = unsafe { Peripherals::steal() };
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let systimer = SystemTimer::new(peripherals.SYSTIMER);
|
||||
let alarm0: ErasedTimer = systimer.alarm0.into();
|
||||
let timers = [OneShotTimer::new(alarm0)];
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
|
||||
esp_hal_embassy::init(&clocks, timers);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
Timer::after_millis(500).await;
|
||||
task300ms().await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 500u64);
|
||||
}
|
||||
|
||||
pub async fn test_join_timg() {
|
||||
let peripherals = unsafe { Peripherals::steal() };
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
let timer0: ErasedTimer = timg0.timer0.into();
|
||||
let timers = [OneShotTimer::new(timer0)];
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
|
||||
esp_hal_embassy::init(&clocks, timers);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
embassy_futures::join::join(task500ms(), task300ms()).await;
|
||||
task500ms().await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1_000u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
pub async fn test_join_systimer() {
|
||||
let peripherals = unsafe { Peripherals::steal() };
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let systimer = SystemTimer::new(peripherals.SYSTIMER);
|
||||
let alarm0: ErasedTimer = systimer.alarm0.into();
|
||||
let timers = [OneShotTimer::new(alarm0)];
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
|
||||
esp_hal_embassy::init(&clocks, timers);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
embassy_futures::join::join(task500ms(), task300ms()).await;
|
||||
task500ms().await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1_000u64);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
pub async fn test_interrupt_executor() {
|
||||
let mut ticker = Ticker::every(Duration::from_millis(300));
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
ticker.next().await;
|
||||
ticker.next().await;
|
||||
ticker.next().await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 900u64);
|
||||
}
|
||||
|
||||
pub async fn tick_and_increment() {
|
||||
const HZ: u64 = 100_000u64;
|
||||
let mut counter = 0;
|
||||
let mut ticker = Ticker::every(Duration::from_hz(HZ));
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
let t2;
|
||||
|
||||
loop {
|
||||
ticker.next().await;
|
||||
counter += 1;
|
||||
|
||||
if counter > 100_000 {
|
||||
t2 = esp_hal::time::current_time();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1000u64);
|
||||
assert!((t2 - t1).to_millis() <= 1300u64);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn tick() {
|
||||
const HZ: u64 = 1000u64;
|
||||
let mut ticker = Ticker::every(Duration::from_hz(HZ));
|
||||
pub async fn e_task30ms() {
|
||||
Timer::after_millis(30).await;
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
ticker.next().await;
|
||||
}
|
||||
mod test_cases {
|
||||
use esp_hal::peripheral::Peripheral;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub async fn run_test_one_shot_async() {
|
||||
let t1 = esp_hal::time::current_time();
|
||||
Timer::after_millis(50).await;
|
||||
Timer::after_millis(30).await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1);
|
||||
assert!(
|
||||
(t2 - t1).to_millis() >= 80u64,
|
||||
"diff: {:?}",
|
||||
(t2 - t1).to_millis()
|
||||
);
|
||||
}
|
||||
|
||||
pub async fn task500ms() {
|
||||
Timer::after_millis(500).await;
|
||||
pub fn run_test_periodic_timer<T: esp_hal::timer::Timer>(timer: impl Peripheral<P = T>) {
|
||||
let mut periodic = PeriodicTimer::new(timer);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
periodic.start(100.millis()).unwrap();
|
||||
|
||||
nb::block!(periodic.wait()).unwrap();
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1);
|
||||
assert!(
|
||||
(t2 - t1).to_millis() >= 100u64,
|
||||
"diff: {:?}",
|
||||
(t2 - t1).to_millis()
|
||||
);
|
||||
}
|
||||
|
||||
pub async fn task300ms() {
|
||||
Timer::after_millis(300).await;
|
||||
pub fn run_test_oneshot_timer<T: esp_hal::timer::Timer>(timer: impl Peripheral<P = T>) {
|
||||
let timer = OneShotTimer::new(timer);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
timer.delay_millis(50);
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1);
|
||||
assert!(
|
||||
(t2 - t1).to_millis() >= 50u64,
|
||||
"diff: {:?}",
|
||||
(t2 - t1).to_millis()
|
||||
);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn e_task300ms() {
|
||||
task300ms().await;
|
||||
pub async fn run_join_test() {
|
||||
let t1 = esp_hal::time::current_time();
|
||||
embassy_futures::join::join(Timer::after_millis(50), Timer::after_millis(30)).await;
|
||||
Timer::after_millis(50).await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1);
|
||||
assert!(
|
||||
(t2 - t1).to_millis() >= 100u64,
|
||||
"diff: {:?}",
|
||||
(t2 - t1).to_millis()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
struct Resources {
|
||||
clocks: Clocks<'static>,
|
||||
timg0: esp_hal::peripherals::TIMG0,
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
systimer: esp_hal::peripherals::SYSTIMER,
|
||||
software_interrupt_control: esp_hal::system::SoftwareInterruptControl,
|
||||
}
|
||||
|
||||
impl Resources {
|
||||
fn set_up_embassy_with_timg0(self) {
|
||||
let timg0 = TimerGroup::new(self.timg0, &self.clocks);
|
||||
let timer0: ErasedTimer = timg0.timer0.into();
|
||||
let timers = mk_static!(OneShotTimer<ErasedTimer>, OneShotTimer::new(timer0));
|
||||
esp_hal_embassy::init(&self.clocks, core::slice::from_mut(timers));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
fn set_up_embassy_with_systimer(self) {
|
||||
let systimer = SystemTimer::new(self.systimer);
|
||||
let alarm0: ErasedTimer = systimer.alarm0.into();
|
||||
let timers = mk_static!(OneShotTimer<ErasedTimer>, OneShotTimer::new(alarm0));
|
||||
esp_hal_embassy::init(&self.clocks, core::slice::from_mut(timers));
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,226 +135,174 @@ mod test_helpers {
|
||||
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{task_invokers::*, test_helpers::*};
|
||||
use crate::{test_cases::*, test_helpers::*};
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn run_test_one_shot_timg() {
|
||||
let mut executor = esp_hal_embassy::Executor::new();
|
||||
let executor = unsafe { __make_static(&mut executor) };
|
||||
executor.run(|spawner| {
|
||||
spawner.must_spawn(task_invokers::test_one_shot_timg_invoker());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn run_test_periodic_timg() {
|
||||
let peripherals = Peripherals::take();
|
||||
#[init]
|
||||
fn init() -> Resources {
|
||||
let peripherals = unsafe { Peripherals::steal() };
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
|
||||
let mut periodic = PeriodicTimer::new(timg0.timer0);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
periodic.start(1.secs()).unwrap();
|
||||
|
||||
let t2;
|
||||
loop {
|
||||
nb::block!(periodic.wait()).unwrap();
|
||||
t2 = esp_hal::time::current_time();
|
||||
break;
|
||||
Resources {
|
||||
clocks: ClockControl::boot_defaults(system.clock_control).freeze(),
|
||||
timg0: peripherals.TIMG0,
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
systimer: peripherals.SYSTIMER,
|
||||
software_interrupt_control: system.software_interrupt_control,
|
||||
}
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1_000u64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
async fn test_one_shot_timg(resources: Resources) {
|
||||
resources.set_up_embassy_with_timg0();
|
||||
|
||||
run_test_one_shot_async().await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
fn run_test_one_shot_systimer() {
|
||||
let mut executor = esp_hal_embassy::Executor::new();
|
||||
let executor = unsafe { __make_static(&mut executor) };
|
||||
executor.run(|spawner| {
|
||||
spawner.must_spawn(test_one_shot_systimer_invoker());
|
||||
});
|
||||
async fn test_one_shot_systimer(resources: Resources) {
|
||||
resources.set_up_embassy_with_systimer();
|
||||
|
||||
run_test_one_shot_async().await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn test_periodic_timg(resources: Resources) {
|
||||
let timg0 = TimerGroup::new(resources.timg0, &resources.clocks);
|
||||
|
||||
run_test_periodic_timer(timg0.timer0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
fn run_test_periodic_systimer() {
|
||||
let peripherals = Peripherals::take();
|
||||
fn test_periodic_systimer(resources: Resources) {
|
||||
let systimer = SystemTimer::new(resources.systimer);
|
||||
|
||||
let systimer = SystemTimer::new(peripherals.SYSTIMER);
|
||||
|
||||
let mut periodic = PeriodicTimer::new(systimer.alarm0);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
periodic.start(1.secs()).unwrap();
|
||||
|
||||
let t2;
|
||||
loop {
|
||||
nb::block!(periodic.wait()).unwrap();
|
||||
t2 = esp_hal::time::current_time();
|
||||
break;
|
||||
}
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1_000u64);
|
||||
run_test_periodic_timer(systimer.alarm0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn run_test_periodic_oneshot_timg() {
|
||||
let mut peripherals = Peripherals::take();
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
fn test_periodic_oneshot_timg(mut resources: Resources) {
|
||||
let mut timg0 = TimerGroup::new(&mut resources.timg0, &resources.clocks);
|
||||
run_test_periodic_timer(&mut timg0.timer0);
|
||||
|
||||
let mut timg0 = TimerGroup::new(&mut peripherals.TIMG0, &clocks);
|
||||
|
||||
let mut periodic = PeriodicTimer::new(&mut timg0.timer0);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
periodic.start(1.secs()).unwrap();
|
||||
|
||||
let t2;
|
||||
loop {
|
||||
nb::block!(periodic.wait()).unwrap();
|
||||
t2 = esp_hal::time::current_time();
|
||||
break;
|
||||
}
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1_000u64);
|
||||
|
||||
core::mem::drop(periodic);
|
||||
|
||||
let timg0 = TimerGroup::new(&mut peripherals.TIMG0, &clocks);
|
||||
|
||||
let timer0 = OneShotTimer::new(timg0.timer0);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
timer0.delay_millis(500);
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 500u64);
|
||||
let mut timg0 = TimerGroup::new(&mut resources.timg0, &resources.clocks);
|
||||
run_test_oneshot_timer(&mut timg0.timer0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
fn run_test_periodic_oneshot_systimer() {
|
||||
let mut peripherals = Peripherals::take();
|
||||
fn test_periodic_oneshot_systimer(mut resources: Resources) {
|
||||
let mut systimer = SystemTimer::new(&mut resources.systimer);
|
||||
run_test_periodic_timer(&mut systimer.alarm0);
|
||||
|
||||
let mut systimer = SystemTimer::new(&mut peripherals.SYSTIMER);
|
||||
|
||||
let mut periodic = PeriodicTimer::new(&mut systimer.alarm0);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
periodic.start(1.secs()).unwrap();
|
||||
|
||||
let t2;
|
||||
loop {
|
||||
nb::block!(periodic.wait()).unwrap();
|
||||
t2 = esp_hal::time::current_time();
|
||||
break;
|
||||
}
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 1_000u64);
|
||||
|
||||
core::mem::drop(periodic);
|
||||
|
||||
let systimer = SystemTimer::new(&mut peripherals.SYSTIMER);
|
||||
|
||||
let timer0 = OneShotTimer::new(systimer.alarm0);
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
timer0.delay_millis(500);
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1);
|
||||
assert!((t2 - t1).to_millis() >= 500u64);
|
||||
let mut systimer = SystemTimer::new(&mut resources.systimer);
|
||||
run_test_oneshot_timer(&mut systimer.alarm0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn run_test_join_timg() {
|
||||
let mut executor = esp_hal_embassy::Executor::new();
|
||||
let executor = unsafe { __make_static(&mut executor) };
|
||||
executor.run(|spawner| {
|
||||
spawner.must_spawn(test_join_timg_invoker());
|
||||
});
|
||||
async fn test_join_timg(resources: Resources) {
|
||||
resources.set_up_embassy_with_timg0();
|
||||
|
||||
run_join_test().await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
fn run_test_join_systimer() {
|
||||
let mut executor = esp_hal_embassy::Executor::new();
|
||||
let executor = unsafe { __make_static(&mut executor) };
|
||||
executor.run(|spawner| {
|
||||
spawner.must_spawn(test_join_systimer_invoker());
|
||||
});
|
||||
async fn test_join_systimer(resources: Resources) {
|
||||
resources.set_up_embassy_with_systimer();
|
||||
|
||||
run_join_test().await;
|
||||
}
|
||||
|
||||
/// Test that the ticker works in tasks ran by the interrupt executors.
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
async fn run_test_interrupt_executor() {
|
||||
let spawner = embassy_executor::Spawner::for_current_executor().await;
|
||||
|
||||
let peripherals = Peripherals::take();
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
async fn test_interrupt_executor(resources: Resources) {
|
||||
let timg0 = TimerGroup::new(resources.timg0, &resources.clocks);
|
||||
let timer0: ErasedTimer = timg0.timer0.into();
|
||||
let timer0 = OneShotTimer::new(timer0);
|
||||
|
||||
let timer1 = {
|
||||
let systimer = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER);
|
||||
let alarm0: ErasedTimer = systimer.alarm0.into();
|
||||
OneShotTimer::new(alarm0)
|
||||
};
|
||||
let systimer = SystemTimer::new(resources.systimer);
|
||||
let alarm0: ErasedTimer = systimer.alarm0.into();
|
||||
let timer1 = OneShotTimer::new(alarm0);
|
||||
|
||||
let timers = [timer0, timer1];
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 2], timers);
|
||||
esp_hal_embassy::init(&clocks, timers);
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 2], [timer0, timer1]);
|
||||
esp_hal_embassy::init(&resources.clocks, timers);
|
||||
|
||||
let executor = mk_static!(
|
||||
InterruptExecutor<2>,
|
||||
InterruptExecutor::new(system.software_interrupt_control.software_interrupt2)
|
||||
InterruptExecutor::new(resources.software_interrupt_control.software_interrupt2)
|
||||
);
|
||||
|
||||
#[embassy_executor::task]
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
async fn test_interrupt_executor_invoker() {
|
||||
let outcome = async {
|
||||
let mut ticker = Ticker::every(Duration::from_millis(30));
|
||||
|
||||
let t1 = esp_hal::time::current_time();
|
||||
ticker.next().await;
|
||||
ticker.next().await;
|
||||
ticker.next().await;
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1);
|
||||
assert!(
|
||||
(t2 - t1).to_micros() >= 85000u64,
|
||||
"diff: {:?}",
|
||||
(t2 - t1).to_micros()
|
||||
);
|
||||
};
|
||||
|
||||
embedded_test::export::check_outcome(outcome.await);
|
||||
}
|
||||
|
||||
let spawner_int = executor.start(Priority::Priority3);
|
||||
spawner_int.must_spawn(test_interrupt_executor_invoker());
|
||||
|
||||
spawner.must_spawn(e_task300ms());
|
||||
|
||||
// we need to delay so the e_task300ms() could be spawned
|
||||
task500ms().await;
|
||||
let spawner = embassy_executor::Spawner::for_current_executor().await;
|
||||
spawner.must_spawn(e_task30ms());
|
||||
|
||||
// The test ends once the interrupt executor's task has finished
|
||||
loop {}
|
||||
}
|
||||
|
||||
/// Test that timg0 and systimer don't have vastly different tick rates.
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
async fn run_tick_test_timg() {
|
||||
let spawner = embassy_executor::Spawner::for_current_executor().await;
|
||||
async fn tick_test_timer_tick_rates(resources: Resources) {
|
||||
resources.set_up_embassy_with_timg0();
|
||||
|
||||
let peripherals = unsafe { Peripherals::steal() };
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
// We are retrying 5 times because probe-rs polling RTT may introduce some
|
||||
// jitter.
|
||||
for _ in 0..5 {
|
||||
let t1 = esp_hal::time::current_time();
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
|
||||
let timer0: ErasedTimer = timg0.timer0.into();
|
||||
let timers = [OneShotTimer::new(timer0)];
|
||||
let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
|
||||
esp_hal_embassy::init(&clocks, timers);
|
||||
let mut ticker = Ticker::every(Duration::from_hz(100_000));
|
||||
for _ in 0..2000 {
|
||||
ticker.next().await;
|
||||
}
|
||||
let t2 = esp_hal::time::current_time();
|
||||
|
||||
spawner.must_spawn(tick());
|
||||
tick_and_increment().await;
|
||||
assert!(t2 > t1, "t2: {:?}, t1: {:?}", t2, t1);
|
||||
let duration = (t2 - t1).to_micros();
|
||||
|
||||
assert!(duration >= 19000, "diff: {:?}", (t2 - t1).to_micros());
|
||||
if duration <= 21000 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert!(false, "Test failed after 5 retries");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user