Enable C3, H2, S2 and S3 HIL (#1513)

* ci: Enable C3, H2, S2 and S3 HIL tests

* feat: Disable H2

* test: Disable S2

* ci: Update test folder

* docs: Update setup

* revert: Revert S2 changes

* ci: Update hil tests targets

* test: Adapt uart test for S2

* ci: Enable H2 HIL

* feat: Filter unsupported targets for the tests failing

* test: Filter failing targets

* ci: Remove the test folder

* test: Filter S2

* feat: Add supported targets

* feat: Remove TODOs and format code

* docs: Remove outdated comment

* feat: Add run-elfs xtask subcommand
This commit is contained in:
Sergio Gasquez Arcos 2024-05-02 17:35:23 +02:00 committed by GitHub
parent 68a4fb29ed
commit edd03717d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 138 additions and 57 deletions

View File

@ -318,6 +318,7 @@ jobs:
- soc: esp32h2 - soc: esp32h2
rust-target: riscv32imac-unknown-none-elf rust-target: riscv32imac-unknown-none-elf
# Xtensa devices: # Xtensa devices:
- soc: esp32s2
- soc: esp32s3 - soc: esp32s3
steps: steps:
@ -339,4 +340,4 @@ jobs:
ldproxy: false ldproxy: false
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- run: cargo xtask build-examples hil-test ${{ matrix.target.soc }} - run: cargo xtask build-tests ${{ matrix.target.soc }}

View File

@ -26,18 +26,21 @@ jobs:
matrix: matrix:
target: target:
# RISC-V devices: # RISC-V devices:
# - soc: esp32c3 - soc: esp32c3
# rust-target: riscv32imc-unknown-none-elf rust-target: riscv32imc-unknown-none-elf
- soc: esp32c6 - soc: esp32c6
rust-target: riscv32imac-unknown-none-elf rust-target: riscv32imac-unknown-none-elf
# - soc: esp32h2 - soc: esp32h2
# rust-target: riscv32imac-unknown-none-elf rust-target: riscv32imac-unknown-none-elf
# # Xtensa devices: # # Xtensa devices:
# - soc: esp32s3 - soc: esp32s2
rust-target: xtensa-esp32s2-none-elf
- soc: esp32s3
rust-target: xtensa-esp32s3-none-elf
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
if: github.event_name != 'workflow_dispatch' if: github.event_name != 'workflow_dispatch'
- uses: actions/checkout@v4 - uses: actions/checkout@v4
if: github.event_name == 'workflow_dispatch' if: github.event_name == 'workflow_dispatch'
with: with:
@ -59,7 +62,7 @@ jobs:
default: true default: true
ldproxy: false ldproxy: false
- name: Run tests - name: Build tests
run: cargo xtask build-tests ${{ matrix.target.soc }} run: cargo xtask build-tests ${{ matrix.target.soc }}
- name: Prepare artifact - name: Prepare artifact
@ -78,12 +81,12 @@ jobs:
base_name="$(basename "$file" | cut -d'-' -f1)" base_name="$(basename "$file" | cut -d'-' -f1)"
mv "$file" "tests/$base_name" mv "$file" "tests/$base_name"
done done
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: tests-${{ matrix.target.soc }} name: tests-${{ matrix.target.soc }}
path: /home/runner/work/esp-hal/esp-hal/tests path: /home/runner/work/esp-hal/esp-hal/tests
if-no-files-found: error if-no-files-found: error
overwrite: true
hil: hil:
name: HIL Test | ${{ matrix.target.soc }} name: HIL Test | ${{ matrix.target.soc }}
@ -95,24 +98,25 @@ jobs:
matrix: matrix:
target: target:
# RISC-V devices: # RISC-V devices:
# - soc: esp32c3 - soc: esp32c3
# runner: rustboard runner: esp32c3-usb
- soc: esp32c6 - soc: esp32c6
runner: esp32c6-usb runner: esp32c6-usb
# - soc: esp32h2 - soc: esp32h2
# runner: esp32h2-usb runner: esp32h2-usb
# # Xtensa devices: # Xtensa devices:
# - soc: esp32s3 - soc: esp32s2
# runner: esp32s3-usb runner: esp32s2-jtag
- soc: esp32s3
runner: esp32s3-usb
steps: steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: tests-${{ matrix.target.soc }} name: tests-${{ matrix.target.soc }}
path: tests path: tests-${{ matrix.target.soc }}
- name: Run tests
- name: Run Tests
run: | run: |
export PATH=$PATH:/home/espressif/.cargo/bin export PATH=$PATH:/home/espressif/.cargo/bin
for file in "tests"/*; do cargo xtask run-elfs ${{ matrix.target.soc }} tests-${{ matrix.target.soc }}
probe-rs run --chip ${{ matrix.target.soc }} "$file"
done

View File

@ -19,11 +19,9 @@ We use [embedded-test] as our testing framework, which relies on [defmt] interna
We use [probe-rs] for flashing and running the tests on a target device, however, this **MUST** be installed from the correct revision, and with the correct features enabled: We use [probe-rs] for flashing and running the tests on a target device, however, this **MUST** be installed from the correct revision, and with the correct features enabled:
```text ```text
cargo install probe-rs \ cargo install probe-rs-tools \
--git=https://github.com/probe-rs/probe-rs \ --git https://github.com/probe-rs/probe-rs \
--rev=ddd59fa \ --rev 4dc1701 --force --locked
--features=cli \
--bin=probe-rs
``` ```
Target device **MUST** connected via its USB-Serial-JTAG port, or if unavailable (eg. ESP32, ESP32-C2, ESP32-S2) then you must connect a compatible debug probe such as an [ESP-Prog]. Target device **MUST** connected via its USB-Serial-JTAG port, or if unavailable (eg. ESP32, ESP32-C2, ESP32-S2) then you must connect a compatible debug probe such as an [ESP-Prog].
@ -61,7 +59,7 @@ Our Virtual Machines have the following setup:
- ESP32-C3 (`rustboard`): - ESP32-C3 (`rustboard`):
- Devkit: `ESP32-C3-DevKit-RUST-1` connected via USB-Serial-JTAG. - Devkit: `ESP32-C3-DevKit-RUST-1` connected via USB-Serial-JTAG.
- `GPIO2` and `GPIO4` are connected. - `GPIO2` and `GPIO4` are connected.
- VM: Ubuntu 20.04.5 configured with the following [setup](#vm-setup) - RPi: Raspbian 12 configured with the following [setup](#vm-setup)
- ESP32-C6 (`esp32c6-usb`): - ESP32-C6 (`esp32c6-usb`):
- Devkit: `ESP32-C6-DevKitC-1 V1.2` connected via USB-Serial-JTAG (`USB` port). - Devkit: `ESP32-C6-DevKitC-1 V1.2` connected via USB-Serial-JTAG (`USB` port).
- `GPIO2` and `GPIO4` are connected. - `GPIO2` and `GPIO4` are connected.
@ -69,11 +67,16 @@ Our Virtual Machines have the following setup:
- ESP32-H2 (`esp32h2-usb`): - ESP32-H2 (`esp32h2-usb`):
- Devkit: `ESP32-H2-DevKitM-1` connected via USB-Serial-JTAG (`USB` port). - Devkit: `ESP32-H2-DevKitM-1` connected via USB-Serial-JTAG (`USB` port).
- `GPIO2` and `GPIO4` are connected. - `GPIO2` and `GPIO4` are connected.
- VM: Ubuntu 20.04.5 configured with the following [setup](#vm-setup) - RPi: Raspbian 12 configured with the following [setup](#vm-setup)
- ESP32-S2 (`esp32s2-jtag`):
- Devkit: `ESP32-S2-Saola-1` connected via UART.
- `GPIO2` and `GPIO4` are connected.
- Probe: `ESP-Prog` connected with the [following connections](https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-guides/jtag-debugging/configure-other-jtag.html#configure-hardware)
- RPi: Raspbian 12 configured with the following [setup](#vm-setup)
- ESP32-S3 (`esp32s3-usb`): - ESP32-S3 (`esp32s3-usb`):
- Devkit: `ESP32-S3-DevKitC-1` connected via USB-Serial-JTAG. - Devkit: `ESP32-S3-DevKitC-1` connected via USB-Serial-JTAG.
- `GPIO2` and `GPIO4` are connected. - `GPIO2` and `GPIO4` are connected.
- VM: Ubuntu 22.04.4 configured with the following [setup](#vm-setup) - RPi: Raspbian 12 configured with the following [setup](#vm-setup)
[`hil.yml`]: https://github.com/esp-rs/esp-hal/blob/main/.github/workflows/hil.yml [`hil.yml`]: https://github.com/esp-rs/esp-hal/blob/main/.github/workflows/hil.yml
@ -86,7 +89,7 @@ source "$HOME/.cargo/env"
# Install dependencies # Install dependencies
sudo apt install -y pkg-config libudev-dev sudo apt install -y pkg-config libudev-dev
# Install probe-rs # Install probe-rs
cargo install probe-rs --git=https://github.com/probe-rs/probe-rs --rev=ddd59fa --features=cli --bin=probe-rs --locked --force cargo install probe-rs-tools --git https://github.com/probe-rs/probe-rs --rev 4dc1701 --force
# Add the udev rules # Add the udev rules
wget -O - https://probe.rs/files/69-probe-rs.rules | sudo tee /etc/udev/rules.d/69-probe-rs.rules > /dev/null wget -O - https://probe.rs/files/69-probe-rs.rules | sudo tee /etc/udev/rules.d/69-probe-rs.rules > /dev/null
# Add the user to plugdev group # Add the user to plugdev group

View File

@ -1,5 +1,7 @@
//! Delay Test //! Delay Test
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32s3
#![no_std] #![no_std]
#![no_main] #![no_main]

View File

@ -1,6 +1,6 @@
//! current_time Test //! current_time Test
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32s2 esp32s3
#![no_std] #![no_std]
#![no_main] #![no_main]

View File

@ -4,6 +4,8 @@
//! GPIO2 //! GPIO2
//! GPIO4 //! GPIO4
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
#![no_std] #![no_std]
#![no_main] #![no_main]
@ -151,7 +153,6 @@ mod tests {
} }
#[test] #[test]
// TODO: See https://github.com/esp-rs/esp-hal/issues/1413
#[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))] #[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))]
fn test_gpio_interrupt(mut ctx: Context) { fn test_gpio_interrupt(mut ctx: Context) {
critical_section::with(|cs| { critical_section::with(|cs| {

View File

@ -8,6 +8,8 @@
//! //!
//! Connect MISO (GPIO2) and MOSI (GPIO4) pins. //! Connect MISO (GPIO2) and MOSI (GPIO4) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
#![no_std] #![no_std]
#![no_main] #![no_main]

View File

@ -8,7 +8,7 @@
//! //!
//! Connect MISO (GPIO2) and MOSI (GPIO4) pins. //! Connect MISO (GPIO2) and MOSI (GPIO4) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s3
#![no_std] #![no_std]
#![no_main] #![no_main]
@ -120,7 +120,7 @@ mod tests {
let transfer = spi.dma_transfer(&mut send, &mut receive).unwrap(); let transfer = spi.dma_transfer(&mut send, &mut receive).unwrap();
transfer.wait().unwrap(); transfer.wait().unwrap();
assert_eq!(send[0], receive[0]); assert_eq!(send[0..1], receive[0..1]);
} }
#[test] #[test]

View File

@ -6,6 +6,8 @@
//! //!
//! Connect TX (GPIO2) and RX (GPIO4) pins. //! Connect TX (GPIO2) and RX (GPIO4) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
#![no_std] #![no_std]
#![no_main] #![no_main]
@ -106,22 +108,43 @@ mod tests {
// working as expected. We will also using different clock sources // working as expected. We will also using different clock sources
// while we're at it. // while we're at it.
// 9600 baud, RC FAST clock source: #[cfg(not(feature = "esp32s2"))]
ctx.uart.change_baud(9600, ClockSource::RcFast, &ctx.clocks); {
ctx.uart.write(7).ok(); #[cfg(not(feature = "esp32c3"))]
let read = block!(ctx.uart.read()); {
assert_eq!(read, Ok(7)); // 9600 baud, RC FAST clock source:
ctx.uart.change_baud(9600, ClockSource::RcFast, &ctx.clocks);
ctx.uart.write(7).ok();
let read = block!(ctx.uart.read());
assert_eq!(read, Ok(7));
}
// 19,200 baud, XTAL clock source: // 19,200 baud, XTAL clock source:
ctx.uart.change_baud(19_200, ClockSource::Xtal, &ctx.clocks); ctx.uart.change_baud(19_200, ClockSource::Xtal, &ctx.clocks);
ctx.uart.write(55).ok(); ctx.uart.write(55).ok();
let read = block!(ctx.uart.read()); let read = block!(ctx.uart.read());
assert_eq!(read, Ok(55)); assert_eq!(read, Ok(55));
// 921,600 baud, APB clock source: // 921,600 baud, APB clock source:
ctx.uart.change_baud(921_600, ClockSource::Apb, &ctx.clocks); ctx.uart.change_baud(921_600, ClockSource::Apb, &ctx.clocks);
ctx.uart.write(253).ok(); ctx.uart.write(253).ok();
let read = block!(ctx.uart.read()); let read = block!(ctx.uart.read());
assert_eq!(read, Ok(253)); assert_eq!(read, Ok(253));
}
#[cfg(feature = "esp32s2")]
{
// 9600 baud, REF TICK clock source:
ctx.uart
.change_baud(9600, ClockSource::RefTick, &ctx.clocks);
ctx.uart.write(7).ok();
let read = block!(ctx.uart.read());
assert_eq!(read, Ok(7));
// 921,600 baud, APB clock source:
ctx.uart.change_baud(921_600, ClockSource::Apb, &ctx.clocks);
ctx.uart.write(253).ok();
let read = block!(ctx.uart.read());
assert_eq!(read, Ok(253));
}
} }
} }

View File

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

View File

@ -257,14 +257,12 @@ pub fn execute_app(
format!("--example={}", app.name()) format!("--example={}", app.name())
}; };
(bin, "build") (bin, "build")
} else if package.starts_with("src/bin") {
(format!("--bin={}", app.name()), "run")
} else if package.starts_with("tests") {
(format!("--test={}", app.name()), "test")
} else { } else {
if package.starts_with("src/bin") { (format!("--example={}", app.name()), "run")
(format!("--bin={}", app.name()), "run")
} else if package.starts_with("tests") {
(format!("--test={}", app.name()), "test")
} else {
(format!("--example={}", app.name()), "run")
}
}; };
let mut features = app.features().to_vec(); let mut features = app.features().to_vec();

View File

@ -1,6 +1,7 @@
use std::{ use std::{
fs, fs,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::Command,
}; };
use anyhow::{bail, Result}; use anyhow::{bail, Result};
@ -29,6 +30,8 @@ enum Cli {
RunExample(RunExampleArgs), RunExample(RunExampleArgs),
/// Run all applicable tests or the specified test for a specified chip. /// Run all applicable tests or the specified test for a specified chip.
RunTests(TestsArgs), RunTests(TestsArgs),
/// Run all ELFs in a folder.
RunElfs(RunElfArgs),
} }
#[derive(Debug, Args)] #[derive(Debug, Args)]
@ -114,6 +117,15 @@ struct TestsArgs {
test: Option<String>, test: Option<String>,
} }
#[derive(Debug, Args)]
struct RunElfArgs {
/// Which chip to run the tests for.
#[arg(value_enum)]
chip: Chip,
/// Path to the ELFs.
path: PathBuf,
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Application // Application
@ -134,6 +146,7 @@ fn main() -> Result<()> {
Cli::GenerateEfuseFields(args) => generate_efuse_src(&workspace, args), Cli::GenerateEfuseFields(args) => generate_efuse_src(&workspace, args),
Cli::RunExample(args) => run_example(&workspace, args), Cli::RunExample(args) => run_example(&workspace, args),
Cli::RunTests(args) => execute_tests(&workspace, args, CargoAction::Run), Cli::RunTests(args) => execute_tests(&workspace, args, CargoAction::Run),
Cli::RunElfs(args) => run_elfs(args),
} }
} }
@ -396,6 +409,38 @@ fn execute_tests(
Ok(()) Ok(())
} }
fn run_elfs(args: RunElfArgs) -> Result<(), anyhow::Error> {
let elfs = fs::read_dir(&args.path)?;
let mut failed_elfs: Vec<String> = Vec::new();
for elf in elfs {
let elf = elf?;
let elf_path = elf.path();
let elf_name = elf_path.file_name().unwrap().to_str().unwrap();
let elf_name = elf_name.split('.').next().unwrap();
let elf_name = elf_name.to_string();
println!("Running '{}' test", elf_name);
let command = Command::new("probe-rs")
.arg("run")
.arg("--chip")
.arg(args.chip.to_string())
.arg(elf_path)
.output()
.expect("Failed to execute probe-rs run command");
let stdout = String::from_utf8_lossy(&command.stdout);
let stderr = String::from_utf8_lossy(&command.stderr);
println!("{}\n{}", stderr, stdout);
if !command.status.success() {
failed_elfs.push(elf_name);
}
}
if !failed_elfs.is_empty() {
bail!("Failed tests: {:?}", failed_elfs);
}
Ok(())
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Helper Functions // Helper Functions