Merge branch 'feat/usb-serial-jtag-select' into 'master'

feat(usb_serial_jtag): Add select functionality to the driver

Closes IDF-7415 and IDFGH-8509

See merge request espressif/esp-idf!30919
This commit is contained in:
Guillaume Souchere
2024-09-24 19:28:51 +08:00
15 changed files with 522 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ endif()
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${include} INCLUDE_DIRS ${include}
PRIV_REQUIRES "${priv_requires}" PRIV_REQUIRES "${priv_requires}"
LDFRAGMENTS "linker.lf"
) )
if(CONFIG_VFS_SUPPORT_IO AND CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED) if(CONFIG_VFS_SUPPORT_IO AND CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED)

View File

@@ -105,6 +105,13 @@ esp_err_t usb_serial_jtag_driver_uninstall(void);
*/ */
bool usb_serial_jtag_is_connected(void); bool usb_serial_jtag_is_connected(void);
/**
* @brief Get information whether the USB serial JTAG driver is installed or not
*
* @return True if driver is installed and False if driver not installed
*/
bool usb_serial_jtag_is_driver_installed(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "driver/usb_serial_jtag.h"
typedef enum {
USJ_SELECT_READ_NOTIF,
USJ_SELECT_WRITE_NOTIF,
USJ_SELECT_ERROR_NOTIF,
} usj_select_notif_t;
typedef void (*usj_select_notif_callback_t)(usj_select_notif_t usb_serial_jtag_select_notif, BaseType_t *task_woken);
/**
* @brief Set notification callback function for select() events
* @param usb_serial_jtag_select_notif_callback callback function
*/
void usb_serial_jtag_set_select_notif_callback(usj_select_notif_callback_t usb_serial_jtag_select_notif_callback);
/**
* @brief Return the readiness status of the driver for read operation
*
* @return true if driver read ready, false if not
*/
bool usb_serial_jtag_read_ready(void);
/**
* @brief Return the readiness status of the driver for write operation
*
* @return true if driver is write ready, false if not
*/
bool usb_serial_jtag_write_ready(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,5 @@
[mapping:usb_serial_jtag_vfs]
archive: libesp_driver_usb_serial_jtag.a
entries:
if VFS_SELECT_IN_RAM = y:
usb_serial_jtag_vfs: select_notif_callback_isr (noflash)

View File

@@ -14,6 +14,7 @@
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "driver/usb_serial_jtag.h" #include "driver/usb_serial_jtag.h"
#include "driver/usb_serial_jtag_select.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "esp_check.h" #include "esp_check.h"
@@ -49,6 +50,8 @@ typedef struct {
//Synchronization stuff, only used for flush for now //Synchronization stuff, only used for flush for now
SemaphoreHandle_t tx_mux; SemaphoreHandle_t tx_mux;
SemaphoreHandle_t tx_idle_sem; SemaphoreHandle_t tx_idle_sem;
usj_select_notif_callback_t usj_select_notif_callback; /*!< Notification about select() events */
} usb_serial_jtag_obj_t; } usb_serial_jtag_obj_t;
static usb_serial_jtag_obj_t *p_usb_serial_jtag_obj = NULL; static usb_serial_jtag_obj_t *p_usb_serial_jtag_obj = NULL;
@@ -103,6 +106,12 @@ static void usb_serial_jtag_isr_handler_default(void *arg)
// Return the buffer if we got it from the ring buffer. // Return the buffer if we got it from the ring buffer.
if (queued_buf != p_usb_serial_jtag_obj->tx_stash_buf) { if (queued_buf != p_usb_serial_jtag_obj->tx_stash_buf) {
vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buf, &xTaskWoken); vRingbufferReturnItemFromISR(p_usb_serial_jtag_obj->tx_ring_buf, queued_buf, &xTaskWoken);
// We just moved items out of the TX ring buffer, the driver is considered write ready, since
// the TX ring buffer is assured to be not full.
if (p_usb_serial_jtag_obj->usj_select_notif_callback) {
p_usb_serial_jtag_obj->usj_select_notif_callback(USJ_SELECT_WRITE_NOTIF, &xTaskWoken);
}
} }
} else { } else {
// No data to send. // No data to send.
@@ -139,6 +148,10 @@ static void usb_serial_jtag_isr_handler_default(void *arg)
uint8_t buf[USB_SER_JTAG_RX_MAX_SIZE]; uint8_t buf[USB_SER_JTAG_RX_MAX_SIZE];
uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(buf, USB_SER_JTAG_RX_MAX_SIZE); uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(buf, USB_SER_JTAG_RX_MAX_SIZE);
xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, buf, rx_fifo_len, &xTaskWoken); xRingbufferSendFromISR(p_usb_serial_jtag_obj->rx_ring_buf, buf, rx_fifo_len, &xTaskWoken);
if (p_usb_serial_jtag_obj->usj_select_notif_callback) {
p_usb_serial_jtag_obj->usj_select_notif_callback(USJ_SELECT_READ_NOTIF, &xTaskWoken);
}
} }
if (xTaskWoken == pdTRUE) { if (xTaskWoken == pdTRUE) {
@@ -341,3 +354,29 @@ esp_err_t usb_serial_jtag_driver_uninstall(void)
p_usb_serial_jtag_obj = NULL; p_usb_serial_jtag_obj = NULL;
return ESP_OK; return ESP_OK;
} }
bool usb_serial_jtag_is_driver_installed(void)
{
return (p_usb_serial_jtag_obj != NULL);
}
void usb_serial_jtag_set_select_notif_callback(usj_select_notif_callback_t usj_select_notif_callback)
{
if (usb_serial_jtag_is_driver_installed()) {
p_usb_serial_jtag_obj->usj_select_notif_callback = usj_select_notif_callback;
}
}
bool usb_serial_jtag_read_ready(void)
{
// sign the the driver is read ready is that data is waiting in the RX ringbuffer
UBaseType_t items_waiting = 0;
vRingbufferGetInfo(p_usb_serial_jtag_obj->rx_ring_buf, NULL, NULL, NULL, NULL, &items_waiting);
return items_waiting != 0;
}
bool usb_serial_jtag_write_ready(void)
{
// sign that the driver is write ready is that the TX ring buffer is not full
return (xRingbufferGetCurFreeSize(p_usb_serial_jtag_obj->tx_ring_buf) > 0);
}

