Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(esp_tinyusb): Changed CONFIG_TINYUSB_NO_DEFAULT_TASK to non-inverted logic #116

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions device/esp_tinyusb/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## (Unreleased)
- esp_tinyusb: Added option to select TinyUSB peripheral on esp32p4 via menuconfig

## 1.6.0

- CDC-ACM: Fixed memory leak on deinit
Expand Down
4 changes: 2 additions & 2 deletions device/esp_tinyusb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ set(srcs
"usb_descriptors.c"
)

if(NOT CONFIG_TINYUSB_NO_DEFAULT_TASK)
if(CONFIG_TINYUSB_DEFAULT_TASK)
list(APPEND srcs "tusb_tasks.c")
endif() # CONFIG_TINYUSB_NO_DEFAULT_TASK
endif() # CONFIG_TINYUSB_DEFAULT_TASK

if(CONFIG_TINYUSB_CDC_ENABLED)
list(APPEND srcs
Expand Down
104 changes: 67 additions & 37 deletions device/esp_tinyusb/Kconfig
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
menu "TinyUSB Stack"
menu "ESP TinyUSB"
config TINYUSB_DEBUG_LEVEL
int "TinyUSB log level (0-3)"
default 1
range 0 3
help
Specify verbosity of TinyUSB log output.

choice TINYUSB_RHPORT
config TINYUSB_DYNAMIC_RHPORT
depends on IDF_TARGET_ESP32P4
prompt "TinyUSB PHY"
default TINYUSB_RHPORT_HS
bool "TinyUSB Peripheral dynamic selection"
default n
help
Allows to select and configure the Peripheral for TinyUSB in run-time.

- Disable to select peripheral via CFG_TUSB_RHPORTx_MODE (legacy way).
- Enable to use run-time port selection via TinyUSB configuration parameter.

choice TINYUSB_RHPORT
depends on !TINYUSB_DYNAMIC_RHPORT
prompt "USB Peripheral"
default TINYUSB_RHPORT_HS if IDF_TARGET_ESP32P4
default TINYUSB_RHPORT_FS
help
Allows set the USB PHY Controller for TinyUSB: HS (USB OTG2.0 PHY for HighSpeed)
Allows set the USB Peripheral Controller for TinyUSB.

- High-speed (USB OTG2.0 Peripheral for High-, Full- and Low-speed)
- Full-speed (USB OTG1.1 Peripheral for Full- and Low-speed)

config TINYUSB_RHPORT_HS
bool "HS"
bool "OTG2.0"
depends on IDF_TARGET_ESP32P4
config TINYUSB_RHPORT_FS
bool "OTG1.1"
endchoice

menu "TinyUSB DCD"
Expand All @@ -31,61 +48,74 @@ menu "TinyUSB Stack"
endchoice
endmenu # "TinyUSB DCD"

menu "TinyUSB task configuration"
config TINYUSB_NO_DEFAULT_TASK
bool "Do not create a TinyUSB task"
default n
help
This option allows to not create the FreeRTOS task during the driver initialization.
User will have to handle TinyUSB events manually.
config TINYUSB_DEFAULT_TASK
bool "Create TinyUSB task"
default y
help
To handle USB event, TinyUSB task tud_task() should be implemented. This option allows create the FreeRTOS task during the driver initialization with default parameters.

config TINYUSB_TASK_PRIORITY
int "TinyUSB task priority"
default 5
depends on !TINYUSB_NO_DEFAULT_TASK
help
Set the priority of the default TinyUSB main task.
Enable - FreeRTOS TinyUSB task (tud_task()) is implemented by the current component.
Disable - FreeRTOS TinyUSB task (tud_task()) must be implemented outside of the current component.

config TINYUSB_TASK_STACK_SIZE
int "TinyUSB task stack size (bytes)"
default 4096
depends on !TINYUSB_NO_DEFAULT_TASK
help
Set the stack size of the default TinyUSB main task.
Enabled by default.

menu "Task configuration"
depends on TINYUSB_DEFAULT_TASK
choice TINYUSB_TASK_AFFINITY
prompt "TinyUSB task affinity"
prompt "CPU affinity"
default TINYUSB_TASK_AFFINITY_CPU1 if !FREERTOS_UNICORE
default TINYUSB_TASK_AFFINITY_NO_AFFINITY
depends on !TINYUSB_NO_DEFAULT_TASK
help
Allows setting TinyUSB tasks affinity, i.e. whether the task is pinned to
CPU0, pinned to CPU1, or allowed to run on any CPU.

Default value: No affinity for unicore systems, pinned to CPU1 for multicore.

config TINYUSB_TASK_AFFINITY_NO_AFFINITY
bool "No affinity"
bool "None"
config TINYUSB_TASK_AFFINITY_CPU0
bool "CPU0"
config TINYUSB_TASK_AFFINITY_CPU1
bool "CPU1"
depends on !FREERTOS_UNICORE
endchoice

config TINYUSB_INIT_IN_TASK
bool "Init in task"
default n if TINYUSB_DEFAULT_TASK
default y
depends on !TINYUSB_TASK_AFFINITY_NO_AFFINITY
help
Run TinyUSB stack initialization just after starting the default TinyUSB task.
This is especially useful in multicore scenarios, when we need to pin the task
to a specific core and, at the same time initialize TinyUSB stack
(i.e. install interrupts) on the same core.

Disabled by default, when TINYUSB_DEFAULT_TASK is enabled.
Enabled by default, when TINYUSB_DEFAULT_TASK is disabled.

config TINYUSB_TASK_PRIORITY
int "Priority"
default 5
help
Set the priority of the default TinyUSB main task.

Default value: 5.

config TINYUSB_TASK_STACK_SIZE
int "Stack size (bytes)"
default 4096
help
Set the stack size of the default TinyUSB main task.

Default value: 4096 bytes.

config TINYUSB_TASK_AFFINITY
hex
default FREERTOS_NO_AFFINITY if TINYUSB_TASK_AFFINITY_NO_AFFINITY
default 0x0 if TINYUSB_TASK_AFFINITY_CPU0
default 0x1 if TINYUSB_TASK_AFFINITY_CPU1

config TINYUSB_INIT_IN_DEFAULT_TASK
bool "Initialize TinyUSB stack within the default TinyUSB task"
default n
depends on !TINYUSB_NO_DEFAULT_TASK
help
Run TinyUSB stack initialization just after starting the default TinyUSB task.
This is especially useful in multicore scenarios, when we need to pin the task
to a specific core and, at the same time initialize TinyUSB stack
(i.e. install interrupts) on the same core.
endmenu # "TinyUSB task configuration"

menu "Descriptor configuration"
Expand Down
9 changes: 9 additions & 0 deletions device/esp_tinyusb/test_apps/default_task/CMakeLists.txt
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_default_task_without_init)
4 changes: 4 additions & 0 deletions device/esp_tinyusb/test_apps/default_task/main/CMakeLists.txt
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)
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 device/esp_tinyusb/test_apps/default_task/main/test_app_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: 2024-2025 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();
}
112 changes: 112 additions & 0 deletions device/esp_tinyusb/test_apps/default_task/main/test_tusb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: 2024-2025 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"

