mirror of
https://github.com/esp-rs/espflash.git
synced 2026-03-10 15:50:30 +00:00
Use esp-hal runners for HIL (#996)
* ci: Test esp-hal runners for c6 * ci: Test esp32s2 * ci: Remove unused code * ci: Enable all the targets * feat: Add C5 and P4 HIL * feat: Add udev rules with symlink * ci: Run tests on multiple ports * ci: Unfold matrix to have better logging * ci: Enable S2 * feat: Use port aliases * feat: Add c5 elf file * ci: Enable P4 * feat: Avoid code duplication * ci: Remove p4 uart * feat: Update p4 bootloader
This commit is contained in:
parent
5419c6c7ba
commit
15ecc03b8e
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -53,7 +53,7 @@ jobs:
|
||||
arch: "x86_64"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: ./.github/actions/setup-target
|
||||
with:
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
arch: "armhf"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: ./.github/actions/setup-target
|
||||
with:
|
||||
@ -105,7 +105,7 @@ jobs:
|
||||
arch: "armhf"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: ./.github/actions/setup-target
|
||||
with:
|
||||
@ -120,7 +120,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- run: cargo check -p xtask --all-features
|
||||
@ -133,7 +133,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./.github/actions/setup-target
|
||||
|
||||
- run: cargo test --lib
|
||||
@ -146,7 +146,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: clippy
|
||||
@ -159,7 +159,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
with:
|
||||
components: rustfmt
|
||||
|
||||
161
.github/workflows/hil.yml
vendored
161
.github/workflows/hil.yml
vendored
@ -28,95 +28,138 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
|
||||
jobs:
|
||||
build-espflash:
|
||||
name: Build espflash
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: ubuntu:20.04
|
||||
build-packages:
|
||||
name: Build packages | (${{ matrix.target.host }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- host: aarch64
|
||||
target: aarch64-unknown-linux-gnu
|
||||
- host: armv7
|
||||
target: armv7-unknown-linux-gnueabihf
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
repository: ${{ github.event.inputs.repository || github.repository }}
|
||||
ref: ${{ github.event.inputs.branch || github.ref }}
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: apt-get update && apt-get -y install curl musl-tools pkg-config
|
||||
|
||||
- name: Install toolchain
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
|
||||
- name: Build espflash
|
||||
run: $HOME/.cargo/bin/cargo build --release
|
||||
working-directory: espflash
|
||||
|
||||
- name: Build xtask
|
||||
run: $HOME/.cargo/bin/cargo build --release --locked
|
||||
working-directory: xtask
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- name: Install cross
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
name: espflash
|
||||
path: target/release/espflash
|
||||
tool: cross
|
||||
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Build binaries
|
||||
run: cross build --release --target ${{ matrix.target.target }} -p espflash -p xtask
|
||||
|
||||
- name: Upload espflash-${{ matrix.target.host }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: espflash-${{ matrix.target.host }}
|
||||
path: target/${{ matrix.target.target }}/release/espflash
|
||||
if-no-files-found: error
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- name: Upload xtask-${{ matrix.target.host }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xtask
|
||||
path: target/release/xtask
|
||||
name: xtask-${{ matrix.target.host }}
|
||||
path: target/${{ matrix.target.target }}/release/xtask
|
||||
if-no-files-found: error
|
||||
|
||||
run-target:
|
||||
run-packages:
|
||||
if: github.repository_owner == 'esp-rs'
|
||||
name: ${{ matrix.board.mcu }}${{ matrix.board.freq }}
|
||||
needs: build-espflash
|
||||
runs-on:
|
||||
[
|
||||
self-hosted,
|
||||
linux,
|
||||
x64,
|
||||
"${{ matrix.board.mcu }}${{ matrix.board.freq }}",
|
||||
]
|
||||
|
||||
name: HIL | ${{ matrix.target.soc }} | ${{ matrix.target.port }}
|
||||
needs: build-packages
|
||||
runs-on: [self-hosted, "${{ matrix.target.runner }}"]
|
||||
env:
|
||||
ESPFLASH_PORT: /dev/serial_ports/${{ matrix.board.mcu }}
|
||||
ESPFLASH_PORT: /dev/serial_ports/${{ matrix.target.port }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board:
|
||||
- mcu: esp32
|
||||
- mcu: esp32c2
|
||||
freq: -26mhz
|
||||
flag: -x 26mhz
|
||||
- mcu: esp32c3
|
||||
- mcu: esp32c6
|
||||
- mcu: esp32h2
|
||||
- mcu: esp32s2
|
||||
- mcu: esp32s3
|
||||
target:
|
||||
- soc: esp32c2
|
||||
runner: esp32c2-jtag
|
||||
port: uart
|
||||
host: aarch64
|
||||
- soc: esp32c3
|
||||
runner: esp32c3-usb
|
||||
port: usb
|
||||
host: armv7
|
||||
- soc: esp32c5
|
||||
runner: esp32c5-usb
|
||||
port: usb
|
||||
host: aarch64
|
||||
- soc: esp32c5
|
||||
runner: esp32c5-usb
|
||||
port: uart
|
||||
host: aarch64
|
||||
- soc: esp32c6
|
||||
runner: esp32c6-usb
|
||||
port: usb
|
||||
host: armv7
|
||||
- soc: esp32c6
|
||||
runner: esp32c6-usb
|
||||
port: uart
|
||||
host: armv7
|
||||
- soc: esp32h2
|
||||
runner: esp32h2-usb
|
||||
port: usb
|
||||
host: armv7
|
||||
- soc: esp32h2
|
||||
runner: esp32h2-usb
|
||||
port: uart
|
||||
host: armv7
|
||||
- soc: esp32p4
|
||||
runner: esp32p4
|
||||
port: usb
|
||||
host: aarch64
|
||||
- soc: esp32
|
||||
runner: esp32-jtag
|
||||
port: uart
|
||||
host: aarch64
|
||||
- soc: esp32s2
|
||||
runner: esp32s2-jtag
|
||||
port: uart
|
||||
host: armv7
|
||||
- soc: esp32s3
|
||||
runner: esp32s3-usb
|
||||
port: usb
|
||||
host: armv7
|
||||
- soc: esp32s3
|
||||
runner: esp32s3-usb
|
||||
port: uart
|
||||
host: armv7
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: espflash
|
||||
name: espflash-${{ matrix.target.host }}
|
||||
path: espflash_app
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: xtask
|
||||
name: xtask-${{ matrix.target.host }}
|
||||
path: xtask_app
|
||||
|
||||
- name: Set up espflash binary
|
||||
- name: Set up binaries
|
||||
run: |
|
||||
chmod +x espflash_app/espflash
|
||||
echo "$PWD/espflash_app" >> "$GITHUB_PATH"
|
||||
chmod +x xtask_app/xtask
|
||||
echo "$PWD/espflash_app" >> "$GITHUB_PATH"
|
||||
echo "$PWD/xtask_app" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Reset device
|
||||
run: |
|
||||
espflash reset
|
||||
sleep 5
|
||||
|
||||
- name: Run all tests
|
||||
run: xtask run-tests --chip ${{ matrix.board.mcu }} -t 60 --no-build
|
||||
run: xtask run-tests --chip ${{ matrix.target.soc }} -t 60 --no-build
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
||||
arch: "x86_64"
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: ./.github/actions/package
|
||||
with:
|
||||
|
||||
24
espflash/resources/70-espflash.rules
Normal file
24
espflash/resources/70-espflash.rules
Normal file
@ -0,0 +1,24 @@
|
||||
# Copy this file to /etc/udev/rules.d/
|
||||
# If rules fail to reload automatically, you can refresh udev rules
|
||||
# with the command "udevadm control --reload"
|
||||
|
||||
# This rules are based on the udev rules from the OpenOCD project, with unsupported probes removed.
|
||||
# See http://openocd.org/ for more details.
|
||||
#
|
||||
# This file is available under the GNU General Public License v2.0
|
||||
|
||||
ACTION!="add|change", GOTO="espflash_rules_end"
|
||||
|
||||
SUBSYSTEM=="gpio", MODE="0660", GROUP="plugdev", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEM!="usb|tty|hidraw", GOTO="espflash_rules_end"
|
||||
|
||||
# Please keep this list sorted by VID:PID
|
||||
|
||||
# Espressif USB JTAG/serial debug unit and USB Bridge
|
||||
ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", MODE="660", GROUP="plugdev", TAG+="uaccess", SYMLINK+="serial_ports/usb"
|
||||
ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1002", MODE="660", GROUP="plugdev", TAG+="uaccess", SYMLINK+="serial_ports/usb"
|
||||
# Silicon Labs CP210x UART Bridge
|
||||
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", GROUP="plugdev", MODE="660", TAG+="uaccess", SYMLINK+="serial_ports/uart"
|
||||
|
||||
LABEL="espflash_rules_end"
|
||||
Binary file not shown.
@ -37,3 +37,13 @@ cargo build --release
|
||||
|
||||
`esp_hal_binary_with_overlapping_defmt_and_embedded_test_sections` is the ESP-HAL `gpio_unstable` test built for ESP32.
|
||||
This file is used in a unit test in espflash, and is not flashed as a HIL test.
|
||||
|
||||
The `esp32c5` and `esp32p4` elf files under this folder have been generated using `esp-idf@v5.5.2`:
|
||||
```
|
||||
git clone -b v5.5.2 --recursive https://github.com/espressif/esp-idf.git
|
||||
cd esp-idf/
|
||||
./install.sh all
|
||||
cd examples/get-started/hello_world/
|
||||
idf.py set-target $CHIP
|
||||
idf.py build
|
||||
```
|
||||
|
||||
BIN
espflash/tests/data/esp32c5
Executable file
BIN
espflash/tests/data/esp32c5
Executable file
Binary file not shown.
BIN
espflash/tests/data/esp32p4
Executable file
BIN
espflash/tests/data/esp32p4
Executable file
Binary file not shown.
@ -130,6 +130,36 @@ impl TestRunner {
|
||||
Ok((child, output, stdout_handle, stderr_handle))
|
||||
}
|
||||
|
||||
fn run_command_capture_output_with_timeout(
|
||||
cmd: &mut Command,
|
||||
timeout: Duration,
|
||||
test_name: &str,
|
||||
) -> Result<String> {
|
||||
let (mut child, output, h1, h2) = Self::spawn_and_capture_output(cmd)?;
|
||||
let start_time = Instant::now();
|
||||
let mut terminated_naturally = false;
|
||||
|
||||
while start_time.elapsed() < timeout {
|
||||
if let Ok(Some(_)) = child.try_wait() {
|
||||
terminated_naturally = true;
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
|
||||
if !terminated_naturally {
|
||||
log::warn!("{test_name} test timed out after {timeout:?}, terminating process");
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
}
|
||||
|
||||
let _ = h1.join();
|
||||
let _ = h2.join();
|
||||
|
||||
let output = output.lock().unwrap();
|
||||
Ok(output.clone())
|
||||
}
|
||||
|
||||
/// Runs a command with a timeout, returning the exit code
|
||||
pub fn run_command_with_timeout(&self, cmd: &mut Command, timeout: Duration) -> Result<i32> {
|
||||
log::debug!("Running command: {cmd:?}");
|
||||
@ -254,29 +284,8 @@ impl TestRunner {
|
||||
let mut cmd = self.create_espflash_command(args);
|
||||
|
||||
if let Some(expected) = expected_contains {
|
||||
let (mut child, output, h1, h2) = Self::spawn_and_capture_output(&mut cmd)?;
|
||||
let start_time = Instant::now();
|
||||
let mut terminated_naturally = false;
|
||||
|
||||
while start_time.elapsed() < timeout {
|
||||
if let Ok(Some(_)) = child.try_wait() {
|
||||
terminated_naturally = true;
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
|
||||
// If still running, kill it
|
||||
if !terminated_naturally {
|
||||
log::warn!("{test_name} test timed out after {timeout:?}, terminating process");
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
}
|
||||
|
||||
let _ = h1.join();
|
||||
let _ = h2.join();
|
||||
|
||||
let output = output.lock().unwrap();
|
||||
let output =
|
||||
Self::run_command_capture_output_with_timeout(&mut cmd, timeout, test_name)?;
|
||||
for &expected in expected {
|
||||
if !output.contains(expected) {
|
||||
Self::restore_terminal();
|
||||
@ -538,12 +547,20 @@ impl TestRunner {
|
||||
|
||||
/// Tests listing available ports
|
||||
pub fn test_list_ports(&self) -> Result<()> {
|
||||
self.run_simple_command_test(
|
||||
&["list-ports"],
|
||||
Some(&["Silicon Labs"]),
|
||||
Duration::from_secs(10),
|
||||
"list-ports",
|
||||
)?;
|
||||
log::info!("Running list-ports test");
|
||||
let mut cmd = self.create_espflash_command(&["list-ports"]);
|
||||
let timeout = Duration::from_secs(10);
|
||||
let output =
|
||||
Self::run_command_capture_output_with_timeout(&mut cmd, timeout, "list-ports")?;
|
||||
// Accept either "Silicon Labs" or "Espressif" in the output
|
||||
if !output.contains("Silicon Labs") && !output.contains("Espressif") {
|
||||
Self::restore_terminal();
|
||||
return Err(
|
||||
"Missing expected output: neither 'Silicon Labs' nor 'Espressif' found".into(),
|
||||
);
|
||||
}
|
||||
|
||||
log::info!("list-ports test passed and output verified");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user