Merge branch 'master' into feature/esp32s2beta_update

This commit is contained in:
Angus Gratton
2019-08-08 13:44:24 +10:00
committed by Angus Gratton
2414 changed files with 160787 additions and 45783 deletions

View File

@@ -1,75 +1,78 @@
# TODO esp32s2beta: Support uncommenting this
# require_idf_targets(esp32)
if(BOOTLOADER_BUILD AND CONFIG_IDF_TARGET_ESP32)
if(BOOTLOADER_BUILD)
# For bootloader, all we need from esp32 is headers
set(COMPONENT_ADD_INCLUDEDIRS include)
register_component()
target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld")
elseif(CONFIG_IDF_TARGET_ESP32)
idf_component_register(INCLUDE_DIRS include)
target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.peripherals.ld")
else()
# Regular app build
set(srcs
"brownout.c"
"cache_err_int.c"
"cache_sram_mmu.c"
"clk.c"
"cpu_start.c"
"crosscore_int.c"
"dport_access.c"
"dport_panic_highint_hdl.S"
"esp_adapter.c"
"esp_timer_esp32.c"
"esp_himem.c"
"hw_random.c"
"int_wdt.c"
"intr_alloc.c"
"panic.c"
"pm_esp32.c"
"pm_trace.c"
"reset_reason.c"
"sleep_modes.c"
"spiram.c"
"spiram_psram.c"
"system_api.c"
"task_wdt.c")
set(include_dirs "include")
set(COMPONENT_SRCS "brownout.c"
"cache_err_int.c"
"cache_sram_mmu.c"
"clk.c"
"cpu_start.c"
"crosscore_int.c"
"dport_access.c"
"dport_panic_highint_hdl.S"
"esp_adapter.c"
"esp_timer_esp32.c"
"esp_himem.c"
"hw_random.c"
"int_wdt.c"
"intr_alloc.c"
"panic.c"
"pm_esp32.c"
"pm_trace.c"
"reset_reason.c"
"sleep_modes.c"
"spiram.c"
"spiram_psram.c"
"system_api.c"
"task_wdt.c")
set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_REQUIRES app_update driver esp_event efuse pthread soc) #unfortunately rom/uart uses SOC registers directly
set(requires driver esp_event efuse soc) #unfortunately rom/uart uses SOC registers directly
# driver is a public requirement because esp_sleep.h uses gpio_num_t & touch_pad_t
# app_update is added here because cpu_start.c uses esp_ota_get_app_description() function.
set(COMPONENT_PRIV_REQUIRES
app_trace app_update bootloader_support log mbedtls nvs_flash
smartconfig_ack spi_flash vfs wpa_supplicant espcoredump esp_common esp_wifi)
set(priv_requires app_trace app_update bootloader_support log mbedtls nvs_flash pthread
spi_flash vfs wpa_supplicant espcoredump esp_common esp_wifi)
set(fragments linker.lf ld/esp32_fragments.lf)
set(COMPONENT_ADD_LDFRAGMENTS linker.lf ld/esp32_fragments.lf)
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}"
LDFRAGMENTS "${fragments}"
REQUIRES "${requires}"
PRIV_REQUIRES "${priv_requires}"
REQUIRED_IDF_TARGETS esp32)
register_component()
target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
# Rely on user code to define app_main
target_link_libraries(${COMPONENT_LIB} "-u app_main")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u app_main")
if(CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY)
# This has to be linked before esp32.project.ld
target_linker_script(${COMPONENT_LIB} "ld/esp32.extram.bss.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.extram.bss.ld")
endif()
# Process the template file through the linker script generation mechanism, and use the output for linking the
# final binary
target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" PROCESS)
target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in"
PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/esp32.project.ld")
target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld")
target_link_libraries(${COMPONENT_LIB} gcc)
target_link_libraries(${COMPONENT_LIB} "-u call_user_start_cpu0")
target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.peripherals.ld")
target_link_libraries(${COMPONENT_LIB} PUBLIC gcc)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u call_user_start_cpu0")
#ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the
#linker will ignore panic_highint_hdl.S as it has no other files depending on any
#symbols in it.
target_link_libraries(${COMPONENT_LIB} "-u ld_include_panic_highint_hdl")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_panic_highint_hdl")
idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER)
get_filename_component(config_dir ${sdkconfig_header} DIRECTORY)
idf_build_get_property(config_dir CONFIG_DIR)
# Preprocess esp32.ld linker script to include configuration, becomes esp32_out.ld
set(LD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ld)
add_custom_command(
@@ -94,6 +97,6 @@ elseif(CONFIG_IDF_TARGET_ESP32)
# To handle some corner cases, the same flag is set in project_include.cmake
target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue)
# also, make sure we link with this option so correct toolchain libs are pulled in
target_link_libraries(${COMPONENT_LIB} -mfix-esp32-psram-cache-issue)
target_link_libraries(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue)
endif()
endif()

