Skip to content

Commit

Permalink
Merge pull request #14 from hydrausb3/pass_stress_test
Browse files Browse the repository at this point in the history
v1.1.2
  • Loading branch information
kauwua committed Jul 16, 2024
2 parents 25ea723 + f2edf2c commit 9041c32
Show file tree
Hide file tree
Showing 28 changed files with 1,856 additions and 476 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: check-yaml
- id: check-added-large-files
- id: check-merge-conflict
- repo: https://github.com/hhatto/autopep8
rev: v2.0.4
rev: v2.3.1
hooks:
- id: autopep8
- repo: https://github.com/pylint-dev/pylint
rev: v3.0.2
rev: v3.2.5
hooks:
- id: pylint
- repo: https://github.com/pre-commit/mirrors-clang-format
Expand Down
6 changes: 5 additions & 1 deletion BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,13 @@ Currently, you need two HydraUSB3 boards connected together via HSPI. You just n
To be able to access the HydraDancer boards and flash them, root privileges may be required, or you can provide them to your regular user, e.g. with the creation of a file `/etc/udev/rules.d/99-hydrausb3.rules` with

```
# UDEV Rules for HydraUSB3 boards, https://github.com/hydrausb3
# UDEV Rules for HydraUSB3 boards https://github.com/hydrausb3, Hydradancer https://github.com/HydraDancer/hydradancer_fw and Facedancer https://github.com/greatscottgadgets/Facedancer
# WinChipHead CH569W Bootloader
SUBSYSTEMS=="usb", ATTRS{idVendor}=="4348", ATTRS{idProduct}=="55e0", MODE="0664", GROUP="plugdev"
# Hydradancer test
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="27d8", MODE="0664", GROUP="plugdev"
# Facedancer stress test
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="0001", MODE="0664", GROUP="plugdev"
```

