Merge branch 'feature/switch_from_external_to_interanl_ram' into 'master'
esp32: Switch SPIRAM stack in esp_restart_noos() to internal stack Closes IDFGH-3086 See merge request espressif/esp-idf!8785
This commit is contained in:
commit
8b156a9095
4 changed files with 171 additions and 1 deletions
|
@ -88,6 +88,16 @@ void IRAM_ATTR esp_restart_noos(void)
|
||||||
uart_tx_wait_idle(1);
|
uart_tx_wait_idle(1);
|
||||||
uart_tx_wait_idle(2);
|
uart_tx_wait_idle(2);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||||
|
if (esp_ptr_external_ram(get_sp())) {
|
||||||
|
// If stack_addr is from External Memory (CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is used)
|
||||||
|
// then need to switch SP to Internal Memory otherwise
|
||||||
|
// we will get the "Cache disabled but cached memory region accessed" error after Cache_Read_Disable.
|
||||||
|
uint32_t new_sp = SOC_DRAM_LOW + (SOC_DRAM_HIGH - SOC_DRAM_LOW) / 2;
|
||||||
|
SET_STACK(new_sp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Disable cache
|
// Disable cache
|
||||||
Cache_Read_Disable(0);
|
Cache_Read_Disable(0);
|
||||||
Cache_Read_Disable(1);
|
Cache_Read_Disable(1);
|
||||||
|
|
|
@ -244,4 +244,89 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_BROWNOUT after brownout event",
|
||||||
check_reset_reason_brownout);
|
check_reset_reason_brownout);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||||
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
|
#include "xt_instr_macros.h"
|
||||||
|
#include "xtensa/config/specreg.h"
|
||||||
|
|
||||||
|
static int size_stack = 1024 * 3;
|
||||||
|
static StackType_t *start_addr_stack;
|
||||||
|
|
||||||
|
static int fibonacci(int n, void* func(void))
|
||||||
|
{
|
||||||
|
int tmp1 = n, tmp2 = n;
|
||||||
|
uint32_t base, start;
|
||||||
|
RSR(WINDOWBASE, base);
|
||||||
|
RSR(WINDOWSTART, start);
|
||||||
|
printf("WINDOWBASE = %-2d WINDOWSTART = 0x%x\n", base, start);
|
||||||
|
if (n <= 1) {
|
||||||
|
StackType_t *last_addr_stack = get_sp();
|
||||||
|
StackType_t *used_stack = (StackType_t *) (start_addr_stack - last_addr_stack);
|
||||||
|
printf("addr_stack = %p, used[%p]/all[0x%x] space in stack\n", last_addr_stack, used_stack, size_stack);
|
||||||
|
func();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
int fib = fibonacci(n - 1, func) + fibonacci(n - 2, func);
|
||||||
|
printf("fib = %d\n", (tmp1 - tmp2) + fib);
|
||||||
|
return fib;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_task(void *func)
|
||||||
|
{
|
||||||
|
start_addr_stack = get_sp();
|
||||||
|
if (esp_ptr_external_ram(start_addr_stack)) {
|
||||||
|
printf("restart_task: uses external stack, addr_stack = %p\n", start_addr_stack);
|
||||||
|
} else {
|
||||||
|
printf("restart_task: uses internal stack, addr_stack = %p\n", start_addr_stack);
|
||||||
|
}
|
||||||
|
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", 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", 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) { };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test1_finish(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_EQUAL(ESP_RST_SW, esp_reset_reason());
|
||||||
|
printf("test - OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test2_finish(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_EQUAL(ESP_RST_PANIC, esp_reset_reason());
|
||||||
|
printf("test - OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_SW after restart in a task with spiram stack", "[spiram_stack][reset=SW_CPU_RESET]",
|
||||||
|
init_restart_task,
|
||||||
|
test1_finish);
|
||||||
|
|
||||||
|
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_PANIC after an exception in a task with spiram stack", "[spiram_stack][reset=StoreProhibited,SW_CPU_RESET]",
|
||||||
|
init_task_do_exception,
|
||||||
|
test2_finish);
|
||||||
|
|
||||||
|
#endif // CONFIG_FREERTOS_UNICORE
|
||||||
|
#endif // CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
|
||||||
|
|
||||||
|
|
||||||
/* Not tested here: ESP_RST_SDIO */
|
/* Not tested here: ESP_RST_SDIO */
|
||||||
|
|
|
@ -22,3 +22,77 @@
|
||||||
|
|
||||||
#define WITLB(at, as) asm volatile ("witlb %0, %1; \n isync \n " : : "r" (at), "r" (as))
|
#define WITLB(at, as) asm volatile ("witlb %0, %1; \n isync \n " : : "r" (at), "r" (as))
|
||||||
#define WDTLB(at, as) asm volatile ("wdtlb %0, %1; \n dsync \n " : : "r" (at), "r" (as))
|
#define WDTLB(at, as) asm volatile ("wdtlb %0, %1; \n dsync \n " : : "r" (at), "r" (as))
|
||||||
|
|
||||||
|
/* The SET_STACK implements a setting a new stack pointer (sp or a1).
|
||||||
|
* to do this the need reset PS_WOE, reset WINDOWSTART, update SP, and return PS_WOE.
|
||||||
|
*
|
||||||
|
* Note: It has 2 implementations one for using in assembler files (*.S) and one for using in C.
|
||||||
|
*
|
||||||
|
* C code prototype for SET_STACK:
|
||||||
|
* uint32_t ps_reg;
|
||||||
|
* uint32_t w_base;
|
||||||
|
* RSR(PS, ps_reg);
|
||||||
|
* ps_reg &= ~(PS_WOE_MASK | PS_OWB_MASK | PS_CALLINC_MASK);
|
||||||
|
* WSR(PS, ps_reg);
|
||||||
|
*
|
||||||
|
* RSR(WINDOWBASE, w_base);
|
||||||
|
* WSR(WINDOWSTART, (1 << w_base));
|
||||||
|
*
|
||||||
|
* asm volatile ( "movi sp, "XTSTR( (SOC_DRAM_LOW + (SOC_DRAM_HIGH - SOC_DRAM_LOW) / 2) )"");
|
||||||
|
*
|
||||||
|
* RSR(PS, ps_reg);
|
||||||
|
* ps_reg |= (PS_WOE_MASK);
|
||||||
|
* WSR(PS, ps_reg);
|
||||||
|
*/
|
||||||
|
#ifdef __ASSEMBLER__
|
||||||
|
.macro SET_STACK new_sp tmp1 tmp2
|
||||||
|
rsr.ps \tmp1
|
||||||
|
movi \tmp2, ~(PS_WOE_MASK | PS_OWB_MASK | PS_CALLINC_MASK)
|
||||||
|
and \tmp1, \tmp1, \tmp2
|
||||||
|
wsr.ps \tmp1
|
||||||
|
rsync
|
||||||
|
|
||||||
|
rsr.windowbase \tmp1
|
||||||
|
ssl \tmp1
|
||||||
|
movi \tmp1, 1
|
||||||
|
sll \tmp1, \tmp1
|
||||||
|
wsr.windowstart \tmp1
|
||||||
|
rsync
|
||||||
|
|
||||||
|
mov sp, \new_sp
|
||||||
|
|
||||||
|
rsr.ps \tmp1
|
||||||
|
movi \tmp2, (PS_WOE)
|
||||||
|
or \tmp1, \tmp1, \tmp2
|
||||||
|
wsr.ps \tmp1
|
||||||
|
rsync
|
||||||
|
.endm
|
||||||
|
#else
|
||||||
|
#define SET_STACK(new_sp) \
|
||||||
|
do { \
|
||||||
|
uint32_t tmp1 = 0, tmp2 = 0; \
|
||||||
|
asm volatile ( \
|
||||||
|
"rsr.ps %1 \n"\
|
||||||
|
"movi %2, ~" XTSTR( PS_WOE_MASK | PS_OWB_MASK | PS_CALLINC_MASK ) " \n"\
|
||||||
|
"and %1, %1, %2 \n"\
|
||||||
|
"wsr.ps %1 \n"\
|
||||||
|
"rsync \n"\
|
||||||
|
" \n"\
|
||||||
|
"rsr.windowbase %1 \n"\
|
||||||
|
"ssl %1 \n"\
|
||||||
|
"movi %1, 1 \n"\
|
||||||
|
"sll %1, %1 \n"\
|
||||||
|
"wsr.windowstart %1 \n"\
|
||||||
|
"rsync \n"\
|
||||||
|
" \n"\
|
||||||
|
"mov sp, %0 \n"\
|
||||||
|
"rsr.ps %1 \n"\
|
||||||
|
" \n"\
|
||||||
|
"movi %2, " XTSTR( PS_WOE_MASK ) "\n"\
|
||||||
|
" \n"\
|
||||||
|
"or %1, %1, %2 \n"\
|
||||||
|
"wsr.ps %1 \n"\
|
||||||
|
"rsync \n"\
|
||||||
|
: "+r"(new_sp), "+r"(tmp1), "+r"(tmp2)); \
|
||||||
|
} while (0);
|
||||||
|
#endif // __ASSEMBLER__
|
||||||
|
|
|
@ -4,3 +4,4 @@ CONFIG_ESP32_SPIRAM_SUPPORT=y
|
||||||
CONFIG_ESP_INT_WDT_TIMEOUT_MS=800
|
CONFIG_ESP_INT_WDT_TIMEOUT_MS=800
|
||||||
CONFIG_SPIRAM_OCCUPY_NO_HOST=y
|
CONFIG_SPIRAM_OCCUPY_NO_HOST=y
|
||||||
CONFIG_ESP32_WIFI_RX_IRAM_OPT=n
|
CONFIG_ESP32_WIFI_RX_IRAM_OPT=n
|
||||||
|
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
|
||||||
|
|
Loading…
Reference in a new issue