Add the qa-test package (#2558)
* Teach `xtask` about the `qa-test` package * Create the `qa-test` package and move some examples to it * Check `qa-test` package in CI * Add `README.md`
This commit is contained in:
parent
c6404fe569
commit
2472e36232
5
.github/actions/check-esp-hal/action.yml
vendored
5
.github/actions/check-esp-hal/action.yml
vendored
@ -61,3 +61,8 @@ runs:
|
|||||||
CI: 1
|
CI: 1
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cargo +${{ inputs.toolchain }} xtask build-examples esp-hal ${{ inputs.device }} --debug
|
run: cargo +${{ inputs.toolchain }} xtask build-examples esp-hal ${{ inputs.device }} --debug
|
||||||
|
- name: Build (qa-test)
|
||||||
|
env:
|
||||||
|
CI: 1
|
||||||
|
shell: bash
|
||||||
|
run: cargo +${{ inputs.toolchain }} xtask build-examples qa-test ${{ inputs.device }} --debug
|
||||||
|
|||||||
@ -21,6 +21,7 @@ exclude = [
|
|||||||
"extras/esp-wifishark",
|
"extras/esp-wifishark",
|
||||||
"extras/ieee802154-sniffer",
|
"extras/ieee802154-sniffer",
|
||||||
"hil-test",
|
"hil-test",
|
||||||
|
"qa-test",
|
||||||
"xtensa-lx",
|
"xtensa-lx",
|
||||||
"xtensa-lx-rt",
|
"xtensa-lx-rt",
|
||||||
"xtensa-lx-rt/procmacros",
|
"xtensa-lx-rt/procmacros",
|
||||||
|
|||||||
@ -19,7 +19,6 @@ embassy-sync = "0.6.0"
|
|||||||
embassy-time = "0.3.2"
|
embassy-time = "0.3.2"
|
||||||
embassy-usb = { version = "0.2.0", default-features = false }
|
embassy-usb = { version = "0.2.0", default-features = false }
|
||||||
embedded-can = "0.4.1"
|
embedded-can = "0.4.1"
|
||||||
embedded-graphics = "0.8.1"
|
|
||||||
embedded-hal-async = "1.0.0"
|
embedded-hal-async = "1.0.0"
|
||||||
embedded-io = { version = "0.6.1", default-features = false }
|
embedded-io = { version = "0.6.1", default-features = false }
|
||||||
embedded-io-async = "0.6.1"
|
embedded-io-async = "0.6.1"
|
||||||
@ -37,7 +36,6 @@ heapless = "0.8.0"
|
|||||||
hmac = { version = "0.12.1", default-features = false }
|
hmac = { version = "0.12.1", default-features = false }
|
||||||
ieee80211 = { version = "0.4.0", default-features = false }
|
ieee80211 = { version = "0.4.0", default-features = false }
|
||||||
ieee802154 = "0.6.1"
|
ieee802154 = "0.6.1"
|
||||||
lis3dh-async = "0.9.3"
|
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
nb = "1.1.0"
|
nb = "1.1.0"
|
||||||
portable-atomic = { version = "1.9.0", default-features = false }
|
portable-atomic = { version = "1.9.0", default-features = false }
|
||||||
@ -45,7 +43,6 @@ sha2 = { version = "0.10.8", default-features = false }
|
|||||||
smoltcp = { version = "0.11.0", default-features = false, features = [ "medium-ethernet", "socket-raw"] }
|
smoltcp = { version = "0.11.0", default-features = false, features = [ "medium-ethernet", "socket-raw"] }
|
||||||
smoltcp-nal = "0.5.1"
|
smoltcp-nal = "0.5.1"
|
||||||
embedded-time = "=0.12.1"
|
embedded-time = "=0.12.1"
|
||||||
ssd1306 = "0.8.4"
|
|
||||||
static_cell = { version = "2.1.0", features = ["nightly"] }
|
static_cell = { version = "2.1.0", features = ["nightly"] }
|
||||||
trouble-host = { git = "https://github.com/embassy-rs/trouble", package = "trouble-host", rev = "4f1114ce58e96fe54f5ed7e726f66e1ad8d9ce54", features = [ "log", "gatt" ] }
|
trouble-host = { git = "https://github.com/embassy-rs/trouble", package = "trouble-host", rev = "4f1114ce58e96fe54f5ed7e726f66e1ad8d9ce54", features = [ "log", "gatt" ] }
|
||||||
usb-device = "0.3.2"
|
usb-device = "0.3.2"
|
||||||
|
|||||||
33
qa-test/.cargo/config.toml
Normal file
33
qa-test/.cargo/config.toml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
[alias]
|
||||||
|
esp32 = "run --release --features=esp32 --target=xtensa-esp32-none-elf"
|
||||||
|
esp32c2 = "run --release --features=esp32c2 --target=riscv32imc-unknown-none-elf"
|
||||||
|
esp32c3 = "run --release --features=esp32c3 --target=riscv32imc-unknown-none-elf"
|
||||||
|
esp32c6 = "run --release --features=esp32c6 --target=riscv32imac-unknown-none-elf"
|
||||||
|
esp32h2 = "run --release --features=esp32h2 --target=riscv32imac-unknown-none-elf"
|
||||||
|
esp32s2 = "run --release --features=esp32s2 --target=xtensa-esp32s2-none-elf"
|
||||||
|
esp32s3 = "run --release --features=esp32s3 --target=xtensa-esp32s3-none-elf"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "riscv32")']
|
||||||
|
runner = "espflash flash --monitor"
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=-Tlinkall.x",
|
||||||
|
"-C", "force-frame-pointers",
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "xtensa")']
|
||||||
|
runner = "espflash flash --monitor"
|
||||||
|
rustflags = [
|
||||||
|
# GNU LD
|
||||||
|
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||||
|
"-C", "link-arg=-nostartfiles",
|
||||||
|
|
||||||
|
# LLD
|
||||||
|
# "-C", "link-arg=-Tlinkall.x",
|
||||||
|
# "-C", "linker=rust-lld",
|
||||||
|
]
|
||||||
|
|
||||||
|
[env]
|
||||||
|
ESP_LOG = "info"
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
build-std = ["alloc", "core"]
|
||||||
36
qa-test/Cargo.toml
Normal file
36
qa-test/Cargo.toml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
[package]
|
||||||
|
name = "qa-test"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cfg-if = "1.0.0"
|
||||||
|
embassy-executor = { version = "0.6.0", features = ["task-arena-size-12288"] }
|
||||||
|
embassy-time = "0.3.2"
|
||||||
|
embedded-graphics = "0.8.1"
|
||||||
|
embedded-hal-async = "1.0.0"
|
||||||
|
esp-alloc = { path = "../esp-alloc" }
|
||||||
|
esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] }
|
||||||
|
esp-hal = { path = "../esp-hal" }
|
||||||
|
esp-hal-embassy = { path = "../esp-hal-embassy" }
|
||||||
|
esp-println = { path = "../esp-println", features = ["log"] }
|
||||||
|
lis3dh-async = "0.9.3"
|
||||||
|
ssd1306 = "0.8.4"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
esp32 = ["esp-backtrace/esp32", "esp-hal/esp32", "esp-hal-embassy/esp32", "esp-println/esp32"]
|
||||||
|
esp32c2 = ["esp-backtrace/esp32c2", "esp-hal/esp32c2", "esp-hal-embassy/esp32c2", "esp-println/esp32c2"]
|
||||||
|
esp32c3 = ["esp-backtrace/esp32c3", "esp-hal/esp32c3", "esp-hal-embassy/esp32c3", "esp-println/esp32c3"]
|
||||||
|
esp32c6 = ["esp-backtrace/esp32c6", "esp-hal/esp32c6", "esp-hal-embassy/esp32c6", "esp-println/esp32c6"]
|
||||||
|
esp32h2 = ["esp-backtrace/esp32h2", "esp-hal/esp32h2", "esp-hal-embassy/esp32h2", "esp-println/esp32h2"]
|
||||||
|
esp32s2 = ["esp-backtrace/esp32s2", "esp-hal/esp32s2", "esp-hal-embassy/esp32s2", "esp-println/esp32s2"]
|
||||||
|
esp32s3 = ["esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-hal-embassy/esp32s3", "esp-println/esp32s3"]
|
||||||
|
|
||||||
|
embassy-generic-timers = ["embassy-time/generic-queue-8"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
lto = "fat"
|
||||||
|
codegen-units = 1
|
||||||
58
qa-test/README.md
Normal file
58
qa-test/README.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# `qa-test`
|
||||||
|
|
||||||
|
This package contains a number of binary applications intended for manual/quality-assurance testing.
|
||||||
|
|
||||||
|
Each device has its own unique set of peripherals, and as such not every test will run on every device. We recommend building and flashing the tests using the `xtask` method documented below, which will greatly simplify the process.
|
||||||
|
|
||||||
|
To check if a device is compatible with a given test, check the metadata comments above the imports, which will list all supported devices following the `//% CHIPS:` designator. If this metadata is not present, then the test will work on any device supported by `esp-hal`.
|
||||||
|
|
||||||
|
As previously stated, we use the [cargo-xtask] pattern for automation. Commands invoking this tool must be run from the root of the repository.
|
||||||
|
|
||||||
|
[cargo-xtask]: https://github.com/matklad/cargo-xtask
|
||||||
|
|
||||||
|
## Building Tests
|
||||||
|
|
||||||
|
You can build all examples for a given device using the `build-examples` subcommand:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo xtask build-examples qa-test esp32
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that we must specify which package to build the tests for, since this repository contains multiple packages.
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
You can also build and then subsequently flash and run an test using the `run-example` subcommand. With a target device connected to your host system, run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo xtask run-example qa-test esp32c6 hello_world
|
||||||
|
```
|
||||||
|
|
||||||
|
Again, note that we must specify which package to build the test from, plus which test to build and flash to the target device.
|
||||||
|
|
||||||
|
## Adding Tests
|
||||||
|
|
||||||
|
If you are contributing to `esp-hal` and would like to add an test, the process is generally the same as any other project.
|
||||||
|
|
||||||
|
One major difference in our case is the metadata comments which state the compatible devices and required features for an test. Both of these designators are optional; if `//% CHIPS:` is omitted then all devices considered to be supported, and if `//% FEATURES:` is omitted then no features are enabled at build time.
|
||||||
|
|
||||||
|
To demonstrated, in `src/bin/embassy_hello_world.rs` you will see the following:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
|
//% FEATURES: embassy esp-hal-embassy/integrated-timers
|
||||||
|
```
|
||||||
|
|
||||||
|
Another thing to be aware of is the GPIO pins being used. We have tried to use pins available the DevKit-C boards from Espressif, however this is being done on a best-effort basis.
|
||||||
|
|
||||||
|
In general, the following GPIO are recommended for use, though be conscious of whether certain pins are used for UART, strapping pins, etc. on some devices:
|
||||||
|
|
||||||
|
- GPIO0
|
||||||
|
- GPIO1
|
||||||
|
- GPIO2
|
||||||
|
- GPIO3
|
||||||
|
- GPIO4
|
||||||
|
- GPIO5
|
||||||
|
- GPIO8
|
||||||
|
- GPIO9
|
||||||
|
- GPIO10
|
||||||
@ -11,7 +11,7 @@
|
|||||||
//! - SCL => GPIO5
|
//! - SCL => GPIO5
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embassy embassy-generic-timers
|
//% FEATURES: embassy-generic-timers
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
@ -1,7 +1,7 @@
|
|||||||
//! Embassy "async" version of ead calibration data from BMP180 sensor
|
//! Embassy "async" version of ead calibration data from BMP180 sensor
|
||||||
//!
|
//!
|
||||||
//! This example dumps the calibration data from a BMP180 sensor by reading by reading
|
//! This example dumps the calibration data from a BMP180 sensor by reading by
|
||||||
//! with the direct I2C API and the embedded-hal-async I2C API.
|
//! reading with the direct I2C API and the embedded-hal-async I2C API.
|
||||||
//!
|
//!
|
||||||
//! Following pins are used:
|
//! Following pins are used:
|
||||||
//! - SDA => GPIO4
|
//! - SDA => GPIO4
|
||||||
@ -9,10 +9,9 @@
|
|||||||
//!
|
//!
|
||||||
//! Depending on your target and the board you are using you have to change the
|
//! Depending on your target and the board you are using you have to change the
|
||||||
//! pins.
|
//! pins.
|
||||||
//!
|
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embassy embassy-generic-timers
|
//% FEATURES: embassy-generic-timers
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
@ -26,7 +26,7 @@
|
|||||||
//! | XSMT | +3V3 |
|
//! | XSMT | +3V3 |
|
||||||
|
|
||||||
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||||
//% FEATURES: embassy embassy-generic-timers
|
//% FEATURES: embassy-generic-timers
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
@ -1,6 +1,8 @@
|
|||||||
//! Drives the camera on a Freenove ESP32-S3 WROOM (also works as is on the ESP32S3-EYE)
|
//! Drives the camera on a Freenove ESP32-S3 WROOM (also works as is on the
|
||||||
|
//! ESP32S3-EYE)
|
||||||
//!
|
//!
|
||||||
//! This example reads a JPEG from an OV2640 and writes it to the console as hex.
|
//! This example reads a JPEG from an OV2640 and writes it to the console as
|
||||||
|
//! hex.
|
||||||
//!
|
//!
|
||||||
//! The following wiring is assumed:
|
//! The following wiring is assumed:
|
||||||
//! - SIOD => GPIO4
|
//! - SIOD => GPIO4
|
||||||
@ -108,8 +110,8 @@ fn main() -> ! {
|
|||||||
let mut transfer = camera.receive(dma_rx_buf).map_err(|e| e.0).unwrap();
|
let mut transfer = camera.receive(dma_rx_buf).map_err(|e| e.0).unwrap();
|
||||||
|
|
||||||
// Skip the first 2 images. Each image ends with an EOF.
|
// Skip the first 2 images. Each image ends with an EOF.
|
||||||
// We likely missed the first few bytes of the first image and the second image is likely
|
// We likely missed the first few bytes of the first image and the second image
|
||||||
// garbage from the OV2640 focusing, calibrating, etc.
|
// is likely garbage from the OV2640 focusing, calibrating, etc.
|
||||||
// Feel free to skip more images if the one captured below is still garbage.
|
// Feel free to skip more images if the one captured below is still garbage.
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
let mut total_bytes = 0;
|
let mut total_bytes = 0;
|
||||||
@ -81,10 +81,11 @@ fn main() -> ! {
|
|||||||
)
|
)
|
||||||
.with_ctrl_pins(lcd_rs, lcd_wr);
|
.with_ctrl_pins(lcd_rs, lcd_wr);
|
||||||
|
|
||||||
// Note: This isn't provided in the HAL since different drivers may require different
|
// Note: This isn't provided in the HAL since different drivers may require
|
||||||
// considerations, like how to manage the CS pin, the CD pin, cancellation semantics,
|
// different considerations, like how to manage the CS pin, the CD pin,
|
||||||
// 8 vs 16 bit, non-native primitives like Rgb565, Rgb888, etc. This Bus is just provided as
|
// cancellation semantics, 8 vs 16 bit, non-native primitives like Rgb565,
|
||||||
// an example of how to implement your own.
|
// Rgb888, etc. This Bus is just provided as an example of how to implement
|
||||||
|
// your own.
|
||||||
struct Bus<'d> {
|
struct Bus<'d> {
|
||||||
resources: Option<(I8080<'d, Blocking>, DmaTxBuf)>,
|
resources: Option<(I8080<'d, Blocking>, DmaTxBuf)>,
|
||||||
}
|
}
|
||||||
@ -232,16 +233,18 @@ fn main() -> ! {
|
|||||||
chunk.copy_from_slice(&color);
|
chunk.copy_from_slice(&color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Naive implementation of tear prevention. A more robust implementation would use an
|
// Naive implementation of tear prevention. A more robust implementation would
|
||||||
// interrupt handler to start shipping out the next frame the moment the tear effect pin
|
// use an interrupt handler to start shipping out the next frame the
|
||||||
// goes high. async/await would be too slow and would risk missing the inter-refresh window.
|
// moment the tear effect pin goes high. async/await would be too slow
|
||||||
|
// and would risk missing the inter-refresh window.
|
||||||
{
|
{
|
||||||
// Wait for display to start refreshing.
|
// Wait for display to start refreshing.
|
||||||
while tear_effect.is_high() {}
|
while tear_effect.is_high() {}
|
||||||
// Wait for display to finish refreshing.
|
// Wait for display to finish refreshing.
|
||||||
while tear_effect.is_low() {}
|
while tear_effect.is_low() {}
|
||||||
|
|
||||||
// Now we have the maximum amount of time between each refresh available, for drawing.
|
// Now we have the maximum amount of time between each refresh
|
||||||
|
// available, for drawing.
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bytes_left_to_write = total_bytes;
|
let mut bytes_left_to_write = total_bytes;
|
||||||
@ -49,6 +49,7 @@ pub enum Package {
|
|||||||
EspWifi,
|
EspWifi,
|
||||||
Examples,
|
Examples,
|
||||||
HilTest,
|
HilTest,
|
||||||
|
QaTest,
|
||||||
XtensaLx,
|
XtensaLx,
|
||||||
XtensaLxRt,
|
XtensaLxRt,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -221,7 +221,7 @@ fn examples(workspace: &Path, mut args: ExampleArgs, action: CargoAction) -> Res
|
|||||||
let package_path = xtask::windows_safe_path(&workspace.join(args.package.to_string()));
|
let package_path = xtask::windows_safe_path(&workspace.join(args.package.to_string()));
|
||||||
|
|
||||||
let example_path = match args.package {
|
let example_path = match args.package {
|
||||||
Package::Examples => package_path.join("src").join("bin"),
|
Package::Examples | Package::QaTest => package_path.join("src").join("bin"),
|
||||||
Package::HilTest => package_path.join("tests"),
|
Package::HilTest => package_path.join("tests"),
|
||||||
_ => package_path.join("examples"),
|
_ => package_path.join("examples"),
|
||||||
};
|
};
|
||||||
@ -749,7 +749,7 @@ fn lint_packages(workspace: &Path, args: LintPackagesArgs) -> Result<()> {
|
|||||||
|
|
||||||
// We will *not* check the following packages with `clippy`; this
|
// We will *not* check the following packages with `clippy`; this
|
||||||
// may or may not change in the future:
|
// may or may not change in the future:
|
||||||
Package::Examples | Package::HilTest => {}
|
Package::Examples | Package::HilTest | Package::QaTest => {}
|
||||||
|
|
||||||
// By default, no `clippy` arguments are required:
|
// By default, no `clippy` arguments are required:
|
||||||
_ => lint_package(&path, &[], args.fix)?,
|
_ => lint_package(&path, &[], args.fix)?,
|
||||||
@ -788,7 +788,7 @@ fn publish(workspace: &Path, args: PublishArgs) -> Result<()> {
|
|||||||
|
|
||||||
use Package::*;
|
use Package::*;
|
||||||
let mut publish_args = match args.package {
|
let mut publish_args = match args.package {
|
||||||
Examples | HilTest => {
|
Examples | HilTest | QaTest => {
|
||||||
bail!(
|
bail!(
|
||||||
"Invalid package '{}' specified, this package should not be published!",
|
"Invalid package '{}' specified, this package should not be published!",
|
||||||
args.package
|
args.package
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user