ci: Add USB Host CDC and MSC pytests to pipeline

This commit is contained in:
Tomas Rezucha 2022-02-10 11:16:53 +01:00
parent 7d950a63cc
commit 6206302787
7 changed files with 132 additions and 8 deletions

View File

@ -196,6 +196,16 @@ test_app_test_pytest_esp32c3_generic:
TARGET: ESP32C3
ENV_MARKER: generic
test_app_test_pytest_esp32s2_usb_host:
extends:
- .pytest_test_apps_dir_template
- .rules:test:custom_test-esp32s2
needs:
- build_pytest_test_apps_esp32s2
variables:
TARGET: ESP32S2
ENV_MARKER: usb_host
# for parallel jobs, CI_JOB_NAME will be "job_name index/total" (for example, "IT_001 1/2")
# we need to convert to pattern "job_name_index.yml"
.define_config_file_name: &define_config_file_name |

View File

@ -72,7 +72,7 @@ void usb_lib_task(void *arg)
all_clients_gone = true;
}
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
printf("All device's freed\n");
printf("All devices freed\n");
all_dev_free = true;
}
}
@ -133,7 +133,7 @@ static void notif_cb(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_host_dev_event_dat
/* Basic test to check CDC communication:
* open/read/write/close device
* CDC-ACM specific commands: set/get_line_coding, set_control_line_state */
TEST_CASE("USB Host CDC-ACM driver: Basic test", "[cdc_acm][ignore]")
TEST_CASE("read_write", "[cdc_acm]")
{
nb_of_responses = 0;
cdc_acm_dev_hdl_t cdc_dev = NULL;
@ -180,7 +180,7 @@ TEST_CASE("USB Host CDC-ACM driver: Basic test", "[cdc_acm][ignore]")
}
/* Test communication with multiple CDC-ACM devices from one thread */
TEST_CASE("USB Host CDC-ACM driver: Multiple devices test", "[cdc_acm][ignore]")
TEST_CASE("multiple_devices", "[cdc_acm]")
{
nb_of_responses = 0;
nb_of_responses2 = 0;
@ -244,7 +244,7 @@ void tx_task(void *arg)
* In this test, one CDC device is accessed from multiple threads.
* It has to be opened/closed just once, though.
*/
TEST_CASE("USB Host CDC-ACM driver: Multiple threads test", "[cdc_acm][ignore]")
TEST_CASE("multiple_threads", "[cdc_acm]")
{
nb_of_responses = 0;
cdc_acm_dev_hdl_t cdc_dev;
@ -278,7 +278,7 @@ TEST_CASE("USB Host CDC-ACM driver: Multiple threads test", "[cdc_acm][ignore]")
}
/* Test CDC driver reaction to USB device sudden disconnection */
TEST_CASE("USB Host CDC-ACM driver: Sudden disconnection test", "[cdc_acm][ignore]")
TEST_CASE("sudden_disconnection", "[cdc_acm]")
{
test_install_cdc_driver();
@ -315,7 +315,7 @@ TEST_CASE("USB Host CDC-ACM driver: Sudden disconnection test", "[cdc_acm][ignor
* -# Send unsupported CDC request
* -# Write to read-only device
*/
TEST_CASE("USB Host CDC-ACM driver: Error handling", "[cdc_acm][ignore]")
TEST_CASE("error_handling", "[cdc_acm]")
{
cdc_acm_dev_hdl_t cdc_dev;
cdc_acm_host_device_config_t dev_config = {
@ -375,7 +375,7 @@ TEST_CASE("USB Host CDC-ACM driver: Error handling", "[cdc_acm][ignore]")
/* Following test case implements dual CDC-ACM USB device that can be used as mock device for CDC-ACM Host tests */
void run_usb_dual_cdc_device(void);
TEST_CASE("USB_CDC_Mock_Device_App", "[cdc_acm_device][ignore]")
TEST_CASE("mock_device_app", "[cdc_acm_device][ignore]")
{
run_usb_dual_cdc_device();
}

View File

@ -19,9 +19,36 @@ void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event)
tinyusb_cdcacm_write_flush(itf, 0);
}
static const tusb_desc_device_t cdc_device_descriptor = {
.bLength = sizeof(cdc_device_descriptor),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_ESPRESSIF_VID,
.idProduct = 0x4002,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
const uint16_t cdc_desc_config_len = TUD_CONFIG_DESC_LEN + 2 * TUD_CDC_DESC_LEN;
static const uint8_t cdc_desc_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, 4, 0, cdc_desc_config_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
TUD_CDC_DESCRIPTOR(0, 4, 0x81, 8, 0x02, 0x82, 64),
TUD_CDC_DESCRIPTOR(2, 4, 0x83, 8, 0x04, 0x84, 64),
};
void run_usb_dual_cdc_device(void)
{
const tinyusb_config_t tusb_cfg = {}; // the configuration using default values
const tinyusb_config_t tusb_cfg = {
.device_descriptor = &cdc_device_descriptor,
.configuration_descriptor = cdc_desc_configuration
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
tinyusb_config_cdcacm_t amc_cfg = {

View File

@ -25,6 +25,7 @@ markers =
ip101: connected via wired 10/100M ethernet
lan8720: connected via LAN8720 ethernet transceiver
octal_psram: runners with octal psram
usb_host: usb host runners
# log related
log_cli = True

View File

@ -7,6 +7,18 @@
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "esp_heap_caps.h"
static size_t before_free_8bit;
static size_t before_free_32bit;
#define TEST_MEMORY_LEAK_THRESHOLD (-10000) // @todo MSC test are leaking memory
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak");
}
void app_main(void)
{
@ -14,3 +26,19 @@ void app_main(void)
unity_run_menu();
UNITY_END();
}
/* setUp runs before every test */
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
/* tearDown runs after every test */
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT");
check_leak(before_free_32bit, after_free_32bit, "32BIT");
}

View File

@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
from typing import Tuple
import pytest
from pytest_embedded_idf.dut import IdfDut
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.usb_host
@pytest.mark.parametrize('count', [
2,
], indirect=True)
def test_usb_host(dut: Tuple[IdfDut, IdfDut]) -> None:
device = dut[0]
host = dut[1]
# 1.1 Prepare USB device for CDC test
device.expect_exact('Press ENTER to see the list of tests.')
device.write('[cdc_acm_device]')
device.expect_exact('USB initialization DONE')
# 1.2 Run CDC test
host.expect_exact('Press ENTER to see the list of tests.')
host.write('[cdc_acm]')
host.expect_unity_test_output()
host.expect_exact("Enter next test, or 'enter' to see menu")
# 2.1 Prepare USB device for MSC test
device.serial.hard_reset()
device.expect_exact('Press ENTER to see the list of tests.')
device.write('[usb_msc_device]')
device.expect_exact('USB initialization DONE')
# 2.2 Run MSC test
host.write('[usb_msc]')
host.expect_unity_test_output()
host.expect_exact("Enter next test, or 'enter' to see menu")

View File

@ -1,4 +1,22 @@
CONFIG_TINYUSB=y
CONFIG_TINYUSB_MSC_ENABLED=y
CONFIG_TINYUSB_CDC_ENABLED=y
CONFIG_TINYUSB_CDC_COUNT=2
CONFIG_ESP_INT_WDT=n
CONFIG_ESP_TASK_WDT=n
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=n
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3000
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=7
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
CONFIG_SPI_FLASH_ENABLE_COUNTERS=y
CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS=y
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
CONFIG_COMPILER_STACK_CHECK=y
CONFIG_COMPILER_WARN_WRITE_STRINGS=y
CONFIG_ESP_TIMER_PROFILING=y
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y