View File

@@ -656,6 +656,13 @@ menu "ESP32-specific"
Please note that the actual length will be reduced by BT_RESERVE_DRAM if Bluetooth
controller is enabled.
config ESP32_DPORT_DIS_INTERRUPT_LVL
int "Disable the interrupt level for the DPORT workarounds"
default 5
help
To prevent interrupting DPORT workarounds,
need to disable interrupt with a maximum used level in the system.
endmenu # ESP32-Specific
menu "Power Management"

View File

@@ -2,6 +2,7 @@
ifdef CONFIG_SPIRAM_CACHE_WORKAROUND
CFLAGS+=-mfix-esp32-psram-cache-issue
CXXFLAGS+=-mfix-esp32-psram-cache-issue
LDFLAGS+=-mfix-esp32-psram-cache-issue
endif
# Enable dynamic esp_timer overflow value if building unit tests

View File

@@ -43,6 +43,7 @@
#include "sdkconfig.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_flash.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_spi_flash.h"
@@ -58,11 +59,10 @@
#include "esp_phy_init.h"
#include "esp32/cache_err_int.h"
#include "esp_coexist_internal.h"
#include "esp_debug_helpers.h"
#include "esp_core_dump.h"
#include "esp_app_trace.h"
#include "esp_private/dbg_stubs.h"
#include "esp_efuse.h"
#include "esp_flash_encrypt.h"
#include "esp32/spiram.h"
#include "esp_clk_internal.h"
#include "esp_timer.h"
@@ -70,6 +70,8 @@
#include "esp_private/pm_impl.h"
#include "trax.h"
#include "esp_ota_ops.h"
#include "esp_efuse.h"
#include "bootloader_flash_config.h"
#define STRINGIFY(s) STRINGIFY2(s)
#define STRINGIFY2(s) #s
@@ -202,6 +204,20 @@ void IRAM_ATTR call_start_cpu0()
abort();
}
ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1);
esp_flash_enc_mode_t mode;
mode = esp_get_flash_encryption_mode();
if (mode == ESP_FLASH_ENC_MODE_DEVELOPMENT) {
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
ESP_EARLY_LOGE(TAG, "Flash encryption settings error: mode should be RELEASE but is actually DEVELOPMENT");
ESP_EARLY_LOGE(TAG, "Mismatch found in security options in menuconfig and efuse settings");
#else
ESP_EARLY_LOGW(TAG, "Flash encryption mode is DEVELOPMENT");
#endif
} else if (mode == ESP_FLASH_ENC_MODE_RELEASE) {
ESP_EARLY_LOGI(TAG, "Flash encryption mode is RELEASE");
}
//Flush and enable icache for APP CPU
Cache_Flush(1);
Cache_Read_Enable(1);
@@ -388,6 +404,10 @@ void start_cpu0_default(void)
spi_flash_init();
/* init default OS-aware flash access critical section */
spi_flash_guard_set(&g_flash_guard_default_ops);
esp_flash_app_init();
esp_err_t flash_ret = esp_flash_init_default_chip();
assert(flash_ret == ESP_OK);
#ifdef CONFIG_PM_ENABLE
esp_pm_impl_init();
#ifdef CONFIG_PM_DFS_INIT_AUTO
@@ -413,6 +433,17 @@ void start_cpu0_default(void)
esp_coex_adapter_register(&g_coex_adapter_funcs);
#endif
bootloader_flash_update_id();
#if !CONFIG_SPIRAM_BOOT_INIT // If psram is uninitialized, we need to improve some flash configuration.
esp_image_header_t fhdr;
const esp_partition_t *partition = esp_ota_get_running_partition();
spi_flash_read(partition->address, &fhdr, sizeof(esp_image_header_t));
bootloader_flash_clock_config(&fhdr);
bootloader_flash_gpio_config(&fhdr);
bootloader_flash_dummy_config(&fhdr);
bootloader_flash_cs_timing_config();
#endif
portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
ESP_TASK_MAIN_STACK, NULL,
ESP_TASK_MAIN_PRIO, NULL, 0);

