diff --git a/components/esp32s2/include/esp_spiram.h b/components/esp32s2/include/esp_spiram.h index 414cc310a..16212e540 100644 --- a/components/esp32s2/include/esp_spiram.h +++ b/components/esp32s2/include/esp_spiram.h @@ -78,18 +78,6 @@ size_t esp_spiram_get_size(void); void esp_spiram_writeback_cache(void); - -/** - * @brief Reserve a pool of internal memory for specific DMA/internal allocations - * - * @param size Size of reserved pool in bytes - * - * @return - * - ESP_OK on success - * - ESP_ERR_NO_MEM when no memory available for pool - */ -esp_err_t esp_spiram_reserve_dma_pool(size_t size); - #ifdef __cplusplus } #endif diff --git a/components/esp_system/private_include/startup_internal.h b/components/esp_system/include/esp_private/startup_internal.h similarity index 97% rename from components/esp_system/private_include/startup_internal.h rename to components/esp_system/include/esp_private/startup_internal.h index 9976b189e..8a12ee367 100644 --- a/components/esp_system/private_include/startup_internal.h +++ b/components/esp_system/include/esp_private/startup_internal.h @@ -21,6 +21,10 @@ #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif + extern bool g_spiram_ok; // [refactor-todo] better way to communicate this from port layer to common startup code // Port layer defines the entry point. It then transfer control to a `sys_startup_fn_t`, stored in this @@ -60,3 +64,7 @@ static __attribute__((used)) esp_system_init_fn_t _SECTION_ATTR_IMPL(".esp_syste static __attribute__((used)) __VA_ARGS__ void __esp_system_init_fn_##f(void) // [refactor-todo] this can be made public API if we allow components to declare init functions, // instead of calling them explicitly +#ifdef __cplusplus +} +#endif + diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 9c50c0e84..663a29952 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -66,7 +66,7 @@ #endif // CONFIG_APP_BUILD_TYPE_ELF_RAM #endif -#include "startup_internal.h" +#include "esp_private/startup_internal.h" extern int _bss_start; extern int _bss_end; @@ -349,10 +349,10 @@ void IRAM_ATTR call_start_cpu0(void) #if CONFIG_IDF_TARGET_ESP32 #if CONFIG_ESP32_TRAX_TWOBANKS trax_enable(TRAX_ENA_PRO_APP); - #else + #else trax_enable(TRAX_ENA_PRO); #endif -#elif CONFIG_IDF_TARGET_ESP32S2 +#elif CONFIG_IDF_TARGET_ESP32S2 trax_enable(TRAX_ENA_PRO); #endif trax_start_trace(TRAX_DOWNCOUNT_WORDS); @@ -362,11 +362,12 @@ void IRAM_ATTR call_start_cpu0(void) esp_perip_clk_init(); intr_matrix_clear(); -#if CONFIG_ESP32_BROWNOUT_DET || CONFIG_ESP32S2_BROWNOUT_DET - esp_brownout_init(); +#ifndef CONFIG_ESP_CONSOLE_UART_NONE + const int uart_clk_freq = APB_CLK_FREQ; + uart_div_modify(CONFIG_ESP_CONSOLE_UART_NUM, (uart_clk_freq << 4) / CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif - rtc_gpio_force_hold_dis_all(); + rtcio_hal_unhold_all(); esp_cache_err_int_init(); @@ -381,7 +382,7 @@ void IRAM_ATTR call_start_cpu0(void) #endif bootloader_flash_update_id(); -#if CONFIG_IDF_TARGET_ESP32 +#if CONFIG_IDF_TARGET_ESP32 #if !CONFIG_SPIRAM_BOOT_INIT // Read the application binary image header. This will also decrypt the header if the image is encrypted. esp_image_header_t fhdr = {0}; diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index f9bebeb48..0c036ef43 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -24,8 +24,8 @@ #include "sdkconfig.h" -#include "soc/rtc_wdt.h" #include "soc/soc_caps.h" +#include "hal/wdt_hal.h" #include "esp_system.h" #include "esp_log.h" @@ -39,7 +39,7 @@ #include "esp_flash_encrypt.h" /***********************************************/ -// Headers for other components init functions +// Headers for other components init functions #include "nvs_flash.h" #include "esp_phy_init.h" #include "esp_coexist_internal.h" @@ -48,6 +48,7 @@ #include "esp_private/dbg_stubs.h" #include "esp_flash_encrypt.h" #include "esp_pm.h" +#include "esp_private/pm_impl.h" #include "esp_pthread.h" // [refactor-todo] make this file completely target-independent @@ -62,7 +63,7 @@ #endif /***********************************************/ -#include "startup_internal.h" +#include "esp_private/startup_internal.h" // Ensure that system configuration matches the underlying number of cores. // This should enable us to avoid checking for both everytime. @@ -70,6 +71,9 @@ #error "System has been configured to run on multiple cores, but target SoC only has a single core." #endif +#define STRINGIFY(s) STRINGIFY2(s) +#define STRINGIFY2(s) #s + // App entry point for core 0 extern void app_main(void); @@ -167,7 +171,6 @@ static void IRAM_ATTR do_core_init(void) app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may fail initializing it properly. */ heap_caps_init(); - esp_setup_syscall_table(); if (g_spiram_ok) { @@ -184,27 +187,15 @@ static void IRAM_ATTR do_core_init(void) } #if CONFIG_ESP32_BROWNOUT_DET || CONFIG_ESP32S2_BROWNOUT_DET - // [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) -> + // [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) -> // malloc (newlib) -> heap_caps_malloc (heap), so heap must be at least initialized esp_brownout_init(); #endif - // Now we have startup stack RAM available for heap, enable any DMA pool memory -#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL - if (g_spiram_ok) { - esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL); - if (r != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r); - abort(); - } - } -#endif - - esp_reent_init(_GLOBAL_REENT); - -#ifndef CONFIG_ESP_CONSOLE_UART_NONE - const int uart_clk_freq = APB_CLK_FREQ; - uart_div_modify(CONFIG_ESP_CONSOLE_UART_NUM, (uart_clk_freq << 4) / CONFIG_ESP_CONSOLE_UART_BAUDRATE); +#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE || CONFIG_ESP32S2_DISABLE_BASIC_ROM_CONSOLE + // [refactor-todo] leads to call chain `esp_efuse_read_field_blob` (efuse) -> `esp_efuse_utility_process` -> `ESP_LOGX` + // syscall table must at least be init + esp_efuse_disable_basic_rom_console(); #endif #ifdef CONFIG_VFS_SUPPORT_IO @@ -239,6 +230,27 @@ static void IRAM_ATTR do_core_init(void) esp_efuse_disable_basic_rom_console(); #endif + esp_err_t err; + + esp_timer_init(); + esp_set_time_from_rtc(); + + // [refactor-todo] move this to secondary init +#if CONFIG_APPTRACE_ENABLE + err = esp_apptrace_init(); + assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!"); +#endif +#if CONFIG_SYSVIEW_ENABLE + SEGGER_SYSVIEW_Conf(); +#endif + +#if CONFIG_ESP_DEBUG_STUBS_ENABLE + esp_dbg_stubs_init(); +#endif + + err = esp_pthread_init(); + assert(err == ESP_OK && "Failed to init pthread module!"); + spi_flash_init(); /* init default OS-aware flash access critical section */ spi_flash_guard_set(&g_flash_guard_default_ops); @@ -277,6 +289,8 @@ static void IRAM_ATTR do_secondary_init(void) void IRAM_ATTR start_cpu0_default(void) { + ESP_EARLY_LOGI(TAG, "Pro cpu start user code"); + // Display information about the current running image. if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { const esp_app_desc_t *app_desc = esp_ota_get_app_description(); @@ -311,12 +325,12 @@ void IRAM_ATTR start_cpu0_default(void) // Now that the application is about to start, disable boot watchdog #ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE - rtc_wdt_disable(); + wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_disable(&rtc_wdt_ctx); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); #endif - // Finally, we jump to user code. - ESP_EARLY_LOGI(TAG, "Pro cpu start user code"); - #if SOC_CPU_CORES_NUM > 1 && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE s_system_full_inited = true; #endif @@ -336,8 +350,6 @@ IRAM_ATTR ESP_SYSTEM_INIT_FN(init_components0, BIT(0)) uart_div_modify(CONFIG_ESP_CONSOLE_UART_NUM, (uart_clk_freq << 4) / CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif // CONFIG_ESP_CONSOLE_UART_NONE - esp_dbg_stubs_init(); - err = esp_pthread_init(); assert(err == ESP_OK && "Failed to init pthread module!"); @@ -372,14 +384,4 @@ IRAM_ATTR ESP_SYSTEM_INIT_FN(init_components0, BIT(0)) esp_efuse_init(efuse_partition->address, efuse_partition->size); } #endif -} - -#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE -IRAM_ATTR ESP_SYSTEM_INIT_FN(init_components1, BIT(1)) -{ -#if CONFIG_APPTRACE_ENABLE - esp_err_t err = esp_apptrace_init(); - assert(err == ESP_OK && "Failed to init apptrace module on APP CPU!"); -#endif -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/components/freertos/xtensa/port.c b/components/freertos/xtensa/port.c index 8f8db730f..e96f71654 100644 --- a/components/freertos/xtensa/port.c +++ b/components/freertos/xtensa/port.c @@ -103,6 +103,7 @@ #include "esp_debug_helpers.h" #include "esp_heap_caps.h" +#include "esp_heap_caps_init.h" #include "esp_private/crosscore_int.h" #include "esp_intr_alloc.h" @@ -119,6 +120,18 @@ #include "soc/dport_reg.h" #include "esp_int_wdt.h" + +#include "sdkconfig.h" + +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/spiram.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/spiram.h" +#endif + +#include "esp_private/startup_internal.h" // [refactor-todo] for g_spiram_ok +#include "esp_app_trace.h" // [refactor-todo] for esp_app_trace_init + /* Defined in portasm.h */ extern void _frxt_tick_timer_init(void); @@ -140,8 +153,8 @@ _Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_A /*-----------------------------------------------------------*/ unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit -BaseType_t port_uxCriticalNesting[portNUM_PROCESSORS] = {0}; -BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0}; +BaseType_t port_uxCriticalNesting[portNUM_PROCESSORS] = {0}; +BaseType_t port_uxOldInterruptState[portNUM_PROCESSORS] = {0}; /*-----------------------------------------------------------*/ // User exception dispatcher when exiting @@ -396,12 +409,12 @@ uint32_t xPortGetTickRateHz(void) { void __attribute__((optimize("-O3"))) vPortEnterCritical(portMUX_TYPE *mux) { BaseType_t oldInterruptLevel = portENTER_CRITICAL_NESTED(); - /* Interrupts may already be disabled (because we're doing this recursively) + /* Interrupts may already be disabled (because we're doing this recursively) * but we can't get the interrupt level after * vPortCPUAquireMutex, because it also may mess with interrupts. * Get it here first, then later figure out if we're nesting * and save for real there. - */ + */ vPortCPUAcquireMutex( mux ); BaseType_t coreID = xPortGetCoreID(); BaseType_t newNesting = port_uxCriticalNesting[coreID] + 1; @@ -419,7 +432,7 @@ void __attribute__((optimize("-O3"))) vPortExitCritical(portMUX_TYPE *mux) vPortCPUReleaseMutex( mux ); BaseType_t coreID = xPortGetCoreID(); BaseType_t nesting = port_uxCriticalNesting[coreID]; - + if(nesting > 0U) { nesting--; @@ -447,11 +460,11 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, c esp_system_abort(buf); } -// `esp_system` calls the app entry point app_main for core 0 and app_mainX for +// `esp_system` calls the app entry point app_main for core 0 and app_mainX for // the rest of the cores which the app normally provides for non-os builds. -// If `freertos` is included in the build, wrap the call to app_main and provide +// If `freertos` is included in the build, wrap the call to app_main and provide // our own definition of app_mainX so that we can do our own initializations for each -// core and start the scheduler. +// core and start the scheduler. // // We now simply execute the real app_main in the context of the main task that // we also start. @@ -466,6 +479,20 @@ static void main_task(void* args) } #endif + // [refactor-todo] check if there is a way to move the following block to esp_system startup + heap_caps_enable_nonos_stack_heaps(); + + // Now we have startup stack RAM available for heap, enable any DMA pool memory +#if CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL + if (g_spiram_ok) { + esp_err_t r = esp_spiram_reserve_dma_pool(CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL); + if (r != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Could not reserve internal/DMA pool (error 0x%x)", r); + abort(); + } + } +#endif + //Initialize task wdt if configured to do so #ifdef CONFIG_ESP_TASK_WDT_PANIC ESP_ERROR_CHECK(esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, true)); @@ -501,6 +528,8 @@ static void main_task(void* args) #error "FreeRTOS and system configuration mismatch regarding the use of multiple cores." #endif + + #if !CONFIG_FREERTOS_UNICORE void app_mainX(void) { @@ -514,6 +543,12 @@ void app_mainX(void) ; } +#if CONFIG_APPTRACE_ENABLE + // [refactor-todo] move to esp_system initialization + esp_err_t err = esp_apptrace_init(); + assert(err == ESP_OK && "Failed to init apptrace module on APP CPU!"); +#endif + #if CONFIG_ESP_INT_WDT //Initialize the interrupt watch dog for CPU1. esp_int_wdt_cpu_init();