static const char *TAG = "default_task";

SemaphoreHandle_t wait_mount = NULL;

#define TEARDOWN_DEVICE_DELAY_MS 1000

#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:
*/
TEST_CASE("tinyusb_default_task_with_init", "[esp_tinyusb][tusb_task]")
{
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_DELAY_MS)));
ESP_LOGD(TAG, "mounted");

// Teardown
vTaskDelay(pdMS_TO_TICKS(TEARDOWN_DEVICE_DELAY_MS));
TEST_ASSERT_EQUAL(ESP_OK, tinyusb_driver_uninstall());
// Remove primitives
vSemaphoreDelete(wait_mount);
}

#endif
12 changes: 12 additions & 0 deletions device/esp_tinyusb/test_apps/default_task/pytest_default_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0

import pytest
from pytest_embedded_idf.dut import IdfDut

@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.usb_device
def test_usb_default_task_with_init(dut: IdfDut) -> None:
dut.run_all_single_board_cases(group='tusb_task')
16 changes: 16 additions & 0 deletions device/esp_tinyusb/test_apps/default_task/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Configure TinyUSB, it will be used to mock USB devices
CONFIG_TINYUSB_DEFAULT_TASK=y
CONFIG_TINYUSB_INIT_IN_TASK=n

# Disable watchdogs, they'd get triggered during unity interactive menu
CONFIG_ESP_INT_WDT=n
CONFIG_ESP_TASK_WDT=n

# Run-time checks of Heap and Stack
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
CONFIG_COMPILER_STACK_CHECK=y

CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y

CONFIG_COMPILER_CXX_EXCEPTIONS=y
Loading
Loading