HIL: Multiple featuresets & conditionally enable generic-queue feature (#1989)

* Conditionally enable generic-queue feature

* Allow specifying multiple feature sets and run all of them
This commit is contained in:
Dániel Buga 2024-08-26 08:19:03 +02:00 committed by GitHub
parent 0e333f7aa2
commit b4ccb359ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 72 additions and 30 deletions

View File

@ -136,7 +136,7 @@ required-features = ["async", "embassy"]
[[test]]
name = "embassy_interrupt_executor"
harness = false
required-features = ["async", "embassy", "integrated-timers"]
required-features = ["async", "embassy"]
[[test]]
name = "twai"
@ -149,7 +149,7 @@ defmt = "0.3.8"
defmt-rtt = { version = "0.4.1", optional = true }
embassy-futures = "0.1.1"
embassy-sync = "0.6.0"
embassy-time = { version = "0.3.1", features = ["generic-queue-64"] }
embassy-time = { version = "0.3.1" }
embedded-hal = "1.0.0"
embedded-hal-02 = { version = "0.2.7", package = "embedded-hal", features = ["unproven"] }
embedded-hal-async = { version = "1.0.0", optional = true }
@ -214,8 +214,11 @@ embassy = [
"embedded-test/external-executor",
"dep:esp-hal-embassy",
]
generic-queue = [
"embassy-time/generic-queue-64"
]
integrated-timers = [
"embassy-executor/integrated-timers",
"esp-hal-embassy/integrated-timers",
]
# https://doc.rust-lang.org/cargo/reference/profiles.html#test

View File

@ -3,11 +3,21 @@
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: integrated-timers
//% FEATURES: generic-queue
#![no_std]
#![no_main]
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal};
use esp_hal::{
clock::ClockControl,
interrupt::Priority,
peripherals::Peripherals,
system::{SoftwareInterrupt, SystemControl},
timer::timg::TimerGroup,
};
use esp_hal_embassy::InterruptExecutor;
use hil_test as _;
macro_rules! mk_static {
($t:ty,$val:expr) => {{
@ -26,24 +36,19 @@ async fn interrupt_driven_task(signal: &'static Signal<CriticalSectionRawMutex,
}
#[cfg(test)]
#[embedded_test::tests]
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
mod test {
use esp_hal::{
clock::ClockControl,
interrupt::Priority,
peripherals::Peripherals,
system::{SoftwareInterrupt, SystemControl},
};
use esp_hal_embassy::InterruptExecutor;
use hil_test as _;
use super::*;
#[init]
fn init() -> SoftwareInterrupt<1> {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
esp_hal_embassy::init(&clocks, timg0.timer0);
system.software_interrupt_control.software_interrupt1
}

View File

@ -1,6 +1,8 @@
//! Embassy timer and executor Test
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: integrated-timers
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -5,6 +5,7 @@
//! GPIO3
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -6,6 +6,7 @@
//! with loopback mode enabled). It's using circular DMA mode
//% CHIPS: esp32c3 esp32c6 esp32s3 esp32h2
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -1,6 +1,7 @@
//! lcd_cam i8080 tests
//% CHIPS: esp32s3
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -15,6 +15,7 @@
//! Connect PCNT (GPIO2) and MOSI (GPIO3) and MISO (GPIO6) and GPIO5 pins.
//% CHIPS: esp32 esp32c6 esp32h2 esp32s3
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -7,6 +7,7 @@
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -7,6 +7,7 @@
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: generic-queue
#![no_std]
#![no_main]

View File

@ -57,11 +57,11 @@ pub enum Package {
pub struct Metadata {
example_path: PathBuf,
chips: Vec<Chip>,
features: Vec<String>,
feature_sets: Vec<Vec<String>>,
}
impl Metadata {
pub fn new(example_path: &Path, chips: Vec<Chip>, features: Vec<String>) -> Self {
pub fn new(example_path: &Path, chips: Vec<Chip>, feature_sets: Vec<Vec<String>>) -> Self {
let chips = if chips.is_empty() {
Chip::iter().collect()
} else {
@ -71,7 +71,7 @@ impl Metadata {
Self {
example_path: example_path.to_path_buf(),
chips,
features,
feature_sets,
}
}
@ -90,8 +90,8 @@ impl Metadata {
}
/// A list of all features required for building a given examples.
pub fn features(&self) -> &[String] {
&self.features
pub fn feature_sets(&self) -> &[Vec<String>] {
&self.feature_sets
}
/// If the specified chip is in the list of chips, then it is supported.
@ -155,7 +155,7 @@ pub fn load_examples(path: &Path) -> Result<Vec<Metadata>> {
.with_context(|| format!("Could not read {}", path.display()))?;
let mut chips = Vec::new();
let mut features = Vec::new();
let mut feature_sets = Vec::new();
// We will indicate metadata lines using the `//%` prefix:
for line in text.lines().filter(|line| line.starts_with("//%")) {
@ -183,13 +183,13 @@ pub fn load_examples(path: &Path) -> Result<Vec<Metadata>> {
.map(|s| Chip::from_str(s, false).unwrap())
.collect::<Vec<_>>();
} else if key == "FEATURES" {
features = split.into();
feature_sets.push(split.into());
} else {
log::warn!("Unrecognized metadata key '{key}', ignoring");
}
}
examples.push(Metadata::new(&path, chips, features));
examples.push(Metadata::new(&path, chips, feature_sets));
}
Ok(examples)
@ -202,19 +202,45 @@ pub fn execute_app(
target: &str,
app: &Metadata,
action: CargoAction,
mut repeat: usize,
repeat: usize,
) -> Result<()> {
log::info!(
"Building example '{}' for '{}'",
app.example_path().display(),
chip
);
if !app.features().is_empty() {
log::info!(" Features: {}", app.features().join(","));
let feature_sets = if app.feature_sets().is_empty() {
vec![vec![]]
} else {
app.feature_sets().to_vec()
};
for features in feature_sets {
execute_app_with_features(package_path, chip, target, app, action, repeat, features)?;
}
Ok(())
}
/// Run or build the specified test or example for the specified chip, with the
/// specified features enabled.
pub fn execute_app_with_features(
package_path: &Path,
chip: Chip,
target: &str,
app: &Metadata,
action: CargoAction,
mut repeat: usize,
mut features: Vec<String>,
) -> Result<()> {
if !features.is_empty() {
log::info!("Features: {}", features.join(","));
}
features.push(chip.to_string());
let package = app.example_path().strip_prefix(package_path)?;
log::info!("Package: {:?}", package);
log::info!("Package: {}", package.display());
let (bin, subcommand) = if action == CargoAction::Build {
repeat = 1; // Do not repeat builds in a loop
let bin = if package.starts_with("src/bin") {
@ -233,9 +259,6 @@ pub fn execute_app(
(format!("--example={}", app.name()), "run")
};
let mut features = app.features().to_vec();
features.push(chip.to_string());
let mut builder = CargoArgsBuilder::default()
.subcommand(subcommand)
.arg("--release")
@ -256,7 +279,10 @@ pub fn execute_app(
let args = builder.build();
log::debug!("{args:#?}");
for _ in 0..repeat {
for i in 0..repeat {
if repeat != 1 {
log::info!("Run {}/{}", i + 1, repeat);
}
cargo::run(&args, package_path)?;
}