mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-19 14:26:01 -04:00
Merge branch 'refactor/core_init_registration' into 'master'
refactor(startup): implement registration of core init functions See merge request espressif/esp-idf!27402
This commit is contained in:
commit
b48b501d85
@ -77,7 +77,7 @@ esp_err_t esp_apptrace_init(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(esp_apptrace_init, ESP_SYSTEM_INIT_ALL_CORES, 115)
|
||||
ESP_SYSTEM_INIT_FN(esp_apptrace_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 115)
|
||||
{
|
||||
return esp_apptrace_init();
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* p
|
||||
* linked whenever SystemView is used.
|
||||
*/
|
||||
|
||||
ESP_SYSTEM_INIT_FN(sysview_init, BIT(0), 120)
|
||||
ESP_SYSTEM_INIT_FN(sysview_init, SECONDARY, BIT(0), 120)
|
||||
{
|
||||
SEGGER_SYSVIEW_Conf();
|
||||
return ESP_OK;
|
||||
|
@ -68,7 +68,7 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void)
|
||||
}
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(usb_serial_jtag_conn_status_init, BIT(0), 230)
|
||||
ESP_SYSTEM_INIT_FN(usb_serial_jtag_conn_status_init, SECONDARY, BIT(0), 230)
|
||||
{
|
||||
#if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION
|
||||
ESP_RETURN_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "usb_serial_jtag", &s_usb_serial_jtag_pm_lock),
|
||||
|
@ -89,7 +89,7 @@ bool clock_domain_pd_allowed(void)
|
||||
}
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE
|
||||
ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, BIT(0), 106)
|
||||
ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106)
|
||||
{
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
sleep_clock_system_retention_init();
|
||||
|
@ -185,7 +185,7 @@ void esp_deep_sleep_wakeup_io_reset(void)
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
|
||||
ESP_SYSTEM_INIT_FN(esp_sleep_startup_init, BIT(0), 105)
|
||||
ESP_SYSTEM_INIT_FN(esp_sleep_startup_init, SECONDARY, BIT(0), 105)
|
||||
{
|
||||
/* If the TOP domain is powered off, the GPIO will also be powered off during sleep,
|
||||
and all configurations in the sleep state of GPIO will not take effect.*/
|
||||
|
@ -259,7 +259,7 @@ bool peripheral_domain_pd_allowed(void)
|
||||
}
|
||||
|
||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, BIT(0), 107)
|
||||
ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, SECONDARY, BIT(0), 107)
|
||||
{
|
||||
sleep_sys_periph_retention_init();
|
||||
return ESP_OK;
|
||||
|
@ -29,6 +29,7 @@ else()
|
||||
"panic.c"
|
||||
"esp_system.c"
|
||||
"startup.c"
|
||||
"startup_funcs.c"
|
||||
"system_time.c"
|
||||
"stack_check.c"
|
||||
"ubsan.c"
|
||||
@ -97,6 +98,7 @@ endif()
|
||||
# due to -ffunction-sections -Wl,--gc-sections options.
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __ubsan_include")
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_system_include_startup_funcs")
|
||||
|
||||
# [refactor-todo] requirements due to init code, should be removable
|
||||
# once link-time registration of component init functions is used.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# This file is used to check the order of execution of ESP_SYSTEM_INIT_FN functions.
|
||||
@ -18,19 +18,20 @@ import typing
|
||||
|
||||
ESP_SYSTEM_INIT_FN_STR = r'ESP_SYSTEM_INIT_FN'
|
||||
ESP_SYSTEM_INIT_FN_REGEX_SIMPLE = re.compile(r'ESP_SYSTEM_INIT_FN')
|
||||
ESP_SYSTEM_INIT_FN_REGEX = re.compile(r'ESP_SYSTEM_INIT_FN\(([a-zA-Z0-9_]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([0-9]+)\)')
|
||||
ESP_SYSTEM_INIT_FN_REGEX = re.compile(r'ESP_SYSTEM_INIT_FN\(([a-zA-Z0-9_]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([0-9]+)\)')
|
||||
STARTUP_ENTRIES_FILE = 'components/esp_system/system_init_fn.txt'
|
||||
|
||||
|
||||
class StartupEntry:
|
||||
def __init__(self, filename: str, func: str, affinity: str, priority: int) -> None:
|
||||
def __init__(self, filename: str, func: str, stage: str, affinity: str, priority: int) -> None:
|
||||
self.filename = filename
|
||||
self.func = func
|
||||
self.stage = stage
|
||||
self.affinity = affinity
|
||||
self.priority = priority
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'{self.priority:3d}: {self.func} in {self.filename} on {self.affinity}'
|
||||
return f'{self.stage}: {self.priority:3d}: {self.func} in {self.filename} on {self.affinity}'
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@ -65,15 +66,20 @@ def main() -> None:
|
||||
entry = StartupEntry(
|
||||
filename=os.path.relpath(filename, idf_path),
|
||||
func=match[0],
|
||||
affinity=match[1],
|
||||
priority=int(match[2])
|
||||
stage=match[1],
|
||||
affinity=match[2],
|
||||
priority=int(match[3])
|
||||
)
|
||||
startup_entries.append(entry)
|
||||
|
||||
#
|
||||
# 2. Sort the ESP_SYSTEM_INIT_FN functions in C source files by priority
|
||||
# 2. Sort the ESP_SYSTEM_INIT_FN functions in C source files by stage and then priority
|
||||
#
|
||||
startup_entries = list(sorted(startup_entries, key=lambda e: e.priority))
|
||||
def sort_key(entry: StartupEntry) -> typing.Tuple[str, int]:
|
||||
# luckily 'core' and 'secondary' are in alphabetical order, so we can return the string
|
||||
return (entry.stage, entry.priority)
|
||||
|
||||
startup_entries = list(sorted(startup_entries, key=sort_key))
|
||||
startup_entries_lines = [str(entry) for entry in startup_entries]
|
||||
|
||||
#
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_cpu.h"
|
||||
|
||||
ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, ESP_SYSTEM_INIT_ALL_CORES, 101)
|
||||
ESP_SYSTEM_INIT_FN(esp_hw_stack_guard_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CORES, 101)
|
||||
{
|
||||
uint32_t core_id = esp_cpu_get_core_id();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -43,13 +43,18 @@ void startup_resume_other_cores(void);
|
||||
*/
|
||||
typedef struct {
|
||||
esp_err_t (*fn)(void); /*!< Pointer to the startup function */
|
||||
uint32_t cores; /*!< Bit map of cores where the function has to be called */
|
||||
uint16_t cores; /*!< Bit mask of cores where the function has to be called */
|
||||
uint16_t stage; /*!< Init stage number (0 or 1) */
|
||||
} esp_system_init_fn_t;
|
||||
|
||||
#define ESP_SYSTEM_INIT_STAGE_CORE 0
|
||||
#define ESP_SYSTEM_INIT_STAGE_SECONDARY 1
|
||||
|
||||
/**
|
||||
* @brief Define a system initialization function which will be executed on the specified cores
|
||||
*
|
||||
* @param f function name (identifier)
|
||||
* @param stage_ init stage name (CORE or SECONDARY)
|
||||
* @param c bit mask of cores to execute the function on (ex. if BIT0 is set, the function
|
||||
* will be executed on CPU 0, if BIT1 is set - on CPU 1, and so on)
|
||||
* @param priority integer, priority of the initialization function. Higher values mean that
|
||||
@ -65,10 +70,14 @@ typedef struct {
|
||||
* It is, on the other hand, a good practice to make sure the initialization function does get
|
||||
* discarded if the related feature is not used.
|
||||
*/
|
||||
#define ESP_SYSTEM_INIT_FN(f, c, priority, ...) \
|
||||
#define ESP_SYSTEM_INIT_FN(f, stage_, c, priority, ...) \
|
||||
static esp_err_t __VA_ARGS__ __esp_system_init_fn_##f(void); \
|
||||
static __attribute__((used)) _SECTION_ATTR_IMPL(".esp_system_init_fn", priority) \
|
||||
esp_system_init_fn_t esp_system_init_fn_##f = { .fn = ( __esp_system_init_fn_##f), .cores = (c) }; \
|
||||
esp_system_init_fn_t esp_system_init_fn_##f = { \
|
||||
.fn = ( __esp_system_init_fn_##f), \
|
||||
.cores = (c), \
|
||||
.stage = ESP_SYSTEM_INIT_STAGE_##stage_ \
|
||||
}; \
|
||||
static esp_err_t __esp_system_init_fn_##f(void)
|
||||
|
||||
#ifdef CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
|
@ -310,7 +310,7 @@ esp_err_t esp_usb_console_init(void)
|
||||
* too early, before esp_timer is fully initialized.
|
||||
* This gets called a bit later in the process when we can already register a timer.
|
||||
*/
|
||||
ESP_SYSTEM_INIT_FN(esp_usb_console_init_restart_timer, BIT(0), 220)
|
||||
ESP_SYSTEM_INIT_FN(esp_usb_console_init_restart_timer, SECONDARY, BIT(0), 220)
|
||||
{
|
||||
esp_timer_create_args_t timer_create_args = {
|
||||
.callback = &esp_usb_console_on_restart_timeout,
|
||||
|
@ -16,66 +16,8 @@
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/uart_types.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
#include "esp_heap_caps_init.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "esp_flash_internal.h"
|
||||
#include "esp_newlib.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_xt_wdt.h"
|
||||
#include "esp_cpu.h"
|
||||
|
||||
#include "esp_partition.h"
|
||||
|
||||
/***********************************************/
|
||||
// Headers for other components init functions
|
||||
#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
#include "private/esp_coexist_internal.h"
|
||||
#endif
|
||||
|
||||
#if __has_include("esp_app_desc.h")
|
||||
#define WITH_APP_IMAGE_INFO
|
||||
#include "esp_app_desc.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_COREDUMP_ENABLE
|
||||
#include "esp_core_dump.h"
|
||||
#endif
|
||||
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
#include "esp_pm.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_VFS_SUPPORT_IO
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_vfs_console.h"
|
||||
#endif
|
||||
|
||||
#include "esp_pthread.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
#include "esp_private/brownout.h"
|
||||
|
||||
#include "esp_rom_caps.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#if CONFIG_SPIRAM
|
||||
#include "esp_psram.h"
|
||||
#include "esp_private/esp_psram_extram.h"
|
||||
#endif
|
||||
/***********************************************/
|
||||
|
||||
#include "esp_private/startup_internal.h"
|
||||
|
||||
// Ensure that system configuration matches the underlying number of cores.
|
||||
@ -84,26 +26,8 @@
|
||||
#error "System has been configured to run on multiple cores, but target SoC only has a single core."
|
||||
#endif
|
||||
|
||||
// Set efuse ROM_LOG_MODE on first boot
|
||||
//
|
||||
// For CONFIG_BOOT_ROM_LOG_ALWAYS_ON (default) or undefined (ESP32), leave
|
||||
// ROM_LOG_MODE undefined (no need to call this function during startup)
|
||||
#if CONFIG_BOOT_ROM_LOG_ALWAYS_OFF
|
||||
#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ALWAYS_OFF
|
||||
#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW
|
||||
#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_LOW
|
||||
#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH
|
||||
#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH
|
||||
#endif
|
||||
|
||||
|
||||
uint64_t g_startup_time = 0;
|
||||
|
||||
#if SOC_APB_BACKUP_DMA
|
||||
// APB DMA lock initialising API
|
||||
extern void esp_apb_backup_dma_lock_init(void);
|
||||
#endif
|
||||
|
||||
// App entry point for core 0
|
||||
extern void esp_startup_start_app(void);
|
||||
|
||||
@ -130,34 +54,8 @@ static volatile bool s_system_full_inited = false;
|
||||
const sys_startup_fn_t g_startup_fn[1] = { start_cpu0 };
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
// workaround for C++ exception crashes
|
||||
void _Unwind_SetNoFunctionContextInstall(unsigned char enable) __attribute__((weak, alias("_Unwind_SetNoFunctionContextInstall_Default")));
|
||||
// workaround for C++ exception large memory allocation
|
||||
void _Unwind_SetEnableExceptionFdeSorting(unsigned char enable);
|
||||
|
||||
static IRAM_ATTR void _Unwind_SetNoFunctionContextInstall_Default(unsigned char enable __attribute__((unused)))
|
||||
{
|
||||
(void)0;
|
||||
}
|
||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
|
||||
static const char* TAG = "cpu_start";
|
||||
|
||||
/**
|
||||
* This function overwrites a the same function of libsupc++ (part of libstdc++).
|
||||
* Consequently, libsupc++ will then follow our configured exception emergency pool size.
|
||||
*
|
||||
* It will be called even with -fno-exception for user code since the stdlib still uses exceptions.
|
||||
*/
|
||||
size_t __cxx_eh_arena_size_get(void)
|
||||
{
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
return CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Xtensa gcc is configured to emit a .ctors section, RISC-V gcc is configured with --enable-initfini-array
|
||||
@ -210,9 +108,10 @@ static void do_global_ctors(void)
|
||||
* linker. The functions are sorted by their priority value.
|
||||
* The sequence of the init function calls (sorted by priority) is documented in
|
||||
* system_init_fn.txt file.
|
||||
* @param stage_num Stage number of the init function call (0, 1).
|
||||
*/
|
||||
__attribute__((no_sanitize_undefined)) /* TODO: IDF-8133 */
|
||||
static void do_system_init_fn(void)
|
||||
static void do_system_init_fn(uint32_t stage_num)
|
||||
{
|
||||
extern esp_system_init_fn_t _esp_system_init_fn_array_start;
|
||||
extern esp_system_init_fn_t _esp_system_init_fn_array_end;
|
||||
@ -221,11 +120,12 @@ static void do_system_init_fn(void)
|
||||
|
||||
int core_id = esp_cpu_get_core_id();
|
||||
for (p = &_esp_system_init_fn_array_start; p < &_esp_system_init_fn_array_end; ++p) {
|
||||
if (p->cores & BIT(core_id)) {
|
||||
ESP_LOGD(TAG, "calling init function: %p on core: %d", p->fn, core_id);
|
||||
if (p->stage == stage_num && (p->cores & BIT(core_id)) != 0) {
|
||||
// During core init, stdout is not initialized yet, so use early logging.
|
||||
ESP_EARLY_LOGD(TAG, "calling init function: %p on core: %d", p->fn, core_id);
|
||||
esp_err_t err = (*(p->fn))();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "init function %p has failed (0x%x), aborting", p->fn, err);
|
||||
ESP_EARLY_LOGE(TAG, "init function %p has failed (0x%x), aborting", p->fn, err);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@ -249,7 +149,7 @@ static void esp_startup_start_app_other_cores_default(void)
|
||||
*/
|
||||
static void IRAM_ATTR start_cpu_other_cores_default(void)
|
||||
{
|
||||
do_system_init_fn();
|
||||
do_system_init_fn(ESP_SYSTEM_INIT_STAGE_SECONDARY);
|
||||
|
||||
while (!s_system_full_inited) {
|
||||
esp_rom_delay_us(100);
|
||||
@ -261,129 +161,7 @@ static void IRAM_ATTR start_cpu_other_cores_default(void)
|
||||
|
||||
static void do_core_init(void)
|
||||
{
|
||||
/* Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted.
|
||||
If the heap allocator is initialized first, it will put free memory linked list items into
|
||||
memory also used by the ROM. Starting the app cpu will let its ROM initialize that memory,
|
||||
corrupting those linked lists. Initializing the allocator *after* the app cpu has booted
|
||||
works around this problem.
|
||||
With SPI RAM enabled, there's a second reason: half of the SPI RAM will be managed by the
|
||||
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();
|
||||
|
||||
// When apptrace module is enabled, there will be SEGGER_SYSVIEW calls in the newlib init.
|
||||
// SEGGER_SYSVIEW relies on apptrace module
|
||||
// apptrace module uses esp_timer_get_time to determine timeout conditions.
|
||||
// esp_timer early initialization is required for esp_timer_get_time to work.
|
||||
esp_timer_early_init();
|
||||
esp_newlib_init();
|
||||
|
||||
#if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
||||
if (esp_psram_is_initialized()) {
|
||||
esp_err_t r=esp_psram_extram_add_to_heap_allocator();
|
||||
if (r != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!");
|
||||
abort();
|
||||
}
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_BROWNOUT_DET
|
||||
// [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
|
||||
|
||||
esp_newlib_time_init();
|
||||
|
||||
#if CONFIG_VFS_SUPPORT_IO
|
||||
// VFS console register.
|
||||
esp_err_t vfs_err = esp_vfs_console_register();
|
||||
assert(vfs_err == ESP_OK && "Failed to register vfs console");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
|
||||
esp_newlib_init_global_stdio(ESP_VFS_DEV_CONSOLE);
|
||||
#else
|
||||
esp_newlib_init_global_stdio(NULL);
|
||||
#endif
|
||||
|
||||
esp_err_t err __attribute__((unused));
|
||||
|
||||
err = esp_pthread_init();
|
||||
assert(err == ESP_OK && "Failed to init pthread module!");
|
||||
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
#if CONFIG_SPI_FLASH_ROM_IMPL
|
||||
spi_flash_rom_impl_init();
|
||||
#endif
|
||||
|
||||
esp_flash_app_init();
|
||||
esp_err_t flash_ret = esp_flash_init_default_chip();
|
||||
assert(flash_ret == ESP_OK);
|
||||
(void)flash_ret;
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
spi_flash_needs_reset_check();
|
||||
#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
const esp_partition_t *efuse_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM, NULL);
|
||||
if (efuse_partition) {
|
||||
esp_efuse_init_virtual_mode_in_flash(efuse_partition->address, efuse_partition->size);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
esp_flash_encryption_init_checks();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT)
|
||||
// Note: in some configs this may read flash, so placed after flash init
|
||||
esp_secure_boot_init_checks();
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_ECDSA_USE_HARDWARE_K
|
||||
if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, NULL)) {
|
||||
// ECDSA key purpose block is present and hence permanently enable
|
||||
// the hardware TRNG supplied k mode (most secure mode)
|
||||
err = esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K);
|
||||
assert(err == ESP_OK && "Failed to enable ECDSA hardware k mode");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
err = esp_efuse_disable_rom_download_mode();
|
||||
assert(err == ESP_OK && "Failed to disable ROM download mode");
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
err = esp_efuse_enable_rom_secure_download_mode();
|
||||
assert(err == ESP_OK && "Failed to enable Secure Download mode");
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE
|
||||
esp_efuse_disable_basic_rom_console();
|
||||
#endif
|
||||
|
||||
#ifdef ROM_LOG_MODE
|
||||
esp_efuse_set_rom_log_scheme(ROM_LOG_MODE);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_XT_WDT
|
||||
esp_xt_wdt_config_t cfg = {
|
||||
.timeout = CONFIG_ESP_XT_WDT_TIMEOUT,
|
||||
.auto_backup_clk_enable = CONFIG_ESP_XT_WDT_BACKUP_CLK_ENABLE,
|
||||
};
|
||||
err = esp_xt_wdt_init(&cfg);
|
||||
assert(err == ESP_OK && "Failed to init xtwdt");
|
||||
#endif
|
||||
do_system_init_fn(ESP_SYSTEM_INIT_STAGE_CORE);
|
||||
}
|
||||
|
||||
static void do_secondary_init(void)
|
||||
@ -397,7 +175,7 @@ static void do_secondary_init(void)
|
||||
// Execute initialization functions esp_system_init_fn_t assigned to the main core. While
|
||||
// this is happening, all other cores are executing the initialization functions
|
||||
// assigned to them since they have been resumed already.
|
||||
do_system_init_fn();
|
||||
do_system_init_fn(ESP_SYSTEM_INIT_STAGE_SECONDARY);
|
||||
|
||||
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
// Wait for all cores to finish secondary init.
|
||||
@ -415,41 +193,6 @@ static void do_secondary_init(void)
|
||||
|
||||
static void start_cpu0_default(void)
|
||||
{
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Pro cpu start user code");
|
||||
int cpu_freq = esp_clk_cpu_freq();
|
||||
ESP_EARLY_LOGI(TAG, "cpu freq: %d Hz", cpu_freq);
|
||||
|
||||
#ifdef WITH_APP_IMAGE_INFO
|
||||
// Display information about the current running image.
|
||||
if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) {
|
||||
const esp_app_desc_t *app_desc = esp_app_get_description();
|
||||
ESP_EARLY_LOGI(TAG, "Application information:");
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
ESP_EARLY_LOGI(TAG, "Project name: %s", app_desc->project_name);
|
||||
#endif
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
||||
ESP_EARLY_LOGI(TAG, "App version: %s", app_desc->version);
|
||||
#endif
|
||||
#ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
|
||||
ESP_EARLY_LOGI(TAG, "Secure version: %d", app_desc->secure_version);
|
||||
#endif
|
||||
#ifdef CONFIG_APP_COMPILE_TIME_DATE
|
||||
ESP_EARLY_LOGI(TAG, "Compile time: %s %s", app_desc->date, app_desc->time);
|
||||
#endif
|
||||
char buf[17];
|
||||
esp_app_get_elf_sha256(buf, sizeof(buf));
|
||||
ESP_EARLY_LOGI(TAG, "ELF file SHA256: %s...", buf);
|
||||
ESP_EARLY_LOGI(TAG, "ESP-IDF: %s", app_desc->idf_ver);
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Min chip rev: v%d.%d", CONFIG_ESP_REV_MIN_FULL / 100, CONFIG_ESP_REV_MIN_FULL % 100);
|
||||
ESP_EARLY_LOGI(TAG, "Max chip rev: v%d.%d %s",CONFIG_ESP_REV_MAX_FULL / 100, CONFIG_ESP_REV_MAX_FULL % 100,
|
||||
efuse_hal_get_disable_wafer_version_major() ? "(constraint ignored)" : "");
|
||||
unsigned revision = efuse_hal_chip_revision();
|
||||
ESP_EARLY_LOGI(TAG, "Chip rev: v%d.%d", revision / 100, revision % 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize core components and services.
|
||||
do_core_init();
|
||||
|
||||
@ -460,14 +203,6 @@ static void start_cpu0_default(void)
|
||||
// until all cores finish (when !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE).
|
||||
do_secondary_init();
|
||||
|
||||
// Now that the application is about to start, disable boot watchdog
|
||||
#ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE
|
||||
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
#endif
|
||||
|
||||
#if SOC_CPU_CORES_NUM > 1 && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|
||||
s_system_full_inited = true;
|
||||
#endif
|
||||
@ -475,35 +210,3 @@ static void start_cpu0_default(void)
|
||||
esp_startup_start_app();
|
||||
while (1);
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_components0, BIT(0), 200)
|
||||
{
|
||||
#if CONFIG_ESP_DEBUG_STUBS_ENABLE
|
||||
esp_dbg_stubs_init();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PM_ENABLE)
|
||||
esp_pm_impl_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_COREDUMP_ENABLE
|
||||
esp_core_dump_init();
|
||||
#endif
|
||||
|
||||
#if SOC_APB_BACKUP_DMA
|
||||
esp_apb_backup_dma_lock_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
esp_coex_adapter_register(&g_coex_adapter_funcs);
|
||||
coex_pre_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
ESP_EARLY_LOGD(TAG, "Setting C++ exception workarounds.");
|
||||
_Unwind_SetNoFunctionContextInstall(1);
|
||||
_Unwind_SetEnableExceptionFdeSorting(0);
|
||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
386
components/esp_system/startup_funcs.c
Normal file
386
components/esp_system/startup_funcs.c
Normal file
@ -0,0 +1,386 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps_init.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "esp_flash_internal.h"
|
||||
#include "esp_newlib.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_xt_wdt.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_private/startup_internal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/uart_types.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
#include "private/esp_coexist_internal.h"
|
||||
#endif
|
||||
|
||||
#if __has_include("esp_app_desc.h")
|
||||
#define WITH_APP_IMAGE_INFO
|
||||
#include "esp_app_desc.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_COREDUMP_ENABLE
|
||||
#include "esp_core_dump.h"
|
||||
#endif
|
||||
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
#include "esp_pm.h"
|
||||
#include "esp_private/pm_impl.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_VFS_SUPPORT_IO
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_vfs_console.h"
|
||||
#endif
|
||||
|
||||
#include "esp_pthread.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
#include "esp_private/brownout.h"
|
||||
|
||||
#include "esp_rom_caps.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#if CONFIG_SPIRAM
|
||||
#include "esp_psram.h"
|
||||
#include "esp_private/esp_psram_extram.h"
|
||||
#endif
|
||||
|
||||
// Using the same tag as in startup.c to keep the logs unchanged
|
||||
static const char* TAG = "cpu_start";
|
||||
|
||||
// Hook to force the linker to include this file
|
||||
void esp_system_include_startup_funcs(void)
|
||||
{
|
||||
}
|
||||
|
||||
// [refactor-todo] Most of these init functions should be moved to the respective components.
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_show_cpu_freq, CORE, BIT(0), 10)
|
||||
{
|
||||
ESP_EARLY_LOGI(TAG, "Pro cpu start user code");
|
||||
int cpu_freq = esp_clk_cpu_freq();
|
||||
ESP_EARLY_LOGI(TAG, "cpu freq: %d Hz", cpu_freq);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef WITH_APP_IMAGE_INFO
|
||||
ESP_SYSTEM_INIT_FN(init_show_app_info, CORE, BIT(0), 20)
|
||||
{
|
||||
// Display information about the current running image.
|
||||
if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) {
|
||||
const esp_app_desc_t *app_desc = esp_app_get_description();
|
||||
ESP_EARLY_LOGI(TAG, "Application information:");
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
ESP_EARLY_LOGI(TAG, "Project name: %s", app_desc->project_name);
|
||||
#endif
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
||||
ESP_EARLY_LOGI(TAG, "App version: %s", app_desc->version);
|
||||
#endif
|
||||
#ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
|
||||
ESP_EARLY_LOGI(TAG, "Secure version: %d", app_desc->secure_version);
|
||||
#endif
|
||||
#ifdef CONFIG_APP_COMPILE_TIME_DATE
|
||||
ESP_EARLY_LOGI(TAG, "Compile time: %s %s", app_desc->date, app_desc->time);
|
||||
#endif
|
||||
char buf[17];
|
||||
esp_app_get_elf_sha256(buf, sizeof(buf));
|
||||
ESP_EARLY_LOGI(TAG, "ELF file SHA256: %s...", buf);
|
||||
ESP_EARLY_LOGI(TAG, "ESP-IDF: %s", app_desc->idf_ver);
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Min chip rev: v%d.%d", CONFIG_ESP_REV_MIN_FULL / 100, CONFIG_ESP_REV_MIN_FULL % 100);
|
||||
ESP_EARLY_LOGI(TAG, "Max chip rev: v%d.%d %s", CONFIG_ESP_REV_MAX_FULL / 100, CONFIG_ESP_REV_MAX_FULL % 100,
|
||||
efuse_hal_get_disable_wafer_version_major() ? "(constraint ignored)" : "");
|
||||
unsigned revision = efuse_hal_chip_revision();
|
||||
ESP_EARLY_LOGI(TAG, "Chip rev: v%d.%d", revision / 100, revision % 100);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // WITH_APP_IMAGE_INFO
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_heap, CORE, BIT(0), 100)
|
||||
{
|
||||
heap_caps_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_timer, CORE, BIT(0), 101)
|
||||
{
|
||||
esp_timer_early_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_newlib, CORE, BIT(0), 102)
|
||||
{
|
||||
esp_newlib_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_psram_heap, CORE, BIT(0), 103)
|
||||
{
|
||||
#if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
||||
if (esp_psram_is_initialized()) {
|
||||
esp_err_t r = esp_psram_extram_add_to_heap_allocator();
|
||||
if (r != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!");
|
||||
abort();
|
||||
}
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_BROWNOUT_DET
|
||||
ESP_SYSTEM_INIT_FN(init_brownout, CORE, BIT(0), 104)
|
||||
{
|
||||
// [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();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_newlib_time, CORE, BIT(0), 105)
|
||||
{
|
||||
esp_newlib_time_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if CONFIG_VFS_SUPPORT_IO
|
||||
ESP_SYSTEM_INIT_FN(init_vfs_console, CORE, BIT(0), 110)
|
||||
{
|
||||
// VFS console register.
|
||||
return esp_vfs_console_register();
|
||||
}
|
||||
#endif // CONFIG_VFS_SUPPORT_IO
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_newlib_stdio, CORE, BIT(0), 115)
|
||||
{
|
||||
#if defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
|
||||
esp_newlib_init_global_stdio(ESP_VFS_DEV_CONSOLE);
|
||||
#else
|
||||
esp_newlib_init_global_stdio(NULL);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_pthread, CORE, BIT(0), 120)
|
||||
{
|
||||
return esp_pthread_init();
|
||||
}
|
||||
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130)
|
||||
{
|
||||
#if CONFIG_SPI_FLASH_ROM_IMPL
|
||||
spi_flash_rom_impl_init();
|
||||
#endif
|
||||
|
||||
esp_flash_app_init();
|
||||
esp_err_t flash_ret = esp_flash_init_default_chip();
|
||||
assert(flash_ret == ESP_OK);
|
||||
(void)flash_ret;
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
spi_flash_needs_reset_check();
|
||||
#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
ESP_SYSTEM_INIT_FN(init_virtual_efuse, CORE, BIT(0), 140)
|
||||
{
|
||||
ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
|
||||
const esp_partition_t *efuse_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM, NULL);
|
||||
if (efuse_partition) {
|
||||
esp_efuse_init_virtual_mode_in_flash(efuse_partition->address, efuse_partition->size);
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_EFUSE_VIRTUAL
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_secure, CORE, BIT(0), 150)
|
||||
{
|
||||
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
|
||||
esp_flash_encryption_init_checks();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT)
|
||||
// Note: in some configs this may read flash, so placed after flash init
|
||||
esp_secure_boot_init_checks();
|
||||
#endif
|
||||
|
||||
#if SOC_EFUSE_ECDSA_USE_HARDWARE_K
|
||||
if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, NULL)) {
|
||||
// ECDSA key purpose block is present and hence permanently enable
|
||||
// the hardware TRNG supplied k mode (most secure mode)
|
||||
ESP_RETURN_ON_ERROR(esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K), TAG, "Failed to enable hardware k mode");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
ESP_RETURN_ON_ERROR(esp_efuse_disable_rom_download_mode(), TAG, "Failed to disable ROM download mode");
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
ESP_RETURN_ON_ERROR(esp_efuse_enable_rom_secure_download_mode(), TAG, "Failed to enable Secure Download mode");
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE
|
||||
esp_efuse_disable_basic_rom_console();
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Set efuse ROM_LOG_MODE on first boot
|
||||
//
|
||||
// For CONFIG_BOOT_ROM_LOG_ALWAYS_ON (default) or undefined (ESP32), leave
|
||||
// ROM_LOG_MODE undefined (no need to call this function during startup)
|
||||
#if CONFIG_BOOT_ROM_LOG_ALWAYS_OFF
|
||||
#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ALWAYS_OFF
|
||||
#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW
|
||||
#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_LOW
|
||||
#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH
|
||||
#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH
|
||||
#endif
|
||||
|
||||
#ifdef ROM_LOG_MODE
|
||||
ESP_SYSTEM_INIT_FN(init_rom_log, CORE, BIT(0), 160)
|
||||
{
|
||||
esp_err_t err = esp_efuse_set_rom_log_scheme(ROM_LOG_MODE);
|
||||
if (err == ESP_ERR_NOT_SUPPORTED) {
|
||||
err = ESP_OK;
|
||||
}
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "Failed to set ROM log scheme");
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // ROM_LOG_MODE
|
||||
|
||||
#if CONFIG_ESP_XT_WDT
|
||||
ESP_SYSTEM_INIT_FN(init_xt_wdt, CORE, BIT(0), 170)
|
||||
{
|
||||
esp_xt_wdt_config_t cfg = {
|
||||
.timeout = CONFIG_ESP_XT_WDT_TIMEOUT,
|
||||
.auto_backup_clk_enable = CONFIG_ESP_XT_WDT_BACKUP_CLK_ENABLE,
|
||||
};
|
||||
return esp_xt_wdt_init(&cfg);
|
||||
}
|
||||
#endif // CONFIG_ESP_XT_WDT
|
||||
|
||||
#if CONFIG_ESP_DEBUG_STUBS_ENABLE
|
||||
ESP_SYSTEM_INIT_FN(init_dbg_stubs, SECONDARY, BIT(0), 200)
|
||||
{
|
||||
esp_dbg_stubs_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_ESP_DEBUG_STUBS_ENABLE
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
ESP_SYSTEM_INIT_FN(init_pm, SECONDARY, BIT(0), 201)
|
||||
{
|
||||
esp_pm_impl_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_PM_ENABLE
|
||||
|
||||
#if CONFIG_ESP_COREDUMP_ENABLE
|
||||
ESP_SYSTEM_INIT_FN(init_coredump, SECONDARY, BIT(0), 202)
|
||||
{
|
||||
esp_core_dump_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_ESP_COREDUMP_ENABLE
|
||||
|
||||
#if SOC_APB_BACKUP_DMA
|
||||
ESP_SYSTEM_INIT_FN(init_apb_dma, SECONDARY, BIT(0), 203)
|
||||
{
|
||||
extern void esp_apb_backup_dma_lock_init(void);
|
||||
esp_apb_backup_dma_lock_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
ESP_SYSTEM_INIT_FN(init_coexist, SECONDARY, BIT(0), 204)
|
||||
{
|
||||
esp_coex_adapter_register(&g_coex_adapter_funcs);
|
||||
coex_pre_init();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
|
||||
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
/**
|
||||
* This function overwrites a the same function of libsupc++ (part of libstdc++).
|
||||
* Consequently, libsupc++ will then follow our configured exception emergency pool size.
|
||||
*
|
||||
* It will be called even with -fno-exception for user code since the stdlib still uses exceptions.
|
||||
*/
|
||||
size_t __cxx_eh_arena_size_get(void)
|
||||
{
|
||||
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
return CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// workaround for C++ exception crashes
|
||||
void _Unwind_SetNoFunctionContextInstall(unsigned char enable) __attribute__((weak, alias("_Unwind_SetNoFunctionContextInstall_Default")));
|
||||
// workaround for C++ exception large memory allocation
|
||||
void _Unwind_SetEnableExceptionFdeSorting(unsigned char enable);
|
||||
|
||||
static IRAM_ATTR void _Unwind_SetNoFunctionContextInstall_Default(unsigned char enable __attribute__((unused)))
|
||||
{
|
||||
(void)0;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(init_cxx_exceptions, SECONDARY, BIT(0), 205)
|
||||
{
|
||||
ESP_EARLY_LOGD(TAG, "Setting C++ exception workarounds.");
|
||||
_Unwind_SetNoFunctionContextInstall(1);
|
||||
_Unwind_SetEnableExceptionFdeSorting(0);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
|
||||
#ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE
|
||||
ESP_SYSTEM_INIT_FN(init_disable_rtc_wdt, SECONDARY, BIT(0), 999)
|
||||
{
|
||||
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_disable(&rtc_wdt_ctx);
|
||||
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE
|
@ -7,35 +7,86 @@
|
||||
#
|
||||
# Entries are ordered by the order of execution (i.e. from low priority values to high ones).
|
||||
# Each line has the following format:
|
||||
# prio: function_name in path/to/source_file on affinity_expression
|
||||
# stage: prio: function_name in path/to/source_file on affinity_expression
|
||||
# Where:
|
||||
# stage: which startup stage the function is executed in (CORE or SECONDARY)
|
||||
# prio: priority value (higher value means function is executed later)
|
||||
# affinity_expression: bit map of cores the function is executed on
|
||||
|
||||
|
||||
########### CORE startup stage ###########
|
||||
# [refactor-todo]: move init calls into respective components
|
||||
|
||||
# Log some information about the system
|
||||
CORE: 10: init_show_cpu_freq in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 20: init_show_app_info in components/esp_system/startup_funcs.c on BIT(0)
|
||||
|
||||
# Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted.
|
||||
# If the heap allocator is initialized first, it will put free memory linked list items into
|
||||
# memory also used by the ROM. Starting the app cpu will let its ROM initialize that memory,
|
||||
# corrupting those linked lists. Initializing the allocator *after* the app cpu has booted
|
||||
# works around this problem.
|
||||
# With SPI RAM enabled, there's a second reason: half of the SPI RAM will be managed by the
|
||||
# app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may
|
||||
# fail initializing it properly.
|
||||
CORE: 100: init_heap in components/esp_system/startup_funcs.c on BIT(0)
|
||||
|
||||
# When apptrace module is enabled, there will be SEGGER_SYSVIEW calls in the newlib init.
|
||||
# SEGGER_SYSVIEW relies on apptrace module
|
||||
# apptrace module uses esp_timer_get_time to determine timeout conditions.
|
||||
# esp_timer early initialization is required for esp_timer_get_time to work.
|
||||
CORE: 101: init_timer in components/esp_system/startup_funcs.c on BIT(0)
|
||||
|
||||
CORE: 102: init_newlib in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 103: init_psram_heap in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 104: init_brownout in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 105: init_newlib_time in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 110: init_vfs_console in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 115: init_newlib_stdio in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 120: init_pthread in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 130: init_flash in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 140: init_virtual_efuse in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 150: init_secure in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 160: init_rom_log in components/esp_system/startup_funcs.c on BIT(0)
|
||||
CORE: 170: init_xt_wdt in components/esp_system/startup_funcs.c on BIT(0)
|
||||
|
||||
|
||||
########### SECONDARY startup stage ###########
|
||||
|
||||
# esp_timer has to be initialized early, since it is used by several other components
|
||||
100: esp_timer_startup_init in components/esp_timer/src/esp_timer.c on CONFIG_ESP_TIMER_ISR_AFFINITY
|
||||
SECONDARY: 100: esp_timer_startup_init in components/esp_timer/src/esp_timer.c on ESP_TIMER_INIT_MASK
|
||||
|
||||
# HW stack guard via assist-debug module.
|
||||
101: esp_hw_stack_guard_init in components/esp_system/hw_stack_guard.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||
SECONDARY: 101: esp_hw_stack_guard_init in components/esp_system/hw_stack_guard.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||
|
||||
# esp_sleep doesn't have init dependencies
|
||||
105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0)
|
||||
106: sleep_clock_startup_init in components/esp_hw_support/sleep_clock.c on BIT(0)
|
||||
107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
||||
SECONDARY: 105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0)
|
||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/sleep_clock.c on BIT(0)
|
||||
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
||||
|
||||
# app_trace has to be initialized before systemview
|
||||
115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||
120: sysview_init in components/app_trace/sys_view/esp/SEGGER_RTT_esp.c on BIT(0)
|
||||
SECONDARY: 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||
SECONDARY: 120: sysview_init in components/app_trace/sys_view/esp/SEGGER_RTT_esp.c on BIT(0)
|
||||
|
||||
# the rest of the components which are initialized from startup.c
|
||||
# the rest of the components which are initialized from startup_funcs.c
|
||||
# [refactor-todo]: move init calls into respective components
|
||||
200: init_components0 in components/esp_system/startup.c on BIT(0)
|
||||
SECONDARY: 200: init_dbg_stubs in components/esp_system/startup_funcs.c on BIT(0)
|
||||
SECONDARY: 201: init_pm in components/esp_system/startup_funcs.c on BIT(0)
|
||||
SECONDARY: 202: init_coredump in components/esp_system/startup_funcs.c on BIT(0)
|
||||
SECONDARY: 203: init_apb_dma in components/esp_system/startup_funcs.c on BIT(0)
|
||||
SECONDARY: 204: init_coexist in components/esp_system/startup_funcs.c on BIT(0)
|
||||
SECONDARY: 205: init_cxx_exceptions in components/esp_system/startup_funcs.c on BIT(0)
|
||||
|
||||
# usb_console needs to create an esp_timer at startup.
|
||||
# This can be done only after esp_timer initialization, which is now in init_components0.
|
||||
220: esp_usb_console_init_restart_timer in components/esp_system/port/usb_console.c on BIT(0)
|
||||
# This can be done only after esp_timer initialization (esp_timer_startup_init).
|
||||
SECONDARY: 220: esp_usb_console_init_restart_timer in components/esp_system/port/usb_console.c on BIT(0)
|
||||
|
||||
# usb_serial_jtag needs to create and acquire a PM clock at startup.
|
||||
# This makes more sense to be done after esp_pm_impl_init, which is initialized in init_components0.
|
||||
230: usb_serial_jtag_conn_status_init in components/driver/usb_serial_jtag/usb_serial_jtag_connection_monitor.c on BIT(0)
|
||||
# usb_serial_jtag needs to create and acquire a PM lock at startup.
|
||||
# This makes more sense to be done after esp_pm_impl_init (called from init_pm).
|
||||
SECONDARY: 230: usb_serial_jtag_conn_status_init in components/driver/usb_serial_jtag/usb_serial_jtag_connection_monitor.c on BIT(0)
|
||||
|
||||
# Has to be the last step!
|
||||
# Now that the application is about to start, disable boot watchdog
|
||||
SECONDARY: 999: init_disable_rtc_wdt in components/esp_system/startup_funcs.c on BIT(0)
|
||||
|
||||
# DO NOT add new init functions here. Add them to the correct stage above.
|
||||
|
@ -74,12 +74,6 @@ menu "High resolution timer (esp_timer)"
|
||||
depends on !FREERTOS_UNICORE && ESP_TIMER_SHOW_EXPERIMENTAL
|
||||
endchoice
|
||||
|
||||
config ESP_TIMER_ISR_AFFINITY
|
||||
hex
|
||||
default 0x1 if ESP_TIMER_ISR_AFFINITY_CPU0
|
||||
default 0x2 if ESP_TIMER_ISR_AFFINITY_CPU1
|
||||
default FREERTOS_NO_AFFINITY if ESP_TIMER_ISR_AFFINITY_NO_AFFINITY
|
||||
|
||||
choice ESP_TIMER_ISR_AFFINITY
|
||||
prompt "timer interrupt core affinity"
|
||||
default ESP_TIMER_ISR_AFFINITY_CPU0
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -574,7 +574,16 @@ esp_err_t esp_timer_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_SYSTEM_INIT_FN(esp_timer_startup_init, CONFIG_ESP_TIMER_ISR_AFFINITY, 100)
|
||||
#if CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0
|
||||
#define ESP_TIMER_INIT_MASK BIT(0)
|
||||
#elif CONFIG_ESP_TIMER_ISR_AFFINITY_CPU1
|
||||
#define ESP_TIMER_INIT_MASK BIT(1)
|
||||
#elif CONFIG_ESP_TIMER_ISR_AFFINITY_NO_AFFINITY
|
||||
#define ESP_TIMER_INIT_MASK ESP_SYSTEM_INIT_ALL_CORES
|
||||
#endif // CONFIG_ESP_TIMER_ISR_AFFINITY_*
|
||||
|
||||
|
||||
ESP_SYSTEM_INIT_FN(esp_timer_startup_init, SECONDARY, ESP_TIMER_INIT_MASK, 100)
|
||||
{
|
||||
return esp_timer_init();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user