From 98dc1b0188f3b9c30eec0717e97207fc04fbeda7 Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Wed, 10 Jun 2020 21:13:31 +0800 Subject: [PATCH] esp_system: introduce intermediary function to call after system init This MR uses an intermediary function `start_app` to call after system initialization instead of `app_main`. In RTOS builds, freertos provides `start_app` and calls `app_main`. In non-RTOS builds, user provides `start_app` directly. --- components/esp_system/CMakeLists.txt | 9 ++++++--- components/esp_system/startup.c | 16 ++++++++-------- components/freertos/CMakeLists.txt | 8 +++++++- components/freertos/xtensa/port.c | 17 +++++------------ 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 078f2d4e1..5da5b2b62 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -8,9 +8,12 @@ idf_component_register(SRCS "panic.c" "system_api.c" "startup.c" add_subdirectory(port) -# Rely on user code to define app_main -target_link_libraries(${COMPONENT_LIB} INTERFACE "-u app_main") +# After system initialization, `start_app` (and its other cores variant) is called. +# This is provided by the user or from another component. Since we can't establish +# dependency on what we don't know, force linker to not drop the symbol regardless +# of link line order. +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u start_app") if (NOT CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE) - target_link_libraries(${COMPONENT_LIB} INTERFACE "-u app_mainX") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u start_app_other_cores") endif() \ No newline at end of file diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index ae6df19f8..85d0507c0 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -77,23 +77,23 @@ #define STRINGIFY2(s) #s // App entry point for core 0 -extern void app_main(void); +extern void start_app(void); // Entry point for core 0 from hardware init (port layer) void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))) __attribute__((noreturn)); #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE // Entry point for core [1..X] from hardware init (port layer) -void start_cpuX(void) __attribute__((weak, alias("start_cpuX_default"))) __attribute__((noreturn)); +void start_cpu_other_cores(void) __attribute__((weak, alias("start_cpu_other_cores_default"))) __attribute__((noreturn)); // App entry point for core [1..X] -void app_mainX(void) __attribute__((weak, alias("app_mainX_default"))) __attribute__((noreturn)); +void start_app_other_cores(void) __attribute__((weak, alias("start_app_other_cores_default"))) __attribute__((noreturn)); static volatile bool s_system_inited[SOC_CPU_CORES_NUM] = { false }; sys_startup_fn_t g_startup_fn[SOC_CPU_CORES_NUM] = { [0] = start_cpu0, #if SOC_CPU_CORES_NUM > 1 - [1 ... SOC_CPU_CORES_NUM - 1] = start_cpuX + [1 ... SOC_CPU_CORES_NUM - 1] = start_cpu_other_cores #endif }; @@ -143,14 +143,14 @@ static void IRAM_ATTR do_system_init_fn(void) } #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE -static void IRAM_ATTR app_mainX_default(void) +static void IRAM_ATTR start_app_other_cores_default(void) { while (1) { ets_delay_us(UINT32_MAX); } } -static void IRAM_ATTR start_cpuX_default(void) +static void IRAM_ATTR start_cpu_other_cores_default(void) { do_system_init_fn(); @@ -158,7 +158,7 @@ static void IRAM_ATTR start_cpuX_default(void) ets_delay_us(100); } - app_mainX(); + start_app_other_cores(); } #endif @@ -331,7 +331,7 @@ void IRAM_ATTR start_cpu0_default(void) s_system_full_inited = true; #endif - app_main(); + start_app(); while (1); } diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index 58bb3cbd1..5ca347582 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -63,4 +63,10 @@ set_source_files_properties( _ESP_FREERTOS_INTERNAL ) -target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=app_main") \ No newline at end of file +# The freertos component provides the `start_app` and `start_app_other_cores` +# if it is included in the build. It then calls `app_main` +# from the main task created, which must be provided by the user. +# Like for `start_app` and `start_app_other_cores`, +# we can't establish dependency on what we don't yet know, so we force the +# linker to not drop this symbol. +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u app_main") \ No newline at end of file diff --git a/components/freertos/xtensa/port.c b/components/freertos/xtensa/port.c index 733e94829..9c9fa0dc3 100644 --- a/components/freertos/xtensa/port.c +++ b/components/freertos/xtensa/port.c @@ -138,6 +138,8 @@ extern void _frxt_tick_timer_init(void); /* Defined in xtensa_context.S */ extern void _xt_coproc_init(void); +extern void app_main(void); + static const char* TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but // for now maintain the same log output @@ -460,15 +462,6 @@ 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 -// 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 -// our own definition of app_mainX so that we can do our own initializations for each -// core and start the scheduler. -// -// We now simply execute the real app_main in the context of the main task that -// we also start. -extern void __real_app_main(void); static void main_task(void* args) { @@ -515,7 +508,7 @@ static void main_task(void* args) } #endif - __real_app_main(); + app_main(); vTaskDelete(NULL); } @@ -530,7 +523,7 @@ static void main_task(void* args) #if !CONFIG_FREERTOS_UNICORE -void app_mainX(void) +void start_app_other_cores(void) { // For now, we only support up to two core: 0 and 1. if (xPortGetCoreID() >= 2) { @@ -562,7 +555,7 @@ void app_mainX(void) } #endif -void __wrap_app_main(void) +void start_app(void) { #if CONFIG_ESP_INT_WDT esp_int_wdt_init();