mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'feat/riscv-spiram-stack-pointer-update-before-restart_v6.0' into 'release/v6.0'
fix(esp_system): fix PSRAM stack crash in esp_restart_noos on RISC-V SPIRAM chips (v6.0) See merge request espressif/esp-idf!48067
This commit is contained in:
@@ -27,6 +27,10 @@
|
||||
#include "hal/modem_lpcon_ll.h"
|
||||
#endif
|
||||
#include "esp_private/cache_err_int.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
#define ALIGN_DOWN(val, align) ((val) & ~((align) - 1))
|
||||
extern int _bss_end;
|
||||
|
||||
#include "esp32c5/rom/cache.h"
|
||||
#include "esp32c5/rom/rtc.h"
|
||||
@@ -100,6 +104,24 @@ void esp_system_reset_modules_on_exit(void)
|
||||
uart_ll_sclk_enable(&UART0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR __attribute__((noinline, noreturn)) esp_restart_noos_inner(void)
|
||||
{
|
||||
// Disable cache
|
||||
Cache_Disable_Cache();
|
||||
|
||||
esp_system_reset_modules_on_exit();
|
||||
|
||||
// Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader.
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
#endif
|
||||
|
||||
// Reset PRO CPU
|
||||
esp_rom_software_reset_cpu(0);
|
||||
|
||||
ESP_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
/* "inner" restart function for after RTOS, interrupts & anything else on this
|
||||
* core are already stopped. Stalls other core, resets hardware,
|
||||
* triggers restart.
|
||||
@@ -132,25 +154,15 @@ void esp_restart_noos(void)
|
||||
wdt_hal_disable(&wdt1_context);
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
|
||||
// Disable cache
|
||||
Cache_Disable_Cache();
|
||||
|
||||
// Reset wifi/bluetooth/ethernet/sdio (bb/mac)
|
||||
// Moved to module internal
|
||||
// SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG,
|
||||
// SYSTEM_SDIO_RST | // SDIO_HINF_HINF_SDIO_RST?
|
||||
// SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | // TODO: IDF-5325 (ethernet)
|
||||
// REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0);
|
||||
|
||||
esp_system_reset_modules_on_exit();
|
||||
|
||||
// Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader.
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
#ifdef CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
|
||||
if (esp_ptr_external_ram(esp_cpu_get_sp())) {
|
||||
// If stack is in external RAM (CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM), switch SP to
|
||||
// internal RAM before disabling the cache to avoid a "Cache disabled but cached memory
|
||||
// region accessed" crash.
|
||||
uint32_t new_sp = ALIGN_DOWN((uint32_t)&_bss_end, 16);
|
||||
rv_utils_set_sp((void *)new_sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset PRO CPU
|
||||
esp_rom_software_reset_cpu(0);
|
||||
|
||||
ESP_INFINITE_LOOP();
|
||||
esp_restart_noos_inner();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "esp_private/cache_err_int.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
#define ALIGN_DOWN(val, align) ((val) & ~((align) - 1))
|
||||
extern int _bss_end;
|
||||
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#include "hal/modem_syscon_ll.h"
|
||||
@@ -99,6 +103,23 @@ void esp_system_reset_modules_on_exit(void)
|
||||
uart_ll_sclk_enable(&UART0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR __attribute__((noinline, noreturn)) esp_restart_noos_inner(void)
|
||||
{
|
||||
// Disable cache
|
||||
Cache_Disable_Cache();
|
||||
|
||||
esp_system_reset_modules_on_exit();
|
||||
|
||||
// Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader.
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
#endif
|
||||
|
||||
// Reset PRO CPU
|
||||
esp_rom_software_reset_cpu(0);
|
||||
ESP_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
/* "inner" restart function for after RTOS, interrupts & anything else on this
|
||||
* core are already stopped. Stalls other core, resets hardware,
|
||||
* triggers restart.
|
||||
@@ -131,25 +152,15 @@ void esp_restart_noos(void)
|
||||
wdt_hal_disable(&wdt1_context);
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
|
||||
// Disable cache
|
||||
Cache_Disable_Cache();
|
||||
|
||||
//TODO: [ESP32C61] IDF-9553, inherit from verify code
|
||||
// Reset wifi/bluetooth/ethernet/sdio (bb/mac)
|
||||
// Moved to module internal
|
||||
// SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG,
|
||||
// SYSTEM_SDIO_RST | // SDIO_HINF_HINF_SDIO_RST?
|
||||
// SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | // TODO: IDF-5325 (ethernet)
|
||||
// REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0);
|
||||
|
||||
esp_system_reset_modules_on_exit();
|
||||
|
||||
// Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader.
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
rtc_clk_cpu_set_to_default_config();
|
||||
#ifdef CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
|
||||
if (esp_ptr_external_ram(esp_cpu_get_sp())) {
|
||||
// If stack is in external RAM (CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM), switch SP to
|
||||
// internal RAM before disabling the cache to avoid a "Cache disabled but cached memory
|
||||
// region accessed" crash.
|
||||
uint32_t new_sp = ALIGN_DOWN((uint32_t)&_bss_end, 16);
|
||||
rv_utils_set_sp((void *)new_sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset PRO CPU
|
||||
esp_rom_software_reset_cpu(0);
|
||||
ESP_INFINITE_LOOP();
|
||||
esp_restart_noos_inner();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "soc/uart_reg.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
#define ALIGN_DOWN(val, align) ((val) & ~((align) - 1))
|
||||
extern int _bss_end;
|
||||
|
||||
#include "esp32h4/rom/cache.h"
|
||||
// TODO: IDF-11911 need refactor
|
||||
@@ -84,42 +88,9 @@ void esp_system_reset_modules_on_exit(void)
|
||||
uart_ll_sclk_enable(&UART0);
|
||||
}
|
||||
|
||||
/* "inner" restart function for after RTOS, interrupts & anything else on this
|
||||
* core are already stopped. Stalls other core, resets hardware,
|
||||
* triggers restart.
|
||||
*/
|
||||
void esp_restart_noos(void)
|
||||
static void IRAM_ATTR __attribute__((noinline, noreturn)) esp_restart_noos_inner(void)
|
||||
{
|
||||
// Disable interrupts
|
||||
rv_utils_intr_global_disable();
|
||||
// Enable RTC watchdog for 1 second
|
||||
wdt_hal_context_t rtc_wdt_ctx;
|
||||
wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
|
||||
uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
|
||||
//Enable flash boot mode so that flash booting after restart is protected by the RTC WDT.
|
||||
wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true);
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
|
||||
const uint32_t core_id = esp_cpu_get_core_id();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
const uint32_t other_core_id = (core_id == 0) ? 1 : 0;
|
||||
esp_cpu_reset(other_core_id);
|
||||
esp_cpu_stall(other_core_id);
|
||||
#endif
|
||||
|
||||
// Disable TG0/TG1 watchdogs
|
||||
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||
wdt_hal_write_protect_disable(&wdt0_context);
|
||||
wdt_hal_disable(&wdt0_context);
|
||||
wdt_hal_write_protect_enable(&wdt0_context);
|
||||
|
||||
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||
wdt_hal_write_protect_disable(&wdt1_context);
|
||||
wdt_hal_disable(&wdt1_context);
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
|
||||
// Disable cache
|
||||
Cache_Disable_Cache(CACHE_MAP_ALL);
|
||||
@@ -150,3 +121,57 @@ void esp_restart_noos(void)
|
||||
#endif
|
||||
ESP_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
/* "inner" restart function for after RTOS, interrupts & anything else on this
|
||||
* core are already stopped. Stalls other core, resets hardware,
|
||||
* triggers restart.
|
||||
*/
|
||||
void esp_restart_noos(void)
|
||||
{
|
||||
// Disable interrupts
|
||||
rv_utils_intr_global_disable();
|
||||
#if SOC_RTC_WDT_SUPPORTED
|
||||
// Enable RTC watchdog for 1 second
|
||||
wdt_hal_context_t rtc_wdt_ctx;
|
||||
wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
|
||||
uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
|
||||
//Enable flash boot mode so that flash booting after restart is protected by the RTC WDT.
|
||||
wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true);
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
#endif /* SOC_RTC_WDT_SUPPORTED */
|
||||
|
||||
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
const uint32_t core_id = esp_cpu_get_core_id();
|
||||
const uint32_t other_core_id = (core_id == 0) ? 1 : 0;
|
||||
esp_cpu_reset(other_core_id);
|
||||
esp_cpu_stall(other_core_id);
|
||||
#endif
|
||||
|
||||
#if SOC_WDT_SUPPORTED
|
||||
// Disable TG0/TG1 watchdogs
|
||||
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||
wdt_hal_write_protect_disable(&wdt0_context);
|
||||
wdt_hal_disable(&wdt0_context);
|
||||
wdt_hal_write_protect_enable(&wdt0_context);
|
||||
|
||||
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||
wdt_hal_write_protect_disable(&wdt1_context);
|
||||
wdt_hal_disable(&wdt1_context);
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
#endif /* SOC_WDT_SUPPORTED */
|
||||
|
||||
#ifdef CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
|
||||
if (esp_ptr_external_ram(esp_cpu_get_sp())) {
|
||||
// If stack is in external RAM (CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM), switch SP to
|
||||
// internal RAM before disabling the cache to avoid a "Cache disabled but cached memory
|
||||
// region accessed" crash.
|
||||
uint32_t new_sp = ALIGN_DOWN((uint32_t)&_bss_end, 16);
|
||||
rv_utils_set_sp((void *)new_sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_restart_noos_inner();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include "hal/dw_gdma_ll.h"
|
||||
#include "hal/dma2d_ll.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
#define ALIGN_DOWN(val, align) ((val) & ~((align) - 1))
|
||||
extern int _bss_end;
|
||||
|
||||
void esp_system_reset_modules_on_exit(void)
|
||||
{
|
||||
@@ -149,42 +153,9 @@ void esp_system_reset_modules_on_exit(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* "inner" restart function for after RTOS, interrupts & anything else on this
|
||||
* core are already stopped. Stalls other core, resets hardware,
|
||||
* triggers restart.
|
||||
*/
|
||||
void esp_restart_noos(void)
|
||||
static void IRAM_ATTR __attribute__((noinline, noreturn)) esp_restart_noos_inner(void)
|
||||
{
|
||||
// Disable interrupts
|
||||
rv_utils_intr_global_disable();
|
||||
// Enable RTC watchdog for 1 second
|
||||
wdt_hal_context_t rtc_wdt_ctx;
|
||||
wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
|
||||
uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
|
||||
//Enable flash boot mode so that flash booting after restart is protected by the RTC WDT.
|
||||
wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true);
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
|
||||
const uint32_t core_id = esp_cpu_get_core_id();
|
||||
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
const uint32_t other_core_id = (core_id == 0) ? 1 : 0;
|
||||
esp_cpu_reset(other_core_id);
|
||||
esp_cpu_stall(other_core_id);
|
||||
#endif
|
||||
|
||||
// Disable TG0/TG1 watchdogs
|
||||
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||
wdt_hal_write_protect_disable(&wdt0_context);
|
||||
wdt_hal_disable(&wdt0_context);
|
||||
wdt_hal_write_protect_enable(&wdt0_context);
|
||||
|
||||
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||
wdt_hal_write_protect_disable(&wdt1_context);
|
||||
wdt_hal_disable(&wdt1_context);
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
|
||||
// Disable cache
|
||||
#if CONFIG_SPIRAM
|
||||
@@ -230,3 +201,57 @@ void esp_restart_noos(void)
|
||||
|
||||
ESP_INFINITE_LOOP();
|
||||
}
|
||||
|
||||
/* "inner" restart function for after RTOS, interrupts & anything else on this
|
||||
* core are already stopped. Stalls other core, resets hardware,
|
||||
* triggers restart.
|
||||
*/
|
||||
void esp_restart_noos(void)
|
||||
{
|
||||
// Disable interrupts
|
||||
rv_utils_intr_global_disable();
|
||||
#if SOC_RTC_WDT_SUPPORTED
|
||||
// Enable RTC watchdog for 1 second
|
||||
wdt_hal_context_t rtc_wdt_ctx;
|
||||
wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false);
|
||||
uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_SYSTEM);
|
||||
wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE1, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC);
|
||||
//Enable flash boot mode so that flash booting after restart is protected by the RTC WDT.
|
||||
wdt_hal_set_flashboot_en(&rtc_wdt_ctx, true);
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
#endif /* SOC_RTC_WDT_SUPPORTED */
|
||||
|
||||
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
const uint32_t core_id = esp_cpu_get_core_id();
|
||||
const uint32_t other_core_id = (core_id == 0) ? 1 : 0;
|
||||
esp_cpu_reset(other_core_id);
|
||||
esp_cpu_stall(other_core_id);
|
||||
#endif
|
||||
|
||||
#if SOC_WDT_SUPPORTED
|
||||
// Disable TG0/TG1 watchdogs
|
||||
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
|
||||
wdt_hal_write_protect_disable(&wdt0_context);
|
||||
wdt_hal_disable(&wdt0_context);
|
||||
wdt_hal_write_protect_enable(&wdt0_context);
|
||||
|
||||
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
|
||||
wdt_hal_write_protect_disable(&wdt1_context);
|
||||
wdt_hal_disable(&wdt1_context);
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
#endif /* SOC_WDT_SUPPORTED */
|
||||
|
||||
#ifdef CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
|
||||
if (esp_ptr_external_ram(esp_cpu_get_sp())) {
|
||||
// If stack is in external RAM (CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM), switch SP to
|
||||
// internal RAM before disabling the cache to avoid a "Cache disabled but cached memory
|
||||
// region accessed" crash.
|
||||
uint32_t new_sp = ALIGN_DOWN((uint32_t)&_bss_end, 16);
|
||||
rv_utils_set_sp((void *)new_sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_restart_noos_inner();
|
||||
}
|
||||
|
||||
@@ -323,15 +323,31 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_BROWNOUT after brownout event",
|
||||
check_reset_reason_brownout);
|
||||
|
||||
#ifdef CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
#if (defined(CONFIG_IDF_TARGET_ARCH_XTENSA) && !defined(CONFIG_FREERTOS_UNICORE)) || defined(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||
#include "esp_memory_utils.h"
|
||||
#include "freertos/task.h"
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
#include "xt_instr_macros.h"
|
||||
#include "xtensa/config/xt_specreg.h"
|
||||
#endif
|
||||
|
||||
/* IDF's xTaskCreateStatic[PinnedToCore]() takes the stack size in BYTES
|
||||
* (not in words like upstream FreeRTOS). */
|
||||
static int size_stack = 1024 * 4;
|
||||
static StackType_t *start_addr_stack;
|
||||
|
||||
static int fibonacci(int n, void* func(void))
|
||||
static void func_do_exception(void)
|
||||
{
|
||||
*((volatile int *) 0x01) = 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
/* On Xtensa (windowed ABI), recursing forces the register window to wrap,
|
||||
* which triggers overflow/underflow exceptions that spill/fill registers
|
||||
* to/from the (SPIRAM-backed) task stack. This makes sure SP is genuinely
|
||||
* pointing into SPIRAM and that spilled frames live there too when func()
|
||||
* is finally called from deep inside the recursion. */
|
||||
static int fibonacci(int n, void *func(void))
|
||||
{
|
||||
int tmp1 = n, tmp2 = n;
|
||||
uint32_t base, start;
|
||||
@@ -349,6 +365,7 @@ static int fibonacci(int n, void* func(void))
|
||||
printf("fib = %d\n", (tmp1 - tmp2) + fib);
|
||||
return fib;
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
static void test_task(void *func)
|
||||
{
|
||||
@@ -358,30 +375,13 @@ static void test_task(void *func)
|
||||
} else {
|
||||
printf("restart_task: uses internal stack, addr_stack = %p\n", start_addr_stack);
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
fibonacci(35, func);
|
||||
}
|
||||
|
||||
static void func_do_exception(void)
|
||||
{
|
||||
*((int *) 0) = 0;
|
||||
}
|
||||
|
||||
static void init_restart_task(void)
|
||||
{
|
||||
StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task);
|
||||
static StaticTask_t task_buf;
|
||||
xTaskCreateStaticPinnedToCore(test_task, "test_task", size_stack, esp_restart, 5, stack_for_task, &task_buf, 1);
|
||||
while (1) { };
|
||||
}
|
||||
|
||||
static void init_task_do_exception(void)
|
||||
{
|
||||
StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task);
|
||||
static StaticTask_t task_buf;
|
||||
xTaskCreateStaticPinnedToCore(test_task, "test_task", size_stack, func_do_exception, 5, stack_for_task, &task_buf, 1);
|
||||
while (1) { };
|
||||
#else
|
||||
/* RISC-V has no register windows, so no need to recurse. Just invoke
|
||||
* the test function directly from this task (whose stack is in SPIRAM). */
|
||||
((void (*)(void))func)();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test1_finish(void)
|
||||
@@ -396,6 +396,38 @@ static void test2_finish(void)
|
||||
printf("test - OK\n");
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
#define CREATE_TEST_TASK(stack, buf, entry) \
|
||||
xTaskCreateStaticPinnedToCore(test_task, "test_task", size_stack, (entry), 5, (stack), (buf), 1)
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
#else // RISCV
|
||||
#define CREATE_TEST_TASK(stack, buf, entry) \
|
||||
xTaskCreateStatic(test_task, "test_task", size_stack, (entry), 5, (stack), (buf))
|
||||
#endif
|
||||
|
||||
#if defined(CREATE_TEST_TASK)
|
||||
|
||||
static void init_restart_task(void)
|
||||
{
|
||||
StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
TEST_ASSERT_NOT_NULL(stack_for_task);
|
||||
printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task);
|
||||
static StaticTask_t task_buf;
|
||||
CREATE_TEST_TASK(stack_for_task, &task_buf, esp_restart);
|
||||
while (1) { }
|
||||
}
|
||||
|
||||
static void init_task_do_exception(void)
|
||||
{
|
||||
StackType_t *stack_for_task = (StackType_t *) heap_caps_calloc(1, size_stack, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
TEST_ASSERT_NOT_NULL(stack_for_task);
|
||||
printf("init_task: current addr_stack = %p, stack_for_task = %p\n", esp_cpu_get_sp(), stack_for_task);
|
||||
static StaticTask_t task_buf;
|
||||
CREATE_TEST_TASK(stack_for_task, &task_buf, func_do_exception);
|
||||
while (1) { }
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart in a task with spiram stack", "[spiram_stack]",
|
||||
init_restart_task,
|
||||
test1_finish);
|
||||
@@ -404,8 +436,8 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after an exception in a ta
|
||||
init_task_do_exception,
|
||||
test2_finish);
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
#endif // CONFIG_FREERTOS_UNICORE
|
||||
#endif // CREATE_TEST_TASK
|
||||
#endif // (XTENSA && !UNICORE) || RISCV
|
||||
#endif // CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
|
||||
|
||||
/* Not tested here: ESP_RST_SDIO */
|
||||
|
||||
@@ -106,6 +106,17 @@ FORCE_INLINE_ATTR void *rv_utils_get_sp(void)
|
||||
return sp;
|
||||
}
|
||||
|
||||
/* Switch the stack pointer to a new address.
|
||||
*
|
||||
* Unlike the Xtensa SET_STACK, no window register management is required on
|
||||
* RISC-V; a plain register move is sufficient. The "memory" clobber prevents
|
||||
* the compiler from reordering any accesses across the switch.
|
||||
*/
|
||||
FORCE_INLINE_ATTR void rv_utils_set_sp(void *new_sp)
|
||||
{
|
||||
asm volatile ("mv sp, %0" :: "r"(new_sp) : "memory");
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_get_cycle_count(void)
|
||||
{
|
||||
#if !SOC_CPU_HAS_CSR_PC
|
||||
|
||||
Reference in New Issue
Block a user