-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #39 from espressif/feature/esp_tinyusb_stack_teardown
feature(esp_tinyusb): Added tusb_teardown() call while tinyusb_driver_uninstall()
- Loading branch information
Showing
12 changed files
with
344 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# The following lines of boilerplate have to be in your project's | ||
# CMakeLists in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.16) | ||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
|
||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on. | ||
set(COMPONENTS main) | ||
|
||
project(test_app_teardown_device) |
4 changes: 4 additions & 0 deletions
4
device/esp_tinyusb/test_apps/teardown_device/main/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
idf_component_register(SRC_DIRS . | ||
INCLUDE_DIRS . | ||
REQUIRES unity | ||
WHOLE_ARCHIVE) |
5 changes: 5 additions & 0 deletions
5
device/esp_tinyusb/test_apps/teardown_device/main/idf_component.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
## IDF Component Manager Manifest File | ||
dependencies: | ||
espressif/esp_tinyusb: | ||
version: "*" | ||
override_path: "../../../" |
62 changes: 62 additions & 0 deletions
62
device/esp_tinyusb/test_apps/teardown_device/main/test_app_main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include "unity.h" | ||
#include "unity_test_runner.h" | ||
#include "unity_test_utils_memory.h" | ||
|
||
void app_main(void) | ||
{ | ||
/* | ||
_ _ _ | ||
| | (_) | | | ||
___ ___ _ __ | |_ _ _ __ _ _ _ _ ___| |__ | ||
/ _ \/ __| '_ \| __| | '_ \| | | | | | / __| '_ \ | ||
| __/\__ \ |_) | |_| | | | | |_| | |_| \__ \ |_) | | ||
\___||___/ .__/ \__|_|_| |_|\__, |\__,_|___/_.__/ | ||
| |______ __/ | | ||
|_|______| |___/ | ||
_____ _____ _____ _____ | ||
|_ _| ___/ ___|_ _| | ||
| | | |__ \ `--. | | | ||
| | | __| `--. \ | | | ||
| | | |___/\__/ / | | | ||
\_/ \____/\____/ \_/ | ||
*/ | ||
|
||
printf(" _ _ _ \n"); | ||
printf(" | | (_) | | \n"); | ||
printf(" ___ ___ _ __ | |_ _ _ __ _ _ _ _ ___| |__ \n"); | ||
printf(" / _ \\/ __| '_ \\| __| | '_ \\| | | | | | / __| '_ \\ \n"); | ||
printf("| __/\\__ \\ |_) | |_| | | | | |_| | |_| \\__ \\ |_) |\n"); | ||
printf(" \\___||___/ .__/ \\__|_|_| |_|\\__, |\\__,_|___/_.__/ \n"); | ||
printf(" | |______ __/ | \n"); | ||
printf(" |_|______| |___/ \n"); | ||
printf(" _____ _____ _____ _____ \n"); | ||
printf("|_ _| ___/ ___|_ _| \n"); | ||
printf(" | | | |__ \\ `--. | | \n"); | ||
printf(" | | | __| `--. \\ | | \n"); | ||
printf(" | | | |___/\\__/ / | | \n"); | ||
printf(" \\_/ \\____/\\____/ \\_/ \n"); | ||
|
||
unity_utils_setup_heap_record(80); | ||
unity_utils_set_leak_level(128); | ||
unity_run_menu(); | ||
} | ||
|
||
/* setUp runs before every test */ | ||
void setUp(void) | ||
{ | ||
unity_utils_record_free_mem(); | ||
} | ||
|
||
/* tearDown runs after every test */ | ||
void tearDown(void) | ||
{ | ||
unity_utils_evaluate_leaks(); | ||
} |
142 changes: 142 additions & 0 deletions
142
device/esp_tinyusb/test_apps/teardown_device/main/test_teardown.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "soc/soc_caps.h" | ||
#if SOC_USB_OTG_SUPPORTED | ||
|
||
// | ||
#include <stdio.h> | ||
#include <string.h> | ||
// | ||
#include "freertos/FreeRTOS.h" | ||
#include "freertos/task.h" | ||
#include "freertos/semphr.h" | ||
// | ||
#include "esp_system.h" | ||
#include "esp_log.h" | ||
#include "esp_err.h" | ||
// | ||
#include "unity.h" | ||
#include "tinyusb.h" | ||
#include "tusb_cdc_acm.h" | ||
|
||
static const char *TAG = "teardown"; | ||
|
||
SemaphoreHandle_t wait_mount = NULL; | ||
|
||
#define TEARDOWN_DEVICE_INIT_DELAY_MS 1000 | ||
#define TEARDOWN_DEVICE_ATTACH_TIMEOUT_MS 1000 | ||
#define TEARDOWN_DEVICE_DETACH_DELAY_MS 1000 | ||
|
||
#define TEARDOWN_AMOUNT 10 | ||
|
||
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN) | ||
static uint8_t const test_configuration_descriptor[] = { | ||
// Config number, interface count, string index, total length, attribute, power in mA | ||
TUD_CONFIG_DESCRIPTOR(1, 0, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_SELF_POWERED | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), | ||
}; | ||
|
||
static const tusb_desc_device_t test_device_descriptor = { | ||
.bLength = sizeof(test_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 = 0x303A, // This is Espressif VID. This needs to be changed according to Users / Customers | ||
.idProduct = 0x4002, | ||
.bcdDevice = 0x100, | ||
.iManufacturer = 0x01, | ||
.iProduct = 0x02, | ||
.iSerialNumber = 0x03, | ||
.bNumConfigurations = 0x01 | ||
}; | ||
|
||
#if (TUD_OPT_HIGH_SPEED) | ||
static const tusb_desc_device_qualifier_t device_qualifier = { | ||
.bLength = sizeof(tusb_desc_device_qualifier_t), | ||
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, | ||
.bcdUSB = 0x0200, | ||
.bDeviceClass = TUSB_CLASS_MISC, | ||
.bDeviceSubClass = MISC_SUBCLASS_COMMON, | ||
.bDeviceProtocol = MISC_PROTOCOL_IAD, | ||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, | ||
.bNumConfigurations = 0x01, | ||
.bReserved = 0 | ||
}; | ||
#endif // TUD_OPT_HIGH_SPEED | ||
|
||
// Invoked when device is mounted | ||
void tud_mount_cb(void) | ||
{ | ||
xSemaphoreGive(wait_mount); | ||
} | ||
|
||
/** | ||
* @brief TinyUSB Teardown specific testcase | ||
* | ||
* Scenario: | ||
* 1. Install TinyUSB device without any class | ||
* 2. Wait SetConfiguration() (tud_mount_cb) | ||
* 3. If attempts == 0 goto step 8 | ||
* 4. Wait TEARDOWN_DEVICE_DETACH_DELAY_MS | ||
* 5. Uninstall TinyUSB device | ||
* 6. Wait TEARDOWN_DEVICE_INIT_DELAY_MS | ||
* 7. Decrease attempts by 1, goto step 3 | ||
* 8. Wait TEARDOWN_DEVICE_DETACH_DELAY_MS | ||
* 9. Uninstall TinyUSB device | ||
*/ | ||
TEST_CASE("tinyusb_teardown", "[esp_tinyusb][teardown]") | ||
{ | ||
wait_mount = xSemaphoreCreateBinary(); | ||
TEST_ASSERT_NOT_EQUAL(NULL, wait_mount); | ||
|
||
// TinyUSB driver configuration | ||
const tinyusb_config_t tusb_cfg = { | ||
.device_descriptor = &test_device_descriptor, | ||
.string_descriptor = NULL, | ||
.string_descriptor_count = 0, | ||
.external_phy = false, | ||
#if (TUD_OPT_HIGH_SPEED) | ||
.fs_configuration_descriptor = test_configuration_descriptor, | ||
.hs_configuration_descriptor = test_configuration_descriptor, | ||
.qualifier_descriptor = &device_qualifier, | ||
#else | ||
.configuration_descriptor = test_configuration_descriptor, | ||
#endif // TUD_OPT_HIGH_SPEED | ||
}; | ||
|
||
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_install(&tusb_cfg)); | ||
// Wait for the usb event | ||
ESP_LOGD(TAG, "wait mount..."); | ||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(wait_mount, pdMS_TO_TICKS(TEARDOWN_DEVICE_ATTACH_TIMEOUT_MS))); | ||
ESP_LOGD(TAG, "mounted"); | ||
|
||
// Teardown routine | ||
int attempts = TEARDOWN_AMOUNT; | ||
while (attempts--) { | ||
// Keep device attached | ||
vTaskDelay(pdMS_TO_TICKS(TEARDOWN_DEVICE_DETACH_DELAY_MS)); | ||
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_uninstall()); | ||
// Teardown | ||
vTaskDelay(pdMS_TO_TICKS(TEARDOWN_DEVICE_INIT_DELAY_MS)); | ||
// Reconnect | ||
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_install(&tusb_cfg)); | ||
// Wait for the usb event | ||
ESP_LOGD(TAG, "wait mount..."); | ||
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(wait_mount, pdMS_TO_TICKS(TEARDOWN_DEVICE_ATTACH_TIMEOUT_MS))); | ||
ESP_LOGD(TAG, "mounted"); | ||
} | ||
|
||
// Teardown | ||
vTaskDelay(pdMS_TO_TICKS(TEARDOWN_DEVICE_DETACH_DELAY_MS)); | ||
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_uninstall()); | ||
// Remove primitives | ||
vSemaphoreDelete(wait_mount); | ||
} | ||
|
||
#endif |
75 changes: 75 additions & 0 deletions
75
device/esp_tinyusb/test_apps/teardown_device/pytest_teardown_device.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import pytest | ||
from pytest_embedded_idf.dut import IdfDut | ||
import subprocess | ||
from time import sleep, time | ||
|
||
class DeviceNotFoundError(Exception): | ||
"""Custom exception for device not found within the timeout period.""" | ||
pass | ||
|
||
def tusb_dev_in_list(vid, pid): | ||
try: | ||
output = subprocess.check_output(["lsusb"], text=True) | ||
search_string = f"{vid}:{pid}" | ||
return search_string in output | ||
except Exception as e: | ||
print(f"Error while executing lsusb: {e}") | ||
raise | ||
|
||
def wait_tusb_dev_appeared(vid, pid, timeout): | ||
start_time = time() | ||
while True: | ||
if tusb_dev_in_list(vid, pid): | ||
return True | ||
if time() - start_time > timeout: | ||
raise DeviceNotFoundError(f"Device with VID: 0x{vid:04x}, PID: 0x{pid:04x} not found within {timeout} seconds.") | ||
sleep(0.5) | ||
|
||
def wait_tusb_dev_removed(vid, pid, timeout): | ||
start_time = time() | ||
while True: | ||
if not tusb_dev_in_list(vid, pid): | ||
return True | ||
if time() - start_time > timeout: | ||
raise DeviceNotFoundError(f"Device with VID: 0x{vid:04x}, PID: 0x{pid:04x} wasn't removed within {timeout} seconds.") | ||
sleep(0.5) | ||
|
||
def tusb_device_teardown(iterations, timeout): | ||
TUSB_VID = "303a" # Espressif TinyUSB VID | ||
TUSB_PID = "4002" # Espressif TinyUSB VID | ||
|
||
for i in range(iterations): | ||
# Wait until the device is present | ||
print(f"Waiting for device ...") | ||
wait_tusb_dev_appeared(TUSB_VID, TUSB_PID, timeout) | ||
print("Device detected.") | ||
|
||
# Wait until the device is removed | ||
print("Waiting for the device to be removed...") | ||
wait_tusb_dev_removed(TUSB_VID, TUSB_PID, timeout) | ||
print("Device removed.") | ||
print("Monitoring completed.") | ||
|
||
@pytest.mark.esp32s2 | ||
@pytest.mark.esp32s3 | ||
@pytest.mark.esp32p4 | ||
@pytest.mark.usb_device | ||
def test_usb_teardown_device(dut: IdfDut) -> None: | ||
dut.expect_exact('Press ENTER to see the list of tests.') | ||
dut.write('[teardown]') | ||
dut.expect_exact('TinyUSB: TinyUSB Driver installed') | ||
sleep(2) # Some time for the OS to enumerate our USB device | ||
|
||
try: | ||
tusb_device_teardown(10, 10) # Teardown tusb device: amount, timeout | ||
|
||
except DeviceNotFoundError as e: | ||
print(f"Error: {e}") | ||
raise | ||
|
||
except Exception as e: | ||
print(f"An unexpected error occurred: {e}") | ||
raise |
Oops, something went wrong.