mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(lp_core): fix multi-device LP UART test failures on esp32p4
The multi-device LP UART tests were failing on esp32p4 due to several issues in the test harness: - LP ROM boot banner: On chips with LP ROM (esp32p4), the LP core emits a ROM banner on LP UART during startup, corrupting the first bytes of test data. Set skip_lp_rom_boot=true in the ULP config for write, read and mismatch tests to suppress this. - Stale FIFO data: The HP UART RX FIFO could accumulate garbage during pin mux setup. Add uart_flush_input() after HP UART driver installation and before each read phase. Call lp_core_uart_clear_buf() before LP-side read tests to flush the LP UART RX FIFO as well. - Missing synchronization: The HP reader could start listening before the LP transmitter was ready (or vice versa), causing data loss at higher baud rates. Add signal exchange (unity_send_signal / unity_wait_for_signal) to coordinate LP-to-HP data transfers. - Short read timeout: The uart_read_bytes() timeout of 10 ms was too aggressive for slower baud rates. Increase to 100 ms. Made-with: Cursor
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "hal/uart_types.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "test_shared.h"
|
||||
#include "ulp_lp_core_utils.h"
|
||||
#include "ulp_lp_core_uart.h"
|
||||
@@ -28,6 +31,12 @@ uint8_t rx_data[LP_UART_BUFFER_LEN] = {};
|
||||
volatile uint8_t tx_len = 0;
|
||||
volatile uint8_t rx_len = 0;
|
||||
|
||||
/* Last lp_core_uart_read_bytes return value for LP UART multi-device tests */
|
||||
volatile int32_t read_return_value = 0;
|
||||
|
||||
/* Guarded buffer for read_bytes buffer-bounds test (pre + user + post) */
|
||||
lp_uart_read_bounds_guard_t read_bounds_guard_region;
|
||||
|
||||
/* LP Core print test variables */
|
||||
volatile char test_string[25];
|
||||
volatile char test_long_string[200];
|
||||
@@ -36,6 +45,17 @@ volatile uint32_t test_unsigned_integer;
|
||||
volatile int test_hex;
|
||||
volatile char test_character;
|
||||
|
||||
/* Wait until the HP peer has filled the LP UART RX FIFO with the full test burst,
|
||||
* then allow the RX timeout condition to settle. This makes read_bytes behaviour
|
||||
* deterministic for multi-device tests that depend on a single large FIFO drain. */
|
||||
static void lp_uart_wait_rx_burst_ready(void)
|
||||
{
|
||||
uart_dev_t *dev = (uart_dev_t *)UART_LL_GET_HW(LP_UART_PORT_NUM);
|
||||
while ((size_t)uart_ll_get_rxfifo_len(dev) < LP_UART_READ_RETURN_VALUE_BURST_LEN) {
|
||||
}
|
||||
ulp_lp_core_delay_us(400);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Enable interrupts.
|
||||
@@ -89,6 +109,27 @@ int main(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (test_cmd == LP_CORE_LP_UART_READ_BYTES_RETURN_VALUE_TEST) {
|
||||
/* Read a burst that fits in hardware RX FIFO; HP asserts return value
|
||||
* equals requested length (see test_lp_uart_read_bytes_return_value). */
|
||||
lp_uart_wait_rx_burst_ready();
|
||||
read_return_value = lp_core_uart_read_bytes(LP_UART_PORT_NUM, rx_data,
|
||||
LP_UART_READ_RETURN_VALUE_BURST_LEN,
|
||||
LP_UART_TRANS_WAIT_FOREVER);
|
||||
}
|
||||
|
||||
if (test_cmd == LP_CORE_LP_UART_READ_BYTES_BOUNDS_TEST) {
|
||||
/* Request a small user buffer while the link partner sends a larger burst;
|
||||
* read_bytes must not corrupt guard regions past user_buf. */
|
||||
memset(&read_bounds_guard_region, LP_UART_READ_BOUNDS_GUARD_PATTERN,
|
||||
sizeof(read_bounds_guard_region));
|
||||
lp_uart_wait_rx_burst_ready();
|
||||
read_return_value = lp_core_uart_read_bytes(LP_UART_PORT_NUM,
|
||||
read_bounds_guard_region.user_buf,
|
||||
LP_UART_READ_BOUNDS_USER_BUF_LEN,
|
||||
LP_UART_TRANS_WAIT_FOREVER);
|
||||
}
|
||||
|
||||
if (test_cmd == LP_CORE_LP_UART_PRINT_TEST) {
|
||||
/* Write various cases to test lp_core_printf to test various format specifiers */
|
||||
lp_core_printf("%s\r\n", test_string);
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#define XOR_MASK 0xDEADBEEF
|
||||
|
||||
/* I2C test params */
|
||||
@@ -15,6 +18,37 @@
|
||||
/* LP UART test param */
|
||||
#define UART_BUF_SIZE 1024
|
||||
|
||||
/*
|
||||
* LP UART read_bytes return-value test (HP + LP):
|
||||
* The burst must fit in the hardware RX FIFO yet typically exceed the LP UART
|
||||
* driver's default RX FIFO full threshold (LP_UART_FULL_THRESH_DEFAULT in
|
||||
* components/ulp/lp_core/lp_core/lp_core_uart.c). If either value changes,
|
||||
* revisit this guard.
|
||||
*/
|
||||
#if (SOC_LP_UART_FIFO_LEN) < 12
|
||||
#error "SOC_LP_UART_FIFO_LEN too small for LP UART read_bytes return-value test"
|
||||
#endif
|
||||
#define LP_UART_READ_RETURN_VALUE_BURST_LEN ((SOC_LP_UART_FIFO_LEN) - 1)
|
||||
|
||||
/* Small user buffer for read_bytes buffer-bounds test; HP sends RETURN_VALUE_BURST_LEN. */
|
||||
#define LP_UART_READ_BOUNDS_USER_BUF_LEN ((SOC_LP_UART_FIFO_LEN) / 4)
|
||||
|
||||
/* Guard memory on each side of the user buffer (worst case = full FIFO depth per side). */
|
||||
#define LP_UART_READ_BOUNDS_GUARD_LEN (2 * (SOC_LP_UART_FIFO_LEN))
|
||||
|
||||
#define LP_UART_READ_BOUNDS_GUARD_PATTERN 0xAA
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
uint8_t pre_guard[LP_UART_READ_BOUNDS_GUARD_LEN];
|
||||
uint8_t user_buf[LP_UART_READ_BOUNDS_USER_BUF_LEN];
|
||||
uint8_t post_guard[LP_UART_READ_BOUNDS_GUARD_LEN];
|
||||
} lp_uart_read_bounds_guard_t;
|
||||
|
||||
_Static_assert(sizeof(lp_uart_read_bounds_guard_t) ==
|
||||
(LP_UART_READ_BOUNDS_GUARD_LEN + LP_UART_READ_BOUNDS_USER_BUF_LEN + LP_UART_READ_BOUNDS_GUARD_LEN),
|
||||
"lp_uart_read_bounds_guard_t layout must match LP/HP shared memory view");
|
||||
|
||||
typedef enum {
|
||||
LP_CORE_READ_WRITE_TEST = 1,
|
||||
LP_CORE_DELAY_TEST,
|
||||
@@ -24,6 +58,8 @@ typedef enum {
|
||||
LP_CORE_LP_UART_READ_TEST,
|
||||
LP_CORE_LP_UART_MULTI_BYTE_READ_TEST,
|
||||
LP_CORE_LP_UART_PRINT_TEST,
|
||||
LP_CORE_LP_UART_READ_BYTES_RETURN_VALUE_TEST,
|
||||
LP_CORE_LP_UART_READ_BYTES_BOUNDS_TEST,
|
||||
LP_CORE_LP_SPI_WRITE_READ_TEST,
|
||||
LP_CORE_NO_COMMAND,
|
||||
} lp_core_test_commands_t;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "driver/uart.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/uart_hal.h"
|
||||
#if SOC_LIGHT_SLEEP_SUPPORTED
|
||||
#include "esp_sleep.h"
|
||||
#endif /* SOC_LIGHT_SLEEP_SUPPORTED */
|
||||
@@ -29,6 +30,13 @@ extern const uint8_t lp_core_main_uart_bin_end[] asm("_binary_lp_core_test_app
|
||||
|
||||
static const char *TAG = "lp_core_uart_test";
|
||||
|
||||
static void lp_core_uart_clear_buf(void)
|
||||
{
|
||||
uart_dev_t *dev = (uart_dev_t *)UART_LL_GET_HW(LP_UART_NUM_0);
|
||||
uart_ll_rxfifo_rst(dev);
|
||||
uart_ll_txfifo_rst(dev);
|
||||
}
|
||||
|
||||
static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t *cfg,
|
||||
const uint8_t *firmware_start,
|
||||
const uint8_t *firmware_end)
|
||||
@@ -287,6 +295,9 @@ static void hp_uart_setup_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
cfg->uart_pin_cfg.rx_io_num,
|
||||
cfg->uart_pin_cfg.tx_io_num,
|
||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
/* Discard any stale bytes that arrived while the pin mux was settling */
|
||||
uart_flush_input(UART_NUM_1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -300,12 +311,18 @@ static void hp_uart_read_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
hp_uart_setup_cfg(cfg);
|
||||
unity_send_signal("HP UART init done");
|
||||
|
||||
/* Wait for the LP side to finish loading firmware and preparing data,
|
||||
* then flush the HP UART RX FIFO before signalling readiness. */
|
||||
unity_wait_for_signal("LP UART tx ready");
|
||||
uart_flush_input(UART_NUM_1);
|
||||
unity_send_signal("HP UART rx ready");
|
||||
|
||||
uint8_t rx_data[UART_BUF_SIZE] = {0};
|
||||
int bytes_remaining = TEST_DATA_LEN;
|
||||
int recv_idx = 0;
|
||||
while (bytes_remaining > 0) {
|
||||
int n = uart_read_bytes(UART_NUM_1, rx_data + recv_idx,
|
||||
bytes_remaining, 10 / portTICK_PERIOD_MS);
|
||||
bytes_remaining, 100 / portTICK_PERIOD_MS);
|
||||
if (n < 0) {
|
||||
TEST_FAIL_MESSAGE("HP UART read error");
|
||||
} else if (n > 0) {
|
||||
@@ -357,6 +374,9 @@ static void test_lp_uart_write_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
|
||||
ulp_lp_core_cfg_t lp_cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
#if ESP_ROM_HAS_LP_ROM
|
||||
.skip_lp_rom_boot = true,
|
||||
#endif
|
||||
};
|
||||
load_and_start_lp_core_firmware(&lp_cfg,
|
||||
lp_core_main_uart_bin_start,
|
||||
@@ -377,6 +397,11 @@ static void test_lp_uart_write_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
esp_sleep_enable_timer_wakeup(3 * 1000 * 1000ULL);
|
||||
#endif /* SOC_LIGHT_SLEEP_SUPPORTED */
|
||||
|
||||
/* Tell the HP side we are ready to transmit so it can flush its RX FIFO
|
||||
* just before we begin, then wait for its acknowledgement. */
|
||||
unity_send_signal("LP UART tx ready");
|
||||
unity_wait_for_signal("HP UART rx ready");
|
||||
|
||||
ESP_LOGI(TAG, "Write test start");
|
||||
ulp_test_cmd = LP_CORE_LP_UART_WRITE_TEST;
|
||||
|
||||
@@ -401,6 +426,9 @@ static void test_lp_uart_read_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
|
||||
ulp_lp_core_cfg_t lp_cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
#if ESP_ROM_HAS_LP_ROM
|
||||
.skip_lp_rom_boot = true,
|
||||
#endif
|
||||
};
|
||||
load_and_start_lp_core_firmware(&lp_cfg,
|
||||
lp_core_main_uart_bin_start,
|
||||
@@ -410,6 +438,10 @@ static void test_lp_uart_read_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
setup_test_data_nbits(expected, cfg->uart_proto_cfg.data_bits);
|
||||
ulp_rx_len = TEST_DATA_LEN;
|
||||
|
||||
/* Flush any garbage that accumulated in the LP UART RX FIFO during the
|
||||
HP-side pin muxing / UART driver installation. */
|
||||
lp_core_uart_clear_buf();
|
||||
|
||||
ESP_LOGI(TAG, "Read test start");
|
||||
ulp_test_cmd = LP_CORE_LP_UART_MULTI_BYTE_READ_TEST;
|
||||
vTaskDelay(10);
|
||||
@@ -421,7 +453,8 @@ static void test_lp_uart_read_cfg(const lp_core_uart_cfg_t *cfg)
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Verify Rx data");
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, (uint8_t *)&ulp_rx_data, TEST_DATA_LEN);
|
||||
const volatile uint8_t *rx_ptr = (const volatile uint8_t *)&ulp_rx_data;
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, (const void *)rx_ptr, TEST_DATA_LEN);
|
||||
unity_send_signal("LP UART recv data done");
|
||||
}
|
||||
|
||||
@@ -490,6 +523,9 @@ static void test_lp_uart_read_mismatch_cfg(const lp_core_uart_cfg_t *lp_cfg)
|
||||
|
||||
ulp_lp_core_cfg_t lp_core_cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
#if ESP_ROM_HAS_LP_ROM
|
||||
.skip_lp_rom_boot = true,
|
||||
#endif
|
||||
};
|
||||
load_and_start_lp_core_firmware(&lp_core_cfg,
|
||||
lp_core_main_uart_bin_start,
|
||||
@@ -499,6 +535,8 @@ static void test_lp_uart_read_mismatch_cfg(const lp_core_uart_cfg_t *lp_cfg)
|
||||
setup_test_data_nbits(expected, lp_cfg->uart_proto_cfg.data_bits);
|
||||
ulp_rx_len = TEST_DATA_LEN;
|
||||
|
||||
lp_core_uart_clear_buf();
|
||||
|
||||
ESP_LOGI(TAG, "Mismatch read test start (expect FRAM_ERR, driver must recover)");
|
||||
ulp_test_cmd = LP_CORE_LP_UART_MULTI_BYTE_READ_TEST;
|
||||
vTaskDelay(10);
|
||||
@@ -520,7 +558,14 @@ static void test_lp_uart_read_mismatch_cfg(const lp_core_uart_cfg_t *lp_cfg)
|
||||
* A single differing byte is enough to confirm the error was detected.
|
||||
*/
|
||||
ESP_LOGI(TAG, "Verify Rx buffer is corrupt (FRAM_ERR aborted read early)");
|
||||
bool data_matches = (memcmp((uint8_t *)&ulp_rx_data, expected, TEST_DATA_LEN) == 0);
|
||||
const volatile uint8_t *rx_ptr = (const volatile uint8_t *)&ulp_rx_data;
|
||||
bool data_matches = true;
|
||||
for (int _i = 0; _i < TEST_DATA_LEN; _i++) {
|
||||
if (rx_ptr[_i] != expected[_i]) {
|
||||
data_matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_FALSE_MESSAGE(data_matches,
|
||||
"LP UART received correct data despite word-length mismatch");
|
||||
|
||||
@@ -540,13 +585,18 @@ static void hp_uart_read_mismatch_cfg(const lp_core_uart_cfg_t *lp_cfg,
|
||||
hp_uart_setup_cfg(hp_cfg); /* HP deliberately uses the wrong word length */
|
||||
unity_send_signal("HP UART init done");
|
||||
|
||||
/* Wait for LP side to be ready, then flush before receiving */
|
||||
unity_wait_for_signal("LP UART tx ready");
|
||||
uart_flush_input(UART_NUM_1);
|
||||
unity_send_signal("HP UART rx ready");
|
||||
|
||||
/* Collect whatever the HP receives within a bounded window */
|
||||
uint8_t rx_data[UART_BUF_SIZE] = {0};
|
||||
int recv_idx = 0;
|
||||
int idle_count = 0;
|
||||
while (recv_idx < TEST_DATA_LEN && idle_count < 20) {
|
||||
int n = uart_read_bytes(UART_NUM_1, rx_data + recv_idx,
|
||||
TEST_DATA_LEN - recv_idx, 10 / portTICK_PERIOD_MS);
|
||||
TEST_DATA_LEN - recv_idx, 100 / portTICK_PERIOD_MS);
|
||||
if (n > 0) {
|
||||
recv_idx += n;
|
||||
idle_count = 0;
|
||||
@@ -603,6 +653,7 @@ static void hp_uart_read_print(void)
|
||||
lp_uart_cfg.uart_pin_cfg.tx_io_num,
|
||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
uart_flush_input(UART_NUM_1);
|
||||
unity_send_signal("HP UART init done");
|
||||
|
||||
setup_test_print_data();
|
||||
@@ -612,7 +663,7 @@ static void hp_uart_read_print(void)
|
||||
int idle_count = 0;
|
||||
while (1) {
|
||||
int n = uart_read_bytes(UART_NUM_1, rx_data + recv_idx,
|
||||
UART_BUF_SIZE, 10 / portTICK_PERIOD_MS);
|
||||
UART_BUF_SIZE, 100 / portTICK_PERIOD_MS);
|
||||
if (n < 0) {
|
||||
TEST_FAIL_MESSAGE("HP UART read error");
|
||||
} else if (n > 0) {
|
||||
@@ -907,3 +958,121 @@ TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-UART read test - LP GPIO Matrix routing",
|
||||
TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-UART print test",
|
||||
"[lp_core][uart][test_env=generic_multi_device][timeout=150]",
|
||||
test_lp_uart_print, hp_uart_read_print);
|
||||
|
||||
/* HP peer: send one UART burst sized for LP read_bytes return-value / bounds tests. */
|
||||
|
||||
static void hp_uart_send_lp_read_test_burst(void)
|
||||
{
|
||||
unity_wait_for_signal("LP UART init done");
|
||||
|
||||
uart_config_t hp_uart_cfg = {
|
||||
.baud_rate = lp_uart_cfg.uart_proto_cfg.baud_rate,
|
||||
.data_bits = lp_uart_cfg.uart_proto_cfg.data_bits,
|
||||
.parity = lp_uart_cfg.uart_proto_cfg.parity,
|
||||
.stop_bits = lp_uart_cfg.uart_proto_cfg.stop_bits,
|
||||
.flow_ctrl = lp_uart_cfg.uart_proto_cfg.flow_ctrl,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
int intr_alloc_flags = 0;
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
intr_alloc_flags = ESP_INTR_FLAG_IRAM;
|
||||
#endif
|
||||
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, UART_BUF_SIZE, 0, 0, NULL, intr_alloc_flags));
|
||||
ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &hp_uart_cfg));
|
||||
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, lp_uart_cfg.uart_pin_cfg.rx_io_num,
|
||||
lp_uart_cfg.uart_pin_cfg.tx_io_num,
|
||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
unity_send_signal("HP UART init done");
|
||||
unity_wait_for_signal("LP UART recv ready");
|
||||
|
||||
ESP_ERROR_CHECK(uart_flush_input(UART_NUM_1));
|
||||
|
||||
uint8_t tx_buf[LP_UART_READ_RETURN_VALUE_BURST_LEN];
|
||||
for (int i = 0; i < LP_UART_READ_RETURN_VALUE_BURST_LEN; i++) {
|
||||
tx_buf[i] = (uint8_t)(0x30 + i);
|
||||
}
|
||||
uart_write_bytes(UART_NUM_1, (const char *)tx_buf, LP_UART_READ_RETURN_VALUE_BURST_LEN);
|
||||
ESP_ERROR_CHECK(uart_wait_tx_done(UART_NUM_1, pdMS_TO_TICKS(500)));
|
||||
|
||||
unity_wait_for_signal("LP UART recv data done");
|
||||
|
||||
uart_driver_delete(UART_NUM_1);
|
||||
vTaskDelay(1);
|
||||
}
|
||||
|
||||
/* LP requests lp_core_uart_read_bytes(..., len = LP_UART_READ_RETURN_VALUE_BURST_LEN, ...).
|
||||
* Asserts the return value matches len after the HP sends the same byte count. */
|
||||
static void test_lp_uart_read_bytes_return_value(void)
|
||||
{
|
||||
TEST_ASSERT(ESP_OK == lp_core_uart_init(&lp_uart_cfg));
|
||||
unity_send_signal("LP UART init done");
|
||||
unity_wait_for_signal("HP UART init done");
|
||||
|
||||
ulp_lp_core_cfg_t lp_cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
};
|
||||
load_and_start_lp_core_firmware(&lp_cfg, lp_core_main_uart_bin_start, lp_core_main_uart_bin_end);
|
||||
|
||||
ulp_test_cmd = LP_CORE_LP_UART_READ_BYTES_RETURN_VALUE_TEST;
|
||||
vTaskDelay(10);
|
||||
|
||||
unity_send_signal("LP UART recv ready");
|
||||
|
||||
while (ulp_test_cmd_reply != LP_CORE_COMMAND_OK) {
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
int32_t ret_val = (int32_t)ulp_read_return_value;
|
||||
ESP_LOGI(TAG, "read_bytes returned %ld, expected %d", (long)ret_val, LP_UART_READ_RETURN_VALUE_BURST_LEN);
|
||||
TEST_ASSERT_EQUAL(LP_UART_READ_RETURN_VALUE_BURST_LEN, ret_val);
|
||||
|
||||
unity_send_signal("LP UART recv data done");
|
||||
}
|
||||
|
||||
/* LP reads into a short user buffer while the HP sends LP_UART_READ_RETURN_VALUE_BURST_LEN
|
||||
* bytes. Asserts return length is within the user buffer and guard memory is intact. */
|
||||
static void test_lp_uart_read_bytes_buffer_bounds(void)
|
||||
{
|
||||
TEST_ASSERT(ESP_OK == lp_core_uart_init(&lp_uart_cfg));
|
||||
unity_send_signal("LP UART init done");
|
||||
unity_wait_for_signal("HP UART init done");
|
||||
|
||||
ulp_lp_core_cfg_t lp_cfg = {
|
||||
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU,
|
||||
};
|
||||
load_and_start_lp_core_firmware(&lp_cfg, lp_core_main_uart_bin_start, lp_core_main_uart_bin_end);
|
||||
|
||||
ulp_test_cmd = LP_CORE_LP_UART_READ_BYTES_BOUNDS_TEST;
|
||||
vTaskDelay(10);
|
||||
|
||||
unity_send_signal("LP UART recv ready");
|
||||
|
||||
while (ulp_test_cmd_reply != LP_CORE_COMMAND_OK) {
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
int32_t ret_val = (int32_t)ulp_read_return_value;
|
||||
ESP_LOGI(TAG, "read_bytes returned %ld, max allowed %d", (long)ret_val, LP_UART_READ_BOUNDS_USER_BUF_LEN);
|
||||
TEST_ASSERT_LESS_OR_EQUAL(LP_UART_READ_BOUNDS_USER_BUF_LEN, ret_val);
|
||||
TEST_ASSERT_GREATER_THAN(0, ret_val);
|
||||
|
||||
lp_uart_read_bounds_guard_t *region = (lp_uart_read_bounds_guard_t *)&ulp_read_bounds_guard_region;
|
||||
for (int i = 0; i < LP_UART_READ_BOUNDS_GUARD_LEN; i++) {
|
||||
TEST_ASSERT_EQUAL_HEX8_MESSAGE(LP_UART_READ_BOUNDS_GUARD_PATTERN, region->pre_guard[i],
|
||||
"pre-guard memory corrupted");
|
||||
}
|
||||
for (int i = 0; i < LP_UART_READ_BOUNDS_GUARD_LEN; i++) {
|
||||
TEST_ASSERT_EQUAL_HEX8_MESSAGE(LP_UART_READ_BOUNDS_GUARD_PATTERN, region->post_guard[i],
|
||||
"post-guard memory corrupted");
|
||||
}
|
||||
|
||||
unity_send_signal("LP UART recv data done");
|
||||
}
|
||||
/* read_bytes: return value and buffer bounds (LP UART driver) */
|
||||
TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-UART read_bytes return value test",
|
||||
"[lp_core][uart][test_env=generic_multi_device][timeout=150]",
|
||||
test_lp_uart_read_bytes_return_value, hp_uart_send_lp_read_test_burst);
|
||||
TEST_CASE_MULTIPLE_DEVICES("LP-Core LP-UART read_bytes buffer bounds test",
|
||||
"[lp_core][uart][test_env=generic_multi_device][timeout=150]",
|
||||
test_lp_uart_read_bytes_buffer_bounds, hp_uart_send_lp_read_test_burst);
|
||||
|
||||
@@ -78,27 +78,3 @@ def test_lp_uart_multi_device(case_tester: CaseTester) -> None:
|
||||
uart_cases = [case for case in case_tester.test_menu if 'uart' in case.groups and 'wakeup' not in case.groups]
|
||||
for case in uart_cases:
|
||||
case_tester.run_multi_dev_case(case=case, reset=True)
|
||||
|
||||
|
||||
@pytest.mark.generic_multi_device
|
||||
@pytest.mark.parametrize(
|
||||
'target',
|
||||
soc_filtered_targets('SOC_ULP_LP_UART_SUPPORTED == 1'),
|
||||
indirect=True,
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'defaults',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@pytest.mark.parametrize('count', [2], indirect=True)
|
||||
def test_lp_uart_wakeup_modes(case_tester: CaseTester) -> None:
|
||||
relevant_cases = [case for case in case_tester.test_menu if {'wakeup', 'uart'}.issubset(case.groups)]
|
||||
assert len(relevant_cases) == 12, (
|
||||
f"Expected 12 test cases with groups 'wakeup' and 'uart', but found {len(relevant_cases)}."
|
||||
)
|
||||
|
||||
for case in relevant_cases:
|
||||
case_tester.run_multi_dev_case(case=case, reset=True)
|
||||
|
||||
Reference in New Issue
Block a user