mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
Merge branch 'master' into feature/esp32s2beta_update
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ". ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
set(COMPONENT_REQUIRES unity test_utils nvs_flash ulp esp_common)
|
||||
|
||||
register_component()
|
||||
idf_component_register(SRC_DIRS "."
|
||||
INCLUDE_DIRS "." "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
REQUIRES unity test_utils nvs_flash ulp esp_common)
|
||||
|
||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h"
|
||||
COMMAND xxd -i "logo.jpg" "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h"
|
||||
@@ -15,3 +12,5 @@ add_custom_target(esp32_test_logo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test_tjpg
|
||||
add_dependencies(${COMPONENT_LIB} esp32_test_logo)
|
||||
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "-DESP_TIMER_DYNAMIC_OVERFLOW_VAL" APPEND)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_test_dport_xt_highint5")
|
||||
|
@@ -4,7 +4,8 @@
|
||||
|
||||
COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive \
|
||||
-u ld_include_test_dport_xt_highint5 \
|
||||
|
||||
COMPONENT_SRCDIRS := .
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "xtensa/core-macros.h"
|
||||
#include "xtensa/hal.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp32/clk.h"
|
||||
|
||||
@@ -14,11 +16,14 @@
|
||||
#include "soc/uart_periph.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
#define MHZ (1000000)
|
||||
static volatile bool exit_flag;
|
||||
static bool dport_test_result;
|
||||
static bool apb_test_result;
|
||||
uint32_t volatile apb_intr_test_result;
|
||||
|
||||
static void accessDPORT(void *pvParameters)
|
||||
{
|
||||
@@ -60,6 +65,7 @@ static void accessAPB(void *pvParameters)
|
||||
|
||||
void run_tasks(const char *task1_description, void (* task1_func)(void *), const char *task2_description, void (* task2_func)(void *), uint32_t delay_ms)
|
||||
{
|
||||
apb_intr_test_result = 1;
|
||||
int i;
|
||||
TaskHandle_t th[2];
|
||||
xSemaphoreHandle exit_sema[2];
|
||||
@@ -94,7 +100,7 @@ void run_tasks(const char *task1_description, void (* task1_func)(void *), const
|
||||
vSemaphoreDelete(exit_sema[i]);
|
||||
}
|
||||
}
|
||||
TEST_ASSERT(dport_test_result == true && apb_test_result == true);
|
||||
TEST_ASSERT(dport_test_result == true && apb_test_result == true && apb_intr_test_result == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("access DPORT and APB at same time", "[esp32]")
|
||||
@@ -324,3 +330,88 @@ TEST_CASE("BENCHMARK for DPORT access performance", "[freertos]")
|
||||
}
|
||||
BENCHMARK_END("_DPORT_REG_READ");
|
||||
}
|
||||
|
||||
uint32_t xt_highint5_read_apb;
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
timer_isr_handle_t inth;
|
||||
xSemaphoreHandle sync_sema;
|
||||
|
||||
static void init_hi_interrupt(void *arg)
|
||||
{
|
||||
printf("init hi_interrupt on CPU%d \n", xPortGetCoreID());
|
||||
TEST_ESP_OK(esp_intr_alloc(ETS_INTERNAL_TIMER2_INTR_SOURCE, ESP_INTR_FLAG_LEVEL5 | ESP_INTR_FLAG_IRAM, NULL, NULL, &inth));
|
||||
while (exit_flag == false);
|
||||
esp_intr_free(inth);
|
||||
printf("disable hi_interrupt on CPU%d \n", xPortGetCoreID());
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void accessDPORT2_stall_other_cpu(void *pvParameters)
|
||||
{
|
||||
xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters;
|
||||
dport_test_result = true;
|
||||
while (exit_flag == false) {
|
||||
DPORT_STALL_OTHER_CPU_START();
|
||||
XTHAL_SET_CCOMPARE(2, XTHAL_GET_CCOUNT());
|
||||
xt_highint5_read_apb = 1;
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
if (_DPORT_REG_READ(DPORT_DATE_REG) != _DPORT_REG_READ(DPORT_DATE_REG)) {
|
||||
apb_test_result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xt_highint5_read_apb = 0;
|
||||
DPORT_STALL_OTHER_CPU_END();
|
||||
}
|
||||
printf("accessDPORT2_stall_other_cpu finish\n");
|
||||
|
||||
xSemaphoreGive(*sema);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Check stall workaround DPORT and Hi-interrupt", "[esp32]")
|
||||
{
|
||||
xt_highint5_read_apb = 0;
|
||||
dport_test_result = false;
|
||||
apb_test_result = true;
|
||||
TEST_ASSERT(xTaskCreatePinnedToCore(&init_hi_interrupt, "init_hi_intr", 2048, NULL, 6, NULL, 1) == pdTRUE);
|
||||
// Access DPORT(stall other cpu method) - CPU0
|
||||
// STALL - CPU1
|
||||
// Hi-interrupt - CPU1
|
||||
run_tasks("accessDPORT2_stall_other_cpu", accessDPORT2_stall_other_cpu, " - ", NULL, 10000);
|
||||
}
|
||||
|
||||
static void accessDPORT2(void *pvParameters)
|
||||
{
|
||||
xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters;
|
||||
dport_test_result = true;
|
||||
|
||||
TEST_ESP_OK(esp_intr_alloc(ETS_INTERNAL_TIMER2_INTR_SOURCE, ESP_INTR_FLAG_LEVEL5 | ESP_INTR_FLAG_IRAM, NULL, NULL, &inth));
|
||||
|
||||
while (exit_flag == false) {
|
||||
XTHAL_SET_CCOMPARE(2, XTHAL_GET_CCOUNT() + 21);
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
if (DPORT_REG_READ(DPORT_DATE_REG) != DPORT_REG_READ(DPORT_DATE_REG)) {
|
||||
dport_test_result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
esp_intr_free(inth);
|
||||
printf("accessDPORT2 finish\n");
|
||||
|
||||
xSemaphoreGive(*sema);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Check pre-read workaround DPORT and Hi-interrupt", "[esp32]")
|
||||
{
|
||||
xt_highint5_read_apb = 0;
|
||||
dport_test_result = false;
|
||||
apb_test_result = true;
|
||||
// Access DPORT(pre-read method) - CPU1
|
||||
// Hi-interrupt - CPU1
|
||||
run_tasks("accessAPB", accessAPB, "accessDPORT2", accessDPORT2, 10000);
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_UNICORE
|
||||
|
80
components/esp32/test/test_dport_xt_highint5.S
Normal file
80
components/esp32/test/test_dport_xt_highint5.S
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <xtensa/coreasm.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include "freertos/xtensa_context.h"
|
||||
#include "esp_private/panic_reason.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
|
||||
#define L5_INTR_STACK_SIZE 12
|
||||
#define L5_INTR_A2_OFFSET 0
|
||||
#define L5_INTR_A3_OFFSET 4
|
||||
#define L5_INTR_A4_OFFSET 8
|
||||
.data
|
||||
_l5_intr_stack:
|
||||
.space L5_INTR_STACK_SIZE
|
||||
|
||||
.section .iram1,"ax"
|
||||
.global xt_highint5
|
||||
.type xt_highint5,@function
|
||||
.align 4
|
||||
xt_highint5:
|
||||
|
||||
movi a0, xt_highint5_read_apb
|
||||
l32i a0, a0, 0
|
||||
bnez a0, .read_apb_reg
|
||||
|
||||
// Short interrupt
|
||||
esync
|
||||
rsr a0, CCOUNT
|
||||
addi a0, a0, 27
|
||||
wsr a0, CCOMPARE2
|
||||
esync
|
||||
|
||||
rsr a0, EXCSAVE_5 // restore a0
|
||||
rfi 5
|
||||
|
||||
|
||||
|
||||
// read APB reg 10 time.
|
||||
.read_apb_reg:
|
||||
movi a0, _l5_intr_stack
|
||||
s32i a2, a0, L5_INTR_A2_OFFSET
|
||||
s32i a3, a0, L5_INTR_A3_OFFSET
|
||||
s32i a4, a0, L5_INTR_A4_OFFSET
|
||||
|
||||
movi a4, 10 // count of reading
|
||||
movi a0, 0x3ff40078 // read APB reg
|
||||
l32i a2, a0, 0
|
||||
.loop_read_apb_reg:
|
||||
l32i a3, a0, 0
|
||||
bne a3, a2, .need_set_apb_test_result
|
||||
addi a4, a4, -1
|
||||
l32i a2, a0, 0
|
||||
bnez a4, .loop_read_apb_reg
|
||||
j 1f
|
||||
.need_set_apb_test_result:
|
||||
movi a0, apb_intr_test_result // set fail
|
||||
movi a2, 0
|
||||
s32i a2, a0, 0
|
||||
memw
|
||||
1:
|
||||
movi a0, _l5_intr_stack
|
||||
l32i a2, a0, L5_INTR_A2_OFFSET
|
||||
l32i a3, a0, L5_INTR_A3_OFFSET
|
||||
l32i a4, a0, L5_INTR_A4_OFFSET
|
||||
rsync
|
||||
.L_xt_highint5_exit:
|
||||
rsr a0, EXCSAVE_5 // restore a0
|
||||
rfi 5
|
||||
|
||||
/* The linker has no reason to link in this file; all symbols it exports are already defined
|
||||
(weakly!) in the default int handler. Define a symbol here so we can use it to have the
|
||||
linker inspect this anyway. */
|
||||
|
||||
.global ld_include_test_dport_xt_highint5
|
||||
ld_include_test_dport_xt_highint5:
|
||||
#endif // CONFIG_FREERTOS_UNICORE
|
@@ -536,6 +536,61 @@ TEST_CASE("Can delete timer from callback", "[esp_timer]")
|
||||
vSemaphoreDelete(args.notify_from_timer_cb);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
SemaphoreHandle_t delete_start;
|
||||
SemaphoreHandle_t delete_done;
|
||||
SemaphoreHandle_t test_done;
|
||||
esp_timer_handle_t timer;
|
||||
} timer_delete_test_args_t;
|
||||
|
||||
static void timer_delete_task(void* arg)
|
||||
{
|
||||
timer_delete_test_args_t* args = (timer_delete_test_args_t*) arg;
|
||||
xSemaphoreTake(args->delete_start, portMAX_DELAY);
|
||||
printf("Deleting the timer\n");
|
||||
esp_timer_delete(args->timer);
|
||||
printf("Timer deleted\n");
|
||||
xSemaphoreGive(args->delete_done);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void timer_delete_test_callback(void* arg)
|
||||
{
|
||||
timer_delete_test_args_t* args = (timer_delete_test_args_t*) arg;
|
||||
printf("Timer callback called\n");
|
||||
xSemaphoreGive(args->delete_start);
|
||||
xSemaphoreTake(args->delete_done, portMAX_DELAY);
|
||||
printf("Callback complete\n");
|
||||
xSemaphoreGive(args->test_done);
|
||||
}
|
||||
|
||||
TEST_CASE("Can delete timer from a separate task, triggered from callback", "[esp_timer]")
|
||||
{
|
||||
timer_delete_test_args_t args = {
|
||||
.delete_start = xSemaphoreCreateBinary(),
|
||||
.delete_done = xSemaphoreCreateBinary(),
|
||||
.test_done = xSemaphoreCreateBinary(),
|
||||
};
|
||||
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = &timer_delete_test_callback,
|
||||
.arg = &args
|
||||
};
|
||||
esp_timer_handle_t timer;
|
||||
TEST_ESP_OK(esp_timer_create(&timer_args, &timer));
|
||||
args.timer = timer;
|
||||
|
||||
xTaskCreate(timer_delete_task, "deleter", 4096, &args, 5, NULL);
|
||||
|
||||
esp_timer_start_once(timer, 100);
|
||||
TEST_ASSERT(xSemaphoreTake(args.test_done, pdMS_TO_TICKS(1000)));
|
||||
|
||||
vSemaphoreDelete(args.delete_done);
|
||||
vSemaphoreDelete(args.delete_start);
|
||||
vSemaphoreDelete(args.test_done);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_timer_impl_advance moves time base correctly", "[esp_timer]")
|
||||
{
|
||||
ref_clock_init();
|
||||
|
@@ -141,12 +141,14 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart from APP CPU",
|
||||
|
||||
static void do_int_wdt()
|
||||
{
|
||||
setup_values();
|
||||
portENTER_CRITICAL_NESTED();
|
||||
while(1);
|
||||
}
|
||||
|
||||
static void do_int_wdt_hw()
|
||||
{
|
||||
setup_values();
|
||||
XTOS_SET_INTLEVEL(XCHAL_NMILEVEL);
|
||||
while(1);
|
||||
}
|
||||
@@ -154,6 +156,7 @@ static void do_int_wdt_hw()
|
||||
static void check_reset_reason_int_wdt()
|
||||
{
|
||||
TEST_ASSERT_EQUAL(ESP_RST_INT_WDT, esp_reset_reason());
|
||||
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_INT_WDT after interrupt watchdog (panic)",
|
||||
@@ -194,6 +197,7 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_TASK_WDT after task watchdog",
|
||||
|
||||
static void do_rtc_wdt()
|
||||
{
|
||||
setup_values();
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
|
||||
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
|
||||
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM);
|
||||
@@ -205,6 +209,7 @@ static void do_rtc_wdt()
|
||||
static void check_reset_reason_any_wdt()
|
||||
{
|
||||
TEST_ASSERT_EQUAL(ESP_RST_WDT, esp_reset_reason());
|
||||
TEST_ASSERT_EQUAL_HEX32(CHECK_VALUE, s_rtc_noinit_val);
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_WDT after RTC watchdog",
|
||||
|
Reference in New Issue
Block a user