View File

@@ -23,9 +23,14 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "hal/usb_serial_jtag_ll.h" #include "hal/usb_serial_jtag_ll.h"
#include "driver/usb_serial_jtag_select.h"
#include "driver/usb_serial_jtag_vfs.h" #include "driver/usb_serial_jtag_vfs.h"
#include "driver/usb_serial_jtag.h" #include "driver/usb_serial_jtag.h"
#include "esp_private/startup_internal.h" #include "esp_private/startup_internal.h"
#include "esp_heap_caps.h"
// local file descriptor value for the USJ
#define USJ_LOCAL_FD 0
// Token signifying that no character is available // Token signifying that no character is available
#define NONE -1 #define NONE -1
@@ -46,6 +51,12 @@
# define DEFAULT_RX_MODE ESP_LINE_ENDINGS_LF # define DEFAULT_RX_MODE ESP_LINE_ENDINGS_LF
#endif #endif
#if CONFIG_VFS_SELECT_IN_RAM
#define USJ_VFS_MALLOC_FLAGS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else
#define USJ_VFS_MALLOC_FLAGS MALLOC_CAP_DEFAULT
#endif
// write bytes function type // write bytes function type
typedef void (*tx_func_t)(int, int); typedef void (*tx_func_t)(int, int);
// read bytes function type // read bytes function type
@@ -108,10 +119,30 @@ static usb_serial_jtag_vfs_context_t s_ctx = {
.fsync_func = usb_serial_jtag_wait_tx_done_no_driver .fsync_func = usb_serial_jtag_wait_tx_done_no_driver
}; };
#ifdef CONFIG_VFS_SUPPORT_SELECT
typedef struct {
esp_vfs_select_sem_t select_sem;
fd_set *readfds;
fd_set *writefds;
fd_set *errorfds;
fd_set readfds_orig;
fd_set writefds_orig;
fd_set errorfds_orig;
} usb_serial_jtag_select_args_t;
static usb_serial_jtag_select_args_t **s_registered_selects = NULL;
static int s_registered_select_num = 0;
static portMUX_TYPE s_registered_select_lock = portMUX_INITIALIZER_UNLOCKED;
static esp_err_t usb_serial_jtag_end_select(void *end_select_args);
#endif // CONFIG_VFS_SUPPORT_SELECT
static int usb_serial_jtag_open(const char * path, int flags, int mode) static int usb_serial_jtag_open(const char * path, int flags, int mode)
{ {
s_ctx.non_blocking = ((flags & O_NONBLOCK) == O_NONBLOCK); s_ctx.non_blocking = ((flags & O_NONBLOCK) == O_NONBLOCK);
return 0; return USJ_LOCAL_FD;
} }
static void usb_serial_jtag_tx_char_no_driver(int fd, int c) static void usb_serial_jtag_tx_char_no_driver(int fd, int c)
@@ -300,6 +331,164 @@ static int usb_serial_jtag_fsync(int fd)
} }
} }
#ifdef CONFIG_VFS_SUPPORT_SELECT
static void select_notif_callback_isr(usj_select_notif_t usj_select_notif, BaseType_t *task_woken)
{
portENTER_CRITICAL_ISR(&s_registered_select_lock);
for (int i = 0; i < s_registered_select_num; ++i) {
usb_serial_jtag_select_args_t *args = s_registered_selects[i];
if (args) {
switch (usj_select_notif) {
case USJ_SELECT_READ_NOTIF:
if (FD_ISSET(USJ_LOCAL_FD, &args->readfds_orig)) {
FD_SET(USJ_LOCAL_FD, args->readfds);
esp_vfs_select_triggered_isr(args->select_sem, task_woken);
}
break;
case USJ_SELECT_WRITE_NOTIF:
if (FD_ISSET(USJ_LOCAL_FD, &args->writefds_orig)) {
FD_SET(USJ_LOCAL_FD, args->writefds);
esp_vfs_select_triggered_isr(args->select_sem, task_woken);
}
break;
case USJ_SELECT_ERROR_NOTIF:
if (FD_ISSET(USJ_LOCAL_FD, &args->errorfds_orig)) {
FD_SET(USJ_LOCAL_FD, args->errorfds);
esp_vfs_select_triggered_isr(args->select_sem, task_woken);
}
break;
}
}
}
portEXIT_CRITICAL_ISR(&s_registered_select_lock);
}
static esp_err_t register_select(usb_serial_jtag_select_args_t *args)
{
esp_err_t ret = ESP_ERR_INVALID_ARG;
if (args) {
portENTER_CRITICAL(&s_registered_select_lock);
const int new_size = s_registered_select_num + 1;
usb_serial_jtag_select_args_t **new_selects;
if ((new_selects = heap_caps_realloc(s_registered_selects, new_size * sizeof(usb_serial_jtag_select_args_t *), USJ_VFS_MALLOC_FLAGS)) == NULL) {
ret = ESP_ERR_NO_MEM;
} else {
/* on first select registration register the callback */
if (s_registered_select_num == 0) {
usb_serial_jtag_set_select_notif_callback(select_notif_callback_isr);
}
s_registered_selects = new_selects;
s_registered_selects[s_registered_select_num] = args;
s_registered_select_num = new_size;
ret = ESP_OK;
}
portEXIT_CRITICAL(&s_registered_select_lock);
}
return ret;
}
static esp_err_t unregister_select(usb_serial_jtag_select_args_t *args)
{
esp_err_t ret = ESP_OK;
if (args) {
ret = ESP_ERR_INVALID_STATE;
portENTER_CRITICAL(&s_registered_select_lock);
for (int i = 0; i < s_registered_select_num; ++i) {
if (s_registered_selects[i] == args) {
const int new_size = s_registered_select_num - 1;
// The item is removed by overwriting it with the last item. The subsequent rellocation will drop the
// last item.
s_registered_selects[i] = s_registered_selects[new_size];
s_registered_selects = heap_caps_realloc(s_registered_selects, new_size * sizeof(usb_serial_jtag_select_args_t *), USJ_VFS_MALLOC_FLAGS);
// Shrinking a buffer with realloc is guaranteed to succeed.
s_registered_select_num = new_size;
/* when the last select is unregistered, also unregister the callback */
if (s_registered_select_num == 0) {
usb_serial_jtag_set_select_notif_callback(NULL);
}
ret = ESP_OK;
break;
}
}
portEXIT_CRITICAL(&s_registered_select_lock);
}
return ret;
}
static esp_err_t usb_serial_jtag_start_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
esp_vfs_select_sem_t select_sem, void **end_select_args)
{
(void)nfds; /* Since there is only 1 usb serial jtag port, this parameter is useless */
*end_select_args = NULL;
if (!usb_serial_jtag_is_driver_installed()) {
return ESP_ERR_INVALID_STATE;
}
usb_serial_jtag_select_args_t *args = heap_caps_malloc(sizeof(usb_serial_jtag_select_args_t), USJ_VFS_MALLOC_FLAGS);
if (args == NULL) {
return ESP_ERR_NO_MEM;
}
args->select_sem = select_sem;
args->readfds = readfds;
args->writefds = writefds;
args->errorfds = exceptfds;
args->readfds_orig = *readfds; // store the original values because they will be set to zero
args->writefds_orig = *writefds;
args->errorfds_orig = *exceptfds;
FD_ZERO(readfds);
FD_ZERO(writefds);
FD_ZERO(exceptfds);
esp_err_t ret = register_select(args);
if (ret != ESP_OK) {
free(args);
return ret;
}
bool trigger_select = false;
// check if the select should return instantly if the bus is read ready
if (FD_ISSET(USJ_LOCAL_FD, &args->readfds_orig) && usb_serial_jtag_read_ready()) {
// signal immediately when data is buffered
FD_SET(USJ_LOCAL_FD, readfds);
trigger_select = true;
}
// check if the select should return instantly if the bus is write ready
if (FD_ISSET(USJ_LOCAL_FD, &args->writefds_orig) && usb_serial_jtag_write_ready()) {
// signal immediately when data can be written
FD_SET(USJ_LOCAL_FD, writefds);
trigger_select = true;
}
if (trigger_select) {
esp_vfs_select_triggered(args->select_sem);
}
*end_select_args = args;
return ESP_OK;
}
static esp_err_t usb_serial_jtag_end_select(void *end_select_args)
{
usb_serial_jtag_select_args_t *args = end_select_args;
esp_err_t ret = unregister_select(args);
if (args) {
free(args);
}
return ret;
}
#endif // CONFIG_VFS_SUPPORT_SELECT
#ifdef CONFIG_VFS_SUPPORT_TERMIOS #ifdef CONFIG_VFS_SUPPORT_TERMIOS
static int usb_serial_jtag_tcsetattr(int fd, int optional_actions, const struct termios *p) static int usb_serial_jtag_tcsetattr(int fd, int optional_actions, const struct termios *p)
{ {
@@ -391,6 +580,10 @@ static const esp_vfs_t usj_vfs = {
.read = &usb_serial_jtag_read, .read = &usb_serial_jtag_read,
.fcntl = &usb_serial_jtag_fcntl, .fcntl = &usb_serial_jtag_fcntl,
.fsync = &usb_serial_jtag_fsync, .fsync = &usb_serial_jtag_fsync,
#ifdef CONFIG_VFS_SUPPORT_SELECT
.start_select = &usb_serial_jtag_start_select,
.end_select = &usb_serial_jtag_end_select,
#endif // CONFIG_VFS_SUPPORT_SELECT
#ifdef CONFIG_VFS_SUPPORT_TERMIOS #ifdef CONFIG_VFS_SUPPORT_TERMIOS
.tcsetattr = &usb_serial_jtag_tcsetattr, .tcsetattr = &usb_serial_jtag_tcsetattr,
.tcgetattr = &usb_serial_jtag_tcgetattr, .tcgetattr = &usb_serial_jtag_tcgetattr,

View File

@@ -11,3 +11,14 @@ components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag:
- vfs - vfs
- esp_driver_gpio - esp_driver_gpio
- esp_driver_usb_serial_jtag - esp_driver_usb_serial_jtag
components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag_vfs:
disable:
- if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1
disable_test:
- if: IDF_TARGET in ["esp32p4", "esp32c5", "esp32c61"]
temporary: true
reason: No runners.
depends_components:
- vfs
- esp_driver_usb_serial_jtag

View File

@@ -0,0 +1,11 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components")
list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults")
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(usb_serial_jtag_vfs_test)

View File

@@ -0,0 +1,2 @@
| Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |

View File

@@ -0,0 +1,9 @@
set(src "test_app_main.c"
"test_vfs_usb_serial_jtag.c"
)
idf_component_register(SRCS ${src}
PRIV_INCLUDE_DIRS .
PRIV_REQUIRES esp_driver_usb_serial_jtag unity test_utils esp_psram
WHOLE_ARCHIVE
)

View File

@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
// Some resources are lazy allocated, the threadhold is left for that case
#define TEST_MEMORY_LEAK_THRESHOLD (500)
void setUp(void)
{
unity_utils_record_free_mem();
}
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
unity_run_menu();
}

View File

@@ -0,0 +1,130 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/termios.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <unistd.h>
#include "unity.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/usb_serial_jtag_vfs.h"
#include "driver/usb_serial_jtag.h"
#include "hal/usb_serial_jtag_ll.h"
#include "esp_clk_tree.h"
#include "test_utils.h"
#include "sdkconfig.h"
struct task_arg_t {
FILE* stream;
SemaphoreHandle_t done;
};
static int read_bytes_with_select(FILE *stream, void *buf, size_t buf_len, struct timeval tv)
{
int fd = fileno(stream);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
/* call select with to wait for either a read ready or timeout to happen */
int nread = select(fd + 1, &read_fds, NULL, NULL, &tv);
if (nread < 0) {
return -1;
} else if (FD_ISSET(fd, &read_fds)) {
int read_count = 0;
int total_read = 0;
do {
read_count = read(fileno(stream), buf + total_read, buf_len - total_read);
if (read_count < 0 && errno != EWOULDBLOCK) {
return -1;
} else if (read_count > 0) {
total_read += read_count;
if (total_read > buf_len) {
fflush(stream);
break;
}
}
} while (read_count > 0);
return total_read;
} else {
return -2;
}
}
/* In this test, the select returning on timeout, write and read ready functionalities
* are under test. To achieve that, the testing environment:
* 0) Starts the test
* 1) Waits for the select to timeout (read_bytes_with_select returns timeout error which
* triggers the sending of the timeout message back to the testing environment)
* 2) Sends the test message (read_bytes_with_select returns with the received message that
* is sent back to the testing environment to be checked)
* 3) A parallel tasks calls select on stdout for writing and decrement a variable for every
* write calls. At the end of the test, the variable is check to make sure the select returned
* for each of the write calls.
*/
TEST_CASE("test select read, write and timeout", "[usb_serial_jtag]")
{
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
char out_buffer[32];
memset(out_buffer, 0, sizeof(out_buffer));
size_t out_buffer_len = sizeof(out_buffer);
// stdin needs to be non blocking to properly call read after select returns
// with read ready on stdin.
int fd = fileno(stdin);
int flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
int res = fcntl(fd, F_SETFL, flags);
TEST_ASSERT(res == 0);
// init driver
usb_serial_jtag_driver_config_t usj_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
ESP_ERROR_CHECK(usb_serial_jtag_driver_install(&usj_config));
usb_serial_jtag_vfs_use_driver();
// send the message from pytest environment and make sure it can be read
bool message_received = false;
size_t char_read = 0;
while (!message_received && out_buffer_len > char_read) {
int nread = read_bytes_with_select(stdin, out_buffer + char_read, out_buffer_len - char_read, tv);
if (nread > 0) {
char_read += nread;
if (out_buffer[char_read - 1] == '\n') {
message_received = true;
}
} else if (nread == -2) {
// time out occurred, send the expected message back to the testing
// environment to trigger the testing environment into sending the
// test message. don't update this message without updating the pytest
// function since the string is expected as is by the test environment
char timeout_msg[] = "select timed out\n";
write(fileno(stdout), timeout_msg, sizeof(timeout_msg));
} else {
break;
}
}
// write the received message back to the test environment. The test
// environment will check that the message received matches the one sent
write(fileno(stdout), out_buffer, char_read);
// wait for the string to send
vTaskDelay(10);
usb_serial_jtag_vfs_use_nonblocking();
usb_serial_jtag_driver_uninstall();
}

View File

@@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.usb_serial_jtag
@pytest.mark.parametrize(
'port, flash_port, config',
[
pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'release'),
],
indirect=True,)
@pytest.mark.parametrize('test_message', ['test123456789!@#%^&*'])
def test_usj_vfs_release(dut: Dut, test_message: list) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('\"test select read, write and timeout\"')
dut.expect_exact('select timed out', timeout=2)
dut.write(test_message)
dut.expect_exact(test_message, timeout=2)
dut.expect(r'\d{1} Tests 0 Failures 0 Ignored', timeout=10)

View File

@@ -0,0 +1,6 @@
CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y

View File

@@ -0,0 +1,8 @@
# Enable Unity fixture support
CONFIG_UNITY_ENABLE_FIXTURE=n
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
# Custom partition table for this test app
CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y