View File

@@ -256,7 +256,7 @@ uint32_t IRAM_ATTR esp_dport_access_reg_read(uint32_t reg)
unsigned int intLvl;
__asm__ __volatile__ (\
"movi %[APB], "XTSTR(0x3ff40078)"\n"\
"rsil %[LVL], "XTSTR(3)"\n"\
"rsil %[LVL], "XTSTR(CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL)"\n"\
"l32i %[APB], %[APB], 0\n"\
"l32i %[REG], %[REG], 0\n"\
"wsr %[LVL], "XTSTR(PS)"\n"\

View File

@@ -31,9 +31,10 @@ Interrupt , a high-priority interrupt, is used for several things:
*/
#define L4_INTR_STACK_SIZE 8
#define L4_INTR_STACK_SIZE 12
#define L4_INTR_A2_OFFSET 0
#define L4_INTR_A3_OFFSET 4
#define L4_INTR_A4_OFFSET 8
.data
_l4_intr_stack:
.space L4_INTR_STACK_SIZE
@@ -145,10 +146,11 @@ xt_highint4:
movi a0, (1<<ETS_DPORT_INUM)
wsr a0, INTCLEAR
/* Save A2, A3 so we can use those registers */
/* Save A2, A3, A4 so we can use those registers */
movi a0, _l4_intr_stack
s32i a2, a0, L4_INTR_A2_OFFSET
s32i a3, a0, L4_INTR_A3_OFFSET
s32i a4, a0, L4_INTR_A4_OFFSET
/* handle dport interrupt */
/* get CORE_ID */
@@ -168,6 +170,7 @@ xt_highint4:
s32i a2, a0, 0 /* clear intr */
movi a0, 1 /* other cpu id */
3:
rsil a4, CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL /* disable nested iterrupt */
/* set and wait flag */
movi a2, dport_access_start
addx4 a2, a0, a2
@@ -180,10 +183,12 @@ xt_highint4:
l32i a3, a2, 0
beqz a3, .check_dport_access_end
wsr a4, PS /* restore iterrupt level */
/* Done. Restore registers and return. */
movi a0, _l4_intr_stack
l32i a2, a0, L4_INTR_A2_OFFSET
l32i a3, a0, L4_INTR_A3_OFFSET
l32i a4, a0, L4_INTR_A4_OFFSET
rsync /* ensure register restored */
rsr a0, EXCSAVE_4 /* restore a0 */

View File

@@ -33,6 +33,7 @@
#include "esp_intr_alloc.h"
#include "esp_attr.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_heap_caps.h"
#include "esp_private/wifi_os_adapter.h"
#include "esp_private/wifi.h"
@@ -46,7 +47,6 @@
#include "nvs.h"
#include "os.h"
#include "esp_smartconfig.h"
#include "smartconfig_ack.h"
#include "esp_coexist_internal.h"
#include "esp_coexist_adapter.h"
@@ -373,6 +373,15 @@ static int32_t task_get_max_priority_wrapper(void)
return (int32_t)(configMAX_PRIORITIES);
}
static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id, void* event_data, size_t event_data_size, uint32_t ticks_to_wait)
{
if (ticks_to_wait == OSI_FUNCS_TIME_BLOCKING) {
return (int32_t)esp_event_post(event_base, event_id, event_data, event_data_size, portMAX_DELAY);
} else {
return (int32_t)esp_event_post(event_base, event_id, event_data, event_data_size, ticks_to_wait);
}
}
static void IRAM_ATTR timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat)
{
ets_timer_arm(timer, tmout, repeat);
@@ -427,11 +436,6 @@ static void * IRAM_ATTR zalloc_internal_wrapper(size_t size)
return ptr;
}
static void sc_ack_send_wrapper(void *param)
{
return sc_ack_send((sc_ack_t *)param);
}
static uint32_t coex_status_get_wrapper(void)
{
#if CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE
@@ -544,6 +548,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._task_get_max_priority = task_get_max_priority_wrapper,
._malloc = malloc,
._free = free,
._event_post = esp_event_post_wrapper,
._get_free_heap_size = esp_get_free_heap_size,
._rand = esp_random,
._dport_access_stall_other_cpu_start_wrap = esp_dport_access_stall_other_cpu_start_wrap,
@@ -590,8 +595,6 @@ wifi_osi_funcs_t g_wifi_osi_funcs = {
._modem_sleep_exit = esp_modem_sleep_exit,
._modem_sleep_register = esp_modem_sleep_register,
._modem_sleep_deregister = esp_modem_sleep_deregister,
._sc_ack_send = sc_ack_send_wrapper,
._sc_ack_send_stop = sc_ack_send_stop,
._coex_status_get = coex_status_get_wrapper,
._coex_wifi_request = coex_wifi_request_wrapper,
._coex_wifi_release = coex_wifi_release_wrapper,

View File

@@ -41,7 +41,7 @@ void esp_dport_access_int_abort(void);
#else
#define DPORT_STALL_OTHER_CPU_START() esp_dport_access_stall_other_cpu_start()
#define DPORT_STALL_OTHER_CPU_END() esp_dport_access_stall_other_cpu_end()
#define DPORT_INTERRUPT_DISABLE() unsigned int intLvl = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL)
#define DPORT_INTERRUPT_DISABLE() unsigned int intLvl = XTOS_SET_INTLEVEL(CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL)
#define DPORT_INTERRUPT_RESTORE() XTOS_RESTORE_JUST_INTLEVEL(intLvl)
#endif

View File

@@ -26,6 +26,9 @@ PROVIDE ( SPI3 = 0x3ff65000 );
PROVIDE ( SYSCON = 0x3ff66000 );
PROVIDE ( I2C1 = 0x3ff67000 );
PROVIDE ( SDMMC = 0x3ff68000 );
PROVIDE ( EMAC_DMA = 0x3ff69000 );
PROVIDE ( EMAC_EXT = 0x3ff69800 );
PROVIDE ( EMAC_MAC = 0x3ff6A000 );
PROVIDE ( CAN = 0x3ff6B000 );
PROVIDE ( MCPWM1 = 0x3ff6C000 );
PROVIDE ( I2S1 = 0x3ff6D000 );

View File

@@ -15,9 +15,9 @@ SECTIONS
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
_rtc_text_end = ABSOLUTE(.);
} > rtc_iram_seg
/*
This section is required to skip rtc.text area because rtc_iram_seg and
This section is required to skip rtc.text area because rtc_iram_seg and
rtc_data_seg are reflect the same address space on different buses.
*/
.rtc.dummy :
@@ -28,8 +28,8 @@ SECTIONS
_rtc_dummy_end = ABSOLUTE(.);
} > rtc_data_seg
/* This section located in RTC FAST Memory area.
It holds data marked with RTC_FAST_ATTR attribute.
/* This section located in RTC FAST Memory area.
It holds data marked with RTC_FAST_ATTR attribute.
See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
@@ -45,7 +45,7 @@ SECTIONS
data/rodata, including from any source file
named rtc_wake_stub*.c and the data marked with
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
The memory location of the data is dependent on
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
*/
.rtc.data :
@@ -70,11 +70,11 @@ SECTIONS
_rtc_bss_end = ABSOLUTE(.);
} > rtc_data_location
/* This section holds data that should not be initialized at power up
/* This section holds data that should not be initialized at power up
and will be retained during deep sleep.
User data marked with RTC_NOINIT_ATTR will be placed
into this section. See the file "esp_attr.h" for more information.
The memory location of the data is dependent on
into this section. See the file "esp_attr.h" for more information.
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
*/
.rtc_noinit (NOLOAD):
@@ -86,8 +86,8 @@ SECTIONS
_rtc_noinit_end = ABSOLUTE(.);
} > rtc_data_location
/* This section located in RTC SLOW Memory area.
It holds data marked with RTC_SLOW_ATTR attribute.
/* This section located in RTC SLOW Memory area.
It holds data marked with RTC_SLOW_ATTR attribute.
See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
@@ -100,17 +100,17 @@ SECTIONS
} > rtc_slow_seg
/* Get size of rtc slow data based on rtc_data_location alias */
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
@@ -178,6 +178,10 @@ SECTIONS
*libbtdm_app.a:(.data .data.*)
. = ALIGN (4);
_btdm_data_end = ABSOLUTE(.);
_nimble_data_start = ABSOLUTE(.);
*libnimble.a:(.data .data.*)
. = ALIGN (4);
_nimble_data_end = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
@@ -203,7 +207,7 @@ SECTIONS
{
. = ALIGN(4);
_noinit_start = ABSOLUTE(.);
*(.noinit .noinit.*)
*(.noinit .noinit.*)
. = ALIGN(4) ;
_noinit_end = ABSOLUTE(.);
} > dram0_0_seg
@@ -222,6 +226,10 @@ SECTIONS
*libbtdm_app.a:(.bss .bss.* COMMON)
. = ALIGN (4);
_btdm_bss_end = ABSOLUTE(.);
_nimble_bss_start = ABSOLUTE(.);
*libnimble.a:(.bss .bss.* COMMON)
. = ALIGN (4);
_nimble_bss_end = ABSOLUTE(.);
mapping[dram0_bss]
@@ -243,7 +251,7 @@ SECTIONS
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
.flash.rodata :
{
_rodata_start = ABSOLUTE(.);

View File

@@ -30,6 +30,7 @@
#include "soc/cpu.h"
#include "soc/rtc.h"
#include "soc/rtc_wdt.h"
#include "soc/soc_memory_layout.h"
#include "esp_private/gdbstub.h"
#include "esp_debug_helpers.h"
@@ -446,33 +447,36 @@ static void esp_panic_dig_reset()
static void putEntry(uint32_t pc, uint32_t sp)
{
if (pc & 0x80000000) {
pc = (pc & 0x3fffffff) | 0x40000000;
}
panicPutStr(" 0x");
panicPutHex(pc);
panicPutStr(":0x");
panicPutHex(sp);
}
static void doBacktrace(XtExcFrame *frame)
static void doBacktrace(XtExcFrame *exc_frame, int depth)
{
uint32_t i = 0, pc = frame->pc, sp = frame->a1;
//Initialize stk_frame with first frame of stack
esp_backtrace_frame_t stk_frame = {.pc = exc_frame->pc, .sp = exc_frame->a1, .next_pc = exc_frame->a0};
panicPutStr("\r\nBacktrace:");
/* Do not check sanity on first entry, PC could be smashed. */
putEntry(pc, sp);
pc = frame->a0;
while (i++ < 100) {
uint32_t psp = sp;
if (!esp_stack_ptr_is_sane(sp) || i++ > 100) {
break;
}
sp = *((uint32_t *) (sp - 0x10 + 4));
putEntry(pc - 3, sp); // stack frame addresses are return addresses, so subtract 3 to get the CALL address
pc = *((uint32_t *) (psp - 0x10));
if (pc < 0x40000000) {
break;
putEntry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
//Check if first frame is valid
bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) &&
esp_ptr_executable((void*)esp_cpu_process_stack_pc(stk_frame.pc))) ?
false : true;
uint32_t i = ((depth <= 0) ? INT32_MAX : depth) - 1; //Account for stack frame that's already printed
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get next stack frame
corrupted = true;
}
putEntry(esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
}
//Print backtrace termination marker
if (corrupted) {
panicPutStr(" |<-CORRUPTED");
} else if (stk_frame.next_pc != 0) { //Backtrace continues
panicPutStr(" |<-CONTINUES");
}
panicPutStr("\r\n");
}
@@ -549,7 +553,7 @@ static void commonErrorHandler_dump(XtExcFrame *frame, int core_id)
panicPutStr("\r\n");
/* With windowed ABI backtracing is easy, let's do it. */
doBacktrace(frame);
doBacktrace(frame, 100);
panicPutStr("\r\n");
}