and having your user as member of the group `plugdev`.
Expand Down
47 changes: 5 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This library was built alongside [Hydradancer](https://github.com/HydraDancer/hydradancer_fw), a new backend for the Facedancer USB emulation library based on the WCH569 chip.

Reliable drivers were needed for this project and many features were missing from the WCH examples, or untested.
Reliable drivers were needed for this project and many features were missing from the WCH examples or untested.

This library provides USB3, USB2, HSPI and SerDes drivers that have been tested using the benchmark/integrity tests in `tests/`. It is based on `wch-ch56x-bsp` but its goal is to provide a higher level library. As Hydradancer was using several peripherals at a time (USB3/HSPI, USB2/HSPI), an interrupt queue was implemented to avoid missing interrupts for use with `HSPIDeviceScheduled` along with a static memory pool. While the tests in this repository are simple enough to do the processing inside the interrupt handlers, Hydradancer was missing interrupts and deferring interrupts to user mode was required.

Expand All @@ -18,49 +18,16 @@ Available options
* POOL_BLOCK_SIZE, POOL_BLOCK_NUM
* INTERRUPT_QUEUE_SIZE

# Building the tests
# Building the tests and compilation details

To build and flash the firmware, see [the build tutorial](BUILD.md).

More information on compilation options can also be found there.

# More details on compilation

This project uses one or two HydraUSB3 boards, which are based on the WCH569 RISCV MCU.

## Build options

Those options can be set the following way

```shell
cmake --toolchain ../cmake/wch-ch56x-toolchain.cmake -DCMAKE_BUILD_TYPE=release -DOPTION_1=1 -DOPTION_2=1 -B build .
```

- `-DCMAKE_BUILD_TYPE=Debug` use debug optimization
- `-DBUILD_TESTS=1` build the tests

Most warnings will be considered as errors.

## More options

You can set different options to activate more flags, static analysis or the logging system.

Those flags can either be set as build options (but they will apply to all projects) by passing a `-DOPTION=value` to CMake, or by adding a `set(option_name value)` in the project `CMakeLists.txt`.

- `STATIC_ANALYSIS` : activate GCC's built-in static analysers
- `EXTRACFLAGS` : activate -Wconversion and -Wsign-compare

## Logging options

Several logging options can get you infos on different parts of the library/firmwares. By default, no logs are activated so there is no impact on performances.

- Log methods
- `LOG_OUTPUT=printf`. Logs are written directly to the UART
- `LOG_OUTPUT=buffer`. Logs are stored in a buffer, and flushed to the UART when calling `LOG_DUMP()`
- `LOG_OUTPUT=serdes`. Logs are directly sent using Serdes. Might be used to share logs from one board to the other.
- Log levels
- `LOG_OUTPUT=x LOG_LEVEL=y`. With y=1(LOG_LEVEL_CRITICAL), y=2(LOG_LEVEL_ERROR), y=3(LOG_LEVEL_WARNING), y=4(LOG_LEVEL_INFO), y=5(LOG_LEVEL_DEBUG). All levels <=y will be displayed.
- Log filters
- `LOG_OUTPUT=x LOG_FILTER_IDS=a,b,c, ...` You can set any number of filters from the following list 1(LOG_ID_USER), 2(LOG_ID_USB2), 3(LOG_ID_USB3), 4(LOG_ID_HSPI), 5(LOG_ID_SERDES), 6(LOG_ID_INTERRUPT_QUEUE), 7(LOG_ID_RAMX_ALLOC). If `LOG_LEVEL` is also defined, the logs with IDs will only be displayed if they have the right level.

# Structure of the project

```
Expand All @@ -74,11 +41,7 @@ wch-ch56x-lib/

# Tests

There are no automated tests for now, but that doesn't mean tests are not required.

For now, the tests in hydradancer/tests consist in loop-back devices, to test for integrity and benchmark the speed of the device in different scenarios.

More information about the different scenarios can be found in [docs/Testing.md](docs/Testing.md).
More information about the different tests and how to use them can be found in [docs/Testing.md](docs/Testing.md)

# How to contribute

Expand Down
28 changes: 21 additions & 7 deletions docs/Testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Below are the different test cases and how to test them:
### Unittests

* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash to one board, and read its UART.
* Run : flash `test_firmware_unittests.bin` to one board, and read its UART.

The firmware will simply execute a list of functions returning either `true` or `false`, to check if the test has passed.

Expand All @@ -55,36 +55,50 @@ Those "unittests" are a way to get some certainty about edge cases of some parts
### HSPI

* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash to both boards, the jumper is used to differentiate the boards. Run `test_hspi_serdes.py`.
* Run : flash `test_firmware_hspi.bin` to both boards, the jumper is used to differentiate the boards. Run `test_hspi_serdes.py`.

The test simply sends data from one board to the other using HSPI, then exports it to the host to check integrity.

### SerDes

* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash to both boards, the jumper is used to differentiate the boards. Run `test_hspi_serdes.py`.
* Run : flash `test_firmware_serdes.bin` to both boards, the jumper is used to differentiate the boards. Run `test_hspi_serdes.py`.

The test simply sends data from one board to the other using SerDes, then exports it to the host to check integrity.

### Loopback

* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash to both boards, the jumper is used to differentiate the boards. Run `test_loopback.py` or `test_loopback_randomize.py`.
* Run : flash `test_firmware_loopback.bin` to both boards, the jumper is used to differentiate the boards. Run `test_loopback.py` or `test_loopback_randomize.py`.

`test_loopback.py` will send data to the first board via USB, which will transmit it to the second board using HSPI, then receive it back with SerDes, and back to the host via USB. The script will then check for integrity.

Run `test_loopback_randomize.py` to send packets with variable sizes, to check if the boards can handle various packet sizes.

The goal here is to check that all parts of the data loop works, although it does not use HSPI as half-duplex and does not use the interrupt_queue.

### USB stress
* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash `test_firmware_usb_stress_test.bin` to one board. Run `test_stress.py`.

Sends packets of random size using bulk, control or interrupt (for low-speed) requests and checks if data has been correctly sent or received.

Based on Facedancer's stress test.

### USB loopack
NOTE : the above USB stress test should replace this loopback test in most cases.
NOTE : `test_firmware_usb_loopback.bin` allows testing all 16 endpoint numbers in both directions (not simultaneously because of incompatibilities) by uncommenting the dedicated code in `main.c`.

* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash to one board. Run `test_loopback.py` or `test_loopback_randomize.py`.
* Run : flash `test_firmware_usb_loopback.bin` or `test_firmware_usb_loopback_separate_usb_stacks.bin` to one board. Run `test_loopback.py` or `test_loopback_randomize_packetsize.py`.

`test_loopback.py` will send data to the board via USB, which will send it back. The test will then check the integrity of the transmission. The test is repeated for all 7 IN/OUT endpoints pairs.

Run `test_loopback_randomize.py` to send packets with variable sizes, to check if the board can handle various packet sizes.
Run `test_loopback_randomize_packetsize.py` to send packets with variable sizes, to check if the board can handle various packet sizes.

`test_loopback.py --zlp` sends packets without data (ZLP, Zero-length packets) to test if the device can handle these properly.

The `test_firmware_usb_loopback_separate_usb_stacks.bin` firmware will create one USB3 device using the USB3 lines of the connector and one USB2 device using the USB2 lines of the connector. You can then run the scripts at the same time for both device.

The goal is to test if the USB3 and USB2 peripherals are working correctly.

Expand All @@ -93,7 +107,7 @@ By default, the USB3 peripheral is active but you can switch to USB2 by maintain
### USB speedtest

* Compile : compile the tests with `-DBUILD_TESTS=1`
* Run : flash to one board. Run `test_speedtest.py` or `test_speedtest_one_by_one.py`.
* Run : flash `test_firmware_usb_speedtest.bin` to one board. Run `test_speedtest.py` or `test_speedtest_one_by_one.py`.

`test_speedtest.py` will first send data to the board in one go (one call to libusb), then read data from the board in one go (one call to libusb).

Expand Down
Loading

0 comments on commit 9041c32

Please sign in to comment.