mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
test(driver_twai): test app rename and add cache safe test
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
set(COMPONENTS main)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(twai_test)
|
||||
|
||||
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||
add_custom_target(check_test_app_sections ALL
|
||||
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
|
||||
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
||||
--elf-file ${CMAKE_BINARY_DIR}/twai_test.elf
|
||||
find-refs
|
||||
--from-sections=.iram0.text
|
||||
--to-sections=.flash.text,.flash.rodata
|
||||
--exit-code
|
||||
DEPENDS ${elf}
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,8 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# Enable Socket CAN Device with bitrate 250Kbps
|
||||
|
||||
```bash
|
||||
sudo ip link set can0 up type can bitrate 250000 restart-ms 100
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
set(srcs "test_app_main.c"
|
||||
"test_twai_loop_back.c"
|
||||
"test_twai_interactive.c")
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES unity driver
|
||||
WHOLE_ARCHIVE)
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_newlib.h"
|
||||
|
||||
// Some resources are lazy allocated in the TWAI driver, the threshold is left for that case
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (200)
|
||||
|
||||
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)
|
||||
{
|
||||
// _______ ___ ___ _____ _
|
||||
// |_ _\ \ / / \ |_ _| |_ _|__ ___| |_
|
||||
// | | \ \ /\ / / _ \ | | | |/ _ \/ __| __|
|
||||
// | | \ V V / ___ \ | | | | __/\__ \ |_
|
||||
// |_| \_/\_/_/ \_\___| |_|\___||___/\__|
|
||||
printf(" _______ ___ ___ _____ _\n");
|
||||
printf("|_ _\\ \\ / / \\ |_ _| |_ _|__ ___| |_\n");
|
||||
printf(" | | \\ \\ /\\ / / _ \\ | | | |/ _ \\/ __| __|\n");
|
||||
printf(" | | \\ V V / ___ \\ | | | | __/\\__ \\ |_\n");
|
||||
printf(" |_| \\_/\\_/_/ \\_\\___| |_|\\___||___/\\__|\n");
|
||||
unity_run_menu();
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "driver/twai.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#define TEST_TWAI_TX_PIN 4
|
||||
#define TEST_TWAI_RX_PIN 5
|
||||
|
||||
#if CONFIG_TWAI_ISR_IN_IRAM
|
||||
static void IRAM_ATTR test_delay_post_cache_disable(void *args)
|
||||
{
|
||||
esp_rom_delay_us(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("twai_listen_only", "[twai]")
|
||||
{
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TEST_TWAI_TX_PIN, TEST_TWAI_RX_PIN, TWAI_MODE_LISTEN_ONLY);
|
||||
#if CONFIG_TWAI_ISR_IN_IRAM
|
||||
g_config.intr_flags |= ESP_INTR_FLAG_IRAM;
|
||||
#endif
|
||||
// listen only mode doesn't need a tx queue
|
||||
g_config.tx_queue_len = 0;
|
||||
TEST_ESP_OK(twai_driver_install(&g_config, &t_config, &f_config));
|
||||
TEST_ESP_OK(twai_start());
|
||||
|
||||
#if CONFIG_TWAI_ISR_IN_IRAM
|
||||
printf("disable flash cache and check if we can still receive the frame\n");
|
||||
for (int i = 0; i < 100; i++) {
|
||||
unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t expected_data[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
|
||||
twai_message_t rx_msg;
|
||||
TEST_ESP_OK(twai_receive(&rx_msg, portMAX_DELAY));
|
||||
|
||||
TEST_ASSERT_EQUAL(0x123, rx_msg.identifier);
|
||||
ESP_LOG_BUFFER_HEX("rx", rx_msg.data, rx_msg.data_length_code);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_msg.data, rx_msg.data_length_code);
|
||||
|
||||
TEST_ESP_OK(twai_stop());
|
||||
TEST_ESP_OK(twai_driver_uninstall());
|
||||
}
|
||||
|
||||
TEST_CASE("twai_remote_request", "[twai]")
|
||||
{
|
||||
twai_handle_t bus_handle;
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TEST_TWAI_TX_PIN, TEST_TWAI_RX_PIN, TWAI_MODE_NORMAL);
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32P4
|
||||
g_config.controller_id = 1;
|
||||
#endif
|
||||
TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &bus_handle));
|
||||
TEST_ESP_OK(twai_start_v2(bus_handle));
|
||||
|
||||
twai_message_t req_msg = {
|
||||
.identifier = 0x6688,
|
||||
.data_length_code = 8,
|
||||
.rtr = true, // remote request
|
||||
.extd = true,// extended ID
|
||||
};
|
||||
TEST_ESP_OK(twai_transmit_v2(bus_handle, &req_msg, portMAX_DELAY));
|
||||
ESP_LOGI("TWAI", "send remote frame");
|
||||
|
||||
uint8_t expected_data[8] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
|
||||
twai_message_t res_msg;
|
||||
TEST_ESP_OK(twai_receive_v2(bus_handle, &res_msg, portMAX_DELAY));
|
||||
ESP_LOGI("TWAI", "receive with id %lx\n", res_msg.identifier);
|
||||
TEST_ASSERT_EQUAL(0x6688, res_msg.identifier);
|
||||
ESP_LOG_BUFFER_HEX("rx", res_msg.data, res_msg.data_length_code);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, res_msg.data, res_msg.data_length_code);
|
||||
|
||||
TEST_ESP_OK(twai_stop_v2(bus_handle));
|
||||
TEST_ESP_OK(twai_driver_uninstall_v2(bus_handle));
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
#include "driver/twai.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_private/sleep_cpu.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
|
||||
TEST_CASE("driver_life_cycle", "[twai-loop-back]")
|
||||
{
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_100KBITS();
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 0, TWAI_MODE_NO_ACK);
|
||||
printf("install driver\r\n");
|
||||
TEST_ESP_OK(twai_driver_install(&g_config, &t_config, &f_config));
|
||||
// can't install the driver multiple times
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, twai_driver_install(&g_config, &t_config, &f_config));
|
||||
|
||||
printf("start driver\r\n");
|
||||
TEST_ESP_OK(twai_start());
|
||||
// can't start the driver again if it's already in running state
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, twai_start());
|
||||
// can't uninstall the driver before stopping it
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, twai_driver_uninstall());
|
||||
|
||||
printf("stop driver\r\n");
|
||||
TEST_ESP_OK(twai_stop());
|
||||
printf("uninstall driver\r\n");
|
||||
TEST_ESP_OK(twai_driver_uninstall());
|
||||
}
|
||||
|
||||
TEST_CASE("twai_bit_timing", "[twai-loop-back]")
|
||||
{
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 0, TWAI_MODE_NO_ACK);
|
||||
twai_timing_config_t t_config = {
|
||||
.quanta_resolution_hz = 33333, // invalid resolution
|
||||
.tseg_1 = 15,
|
||||
.tseg_2 = 4,
|
||||
.sjw = 1,
|
||||
};
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, twai_driver_install(&g_config, &t_config, &f_config));
|
||||
|
||||
t_config.quanta_resolution_hz = 2000000;
|
||||
TEST_ESP_OK(twai_driver_install(&g_config, &t_config, &f_config));
|
||||
TEST_ESP_OK(twai_driver_uninstall());
|
||||
}
|
||||
|
||||
TEST_CASE("twai_mode_std_no_ack_25kbps", "[twai-loop-back]")
|
||||
{
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_25KBITS();
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
// bind the TX and RX to the same GPIO to act like a loopback
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 0, TWAI_MODE_NO_ACK);
|
||||
printf("install twai driver\r\n");
|
||||
TEST_ESP_OK(twai_driver_install(&g_config, &t_config, &f_config));
|
||||
TEST_ESP_OK(twai_start());
|
||||
|
||||
twai_message_t tx_msg = {
|
||||
.identifier = 0x123,
|
||||
.data_length_code = 8,
|
||||
.data = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88},
|
||||
.self = true, // Transmitted message will also received by the same node
|
||||
};
|
||||
printf("transmit message\r\n");
|
||||
TEST_ESP_OK(twai_transmit(&tx_msg, pdMS_TO_TICKS(1000)));
|
||||
|
||||
printf("receive message\r\n");
|
||||
twai_message_t rx_msg;
|
||||
TEST_ESP_OK(twai_receive(&rx_msg, pdMS_TO_TICKS(1000)));
|
||||
TEST_ASSERT_TRUE(rx_msg.data_length_code == 8);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
TEST_ASSERT_EQUAL(tx_msg.data[i], rx_msg.data[i]);
|
||||
}
|
||||
|
||||
TEST_ESP_OK(twai_stop());
|
||||
TEST_ESP_OK(twai_driver_uninstall());
|
||||
}
|
||||
|
||||
TEST_CASE("twai_mode_ext_no_ack_250kbps", "[twai-loop-back]")
|
||||
{
|
||||
twai_handle_t twai_buses[SOC_TWAI_CONTROLLER_NUM] = {0};
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
// bind the TX and RX to the same GPIO to act like a loopback
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 0, TWAI_MODE_NO_ACK);
|
||||
twai_message_t tx_msg = {
|
||||
.identifier = 0x12345,
|
||||
.data_length_code = 6,
|
||||
.data = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
|
||||
.self = true, // Transmitted message will also received by the same node
|
||||
.extd = true, // Extended Frame Format (29bit ID)
|
||||
};
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
g_config.controller_id = i;
|
||||
g_config.tx_io = i;
|
||||
g_config.rx_io = i;
|
||||
printf("install twai driver %d\r\n", g_config.controller_id);
|
||||
TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &twai_buses[i]));
|
||||
TEST_ESP_OK(twai_start_v2(twai_buses[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
printf("transmit message from %d\r\n", i);
|
||||
tx_msg.data[5] = SOC_TWAI_CONTROLLER_NUM - i;
|
||||
TEST_ESP_OK(twai_transmit_v2(twai_buses[i], &tx_msg, pdMS_TO_TICKS(1000)));
|
||||
}
|
||||
|
||||
twai_message_t rx_msg;
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
printf("receive message from %d\r\n", i);
|
||||
TEST_ESP_OK(twai_receive_v2(twai_buses[i], &rx_msg, pdMS_TO_TICKS(1000)));
|
||||
TEST_ASSERT_TRUE(rx_msg.data_length_code == 6);
|
||||
tx_msg.data[5] = SOC_TWAI_CONTROLLER_NUM - i;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
TEST_ASSERT_EQUAL(tx_msg.data[i], rx_msg.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
TEST_ESP_OK(twai_stop_v2(twai_buses[i]));
|
||||
TEST_ESP_OK(twai_driver_uninstall_v2(twai_buses[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void s_test_sleep_retention(bool allow_pd)
|
||||
{
|
||||
// Prepare a TOP PD sleep
|
||||
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(1 * 1000 * 1000));
|
||||
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||
TEST_ESP_OK(sleep_cpu_configure(true));
|
||||
#endif
|
||||
esp_sleep_context_t sleep_ctx;
|
||||
esp_sleep_set_sleep_context(&sleep_ctx);
|
||||
|
||||
twai_handle_t twai_buses[SOC_TWAI_CONTROLLER_NUM] = {0};
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS();
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
// bind the TX and RX to the same GPIO to act like a loopback
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 0, TWAI_MODE_NO_ACK);
|
||||
g_config.general_flags.sleep_allow_pd = allow_pd;
|
||||
twai_message_t tx_msg = {
|
||||
.identifier = 0x12345,
|
||||
.data_length_code = 6,
|
||||
.data = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
|
||||
.self = true, // Transmitted message will also received by the same node
|
||||
.extd = true, // Extended Frame Format (29bit ID)
|
||||
};
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
g_config.controller_id = i;
|
||||
g_config.tx_io = i;
|
||||
g_config.rx_io = i;
|
||||
printf("install twai driver %d\r\n", g_config.controller_id);
|
||||
TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &twai_buses[i]));
|
||||
}
|
||||
|
||||
printf("Going into sleep...\n");
|
||||
TEST_ESP_OK(esp_light_sleep_start());
|
||||
printf("Waked up!\n");
|
||||
|
||||
// check if the sleep happened as expected
|
||||
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
|
||||
#if SOC_TWAI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
// check if the power domain also is powered down
|
||||
TEST_ASSERT_EQUAL(allow_pd ? PMU_SLEEP_PD_TOP : 0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
TEST_ESP_OK(twai_start_v2(twai_buses[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
printf("transmit message from %d\r\n", i);
|
||||
tx_msg.data[5] = SOC_TWAI_CONTROLLER_NUM - i;
|
||||
TEST_ESP_OK(twai_transmit_v2(twai_buses[i], &tx_msg, pdMS_TO_TICKS(1000)));
|
||||
}
|
||||
|
||||
twai_message_t rx_msg;
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
printf("receive message from %d\r\n", i);
|
||||
TEST_ESP_OK(twai_receive_v2(twai_buses[i], &rx_msg, pdMS_TO_TICKS(1000)));
|
||||
TEST_ASSERT_TRUE(rx_msg.data_length_code == 6);
|
||||
tx_msg.data[5] = SOC_TWAI_CONTROLLER_NUM - i;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
TEST_ASSERT_EQUAL(tx_msg.data[i], rx_msg.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SOC_TWAI_CONTROLLER_NUM; i++) {
|
||||
TEST_ESP_OK(twai_stop_v2(twai_buses[i]));
|
||||
TEST_ESP_OK(twai_driver_uninstall_v2(twai_buses[i]));
|
||||
}
|
||||
|
||||
esp_sleep_set_sleep_context(NULL);
|
||||
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||
TEST_ESP_OK(sleep_cpu_configure(false));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SOC_TWAI_SUPPORT_SLEEP_RETENTION
|
||||
TEST_CASE("twai_mode_ext_no_ack_250kbps with sleep retention (allow pd)", "[twai-loop-back]")
|
||||
{
|
||||
s_test_sleep_retention(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("twai_mode_ext_no_ack_250kbps with sleep retention (no pd)", "[twai-loop-back]")
|
||||
{
|
||||
s_test_sleep_retention(false);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import logging
|
||||
import subprocess
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
from can import Bus
|
||||
from can import Message
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'release',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize(
|
||||
'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']
|
||||
)
|
||||
def test_twai_self(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(group='twai-loop-back')
|
||||
|
||||
|
||||
@pytest.fixture(name='socket_can', scope='module')
|
||||
def fixture_create_socket_can() -> Bus:
|
||||
# Set up the socket CAN with the bitrate
|
||||
start_command = 'sudo ip link set can0 up type can bitrate 250000 restart-ms 100'
|
||||
stop_command = 'sudo ip link set can0 down'
|
||||
subprocess.run(start_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
bus = Bus(interface='socketcan', channel='can0', bitrate=250000)
|
||||
yield bus # test invoked here
|
||||
bus.shutdown()
|
||||
subprocess.run(stop_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
|
||||
|
||||
@pytest.mark.twai_std
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'iram_safe',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize(
|
||||
'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']
|
||||
)
|
||||
def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
|
||||
dut.serial.hard_reset()
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
|
||||
# TEST_CASE("twai_listen_only", "[twai]")
|
||||
dut.write('"twai_listen_only"')
|
||||
|
||||
# wait the DUT to block at the receive API
|
||||
sleep(0.03)
|
||||
|
||||
message = Message(
|
||||
arbitration_id=0x123,
|
||||
is_extended_id=False,
|
||||
data=[0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
|
||||
)
|
||||
socket_can.send(message, timeout=0.2)
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
|
||||
@pytest.mark.twai_std
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'release',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize(
|
||||
'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']
|
||||
)
|
||||
def test_twai_remote_request(dut: Dut, socket_can: Bus) -> None:
|
||||
dut.serial.hard_reset()
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
|
||||
# TEST_CASE("twai_remote_request", "[twai]")
|
||||
dut.write('"twai_remote_request"')
|
||||
|
||||
while True:
|
||||
req = socket_can.recv(timeout=0.2)
|
||||
# wait for the remote request frame
|
||||
if req is not None and req.is_remote_frame:
|
||||
break
|
||||
|
||||
logging.info(f'Received message: {req}')
|
||||
|
||||
reply = Message(
|
||||
arbitration_id=req.arbitration_id,
|
||||
is_extended_id=req.is_extended_id,
|
||||
data=[0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80],
|
||||
)
|
||||
socket_can.send(reply, timeout=0.2)
|
||||
print('send', reply)
|
||||
|
||||
dut.expect_unity_test_output()
|
||||
@@ -0,0 +1,12 @@
|
||||
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
||||
CONFIG_TWAI_ISR_IN_IRAM=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_NONE=y
|
||||
|
||||
# silent the error check, as the error string are stored in rodata, causing RTL check failure
|
||||
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
|
||||
|
||||
# place non-ISR FreeRTOS functions in Flash
|
||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||
|
||||
# twai driver uses assert in the ISR code path
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
|
||||
@@ -0,0 +1,7 @@
|
||||
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_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
|
||||
@@ -0,0 +1,4 @@
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
# primitives for checking sleep internal state
|
||||
CONFIG_ESP_SLEEP_DEBUG=y
|
||||
Reference in New Issue
Block a user