View File

@@ -31,6 +31,7 @@
#include "esp32/rom/efuse.h"
#include "soc/dport_reg.h"
#include "soc/efuse_periph.h"
#include "soc/spi_caps.h"
#include "driver/gpio.h"
#include "driver/spi_common.h"
#include "driver/periph_ctrl.h"
@@ -94,8 +95,6 @@ typedef enum {
// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
// hardcode the flash pins as well, making this code incompatible with either a setup
// that has the flash on non-standard pins or ESP32s with built-in flash.
#define FLASH_CLK_IO 6
#define FLASH_CS_IO 11
#define PSRAM_SPIQ_SD0_IO 7
#define PSRAM_SPID_SD1_IO 8
#define PSRAM_SPIWP_SD3_IO 10
@@ -134,8 +133,8 @@ typedef struct {
#define PSRAM_INTERNAL_IO_28 28
#define PSRAM_INTERNAL_IO_29 29
#define PSRAM_IO_MATRIX_DUMMY_40M 1
#define PSRAM_IO_MATRIX_DUMMY_80M 2
#define PSRAM_IO_MATRIX_DUMMY_40M ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M
#define PSRAM_IO_MATRIX_DUMMY_80M ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M
#define _SPI_CACHE_PORT 0
#define _SPI_FLASH_PORT 1
@@ -505,9 +504,11 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_mode_t
{
int spi_cache_dummy = 0;
uint32_t rd_mode_reg = READ_PERI_REG(SPI_CTRL_REG(0));
if (rd_mode_reg & (SPI_FREAD_QIO_M | SPI_FREAD_DIO_M)) {
if (rd_mode_reg & SPI_FREAD_QIO_M) {
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
} else if (rd_mode_reg & (SPI_FREAD_QUAD_M | SPI_FREAD_DUAL_M)) {
} else if (rd_mode_reg & SPI_FREAD_DIO_M) {
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
} else if (rd_mode_reg & (SPI_FREAD_QUAD_M | SPI_FREAD_DUAL_M)) {
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
} else {
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
@@ -566,7 +567,7 @@ static void IRAM_ATTR psram_gpio_config(psram_io_t *psram_io, psram_cache_mode_t
gpio_matrix_in(psram_io->psram_spihd_sd2_io, SPIHD_IN_IDX, 0);
//select pin function gpio
if ((psram_io->flash_clk_io == FLASH_CLK_IO) && (psram_io->flash_clk_io != psram_io->psram_clk_io)) {
if ((psram_io->flash_clk_io == SPI_IOMUX_PIN_NUM_CLK) && (psram_io->flash_clk_io != psram_io->psram_clk_io)) {
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io->flash_clk_io], FUNC_SD_CLK_SPICLK);
} else {
@@ -647,8 +648,8 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
const uint32_t spiconfig = ets_efuse_get_spiconfig();
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
psram_io.flash_clk_io = FLASH_CLK_IO;
psram_io.flash_cs_io = FLASH_CS_IO;
psram_io.flash_clk_io = SPI_IOMUX_PIN_NUM_CLK;
psram_io.flash_cs_io = SPI_IOMUX_PIN_NUM_CS;
psram_io.psram_spiq_sd0_io = PSRAM_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PSRAM_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PSRAM_SPIWP_SD3_IO;

View File

@@ -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")

View File

@@ -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 := .

View File

@@ -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

View 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

View File

@@ -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();

View File

@@ -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",