From 2d5f12b8ef32d5f28be7fd7d1d5422ab5a8a3132 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sat, 7 Apr 2018 14:46:02 +0800 Subject: [PATCH] Move continuation stack from .bss onto sys stack --- cores/esp8266/cont_util.c | 3 + cores/esp8266/core_esp8266_main.cpp | 73 ++++++++++++++++--------- cores/esp8266/core_esp8266_postmortem.c | 6 +- cores/esp8266/libc_replacements.c | 38 +------------ platform.txt | 2 +- tools/platformio-build.py | 3 +- tools/sdk/include/ets_sys.h | 1 + tools/sdk/ld/eagle.app.v6.common.ld | 6 +- tools/sdk/ld/eagle.app.v6.common.ld.h | 7 ++- 9 files changed, 70 insertions(+), 69 deletions(-) diff --git a/cores/esp8266/cont_util.c b/cores/esp8266/cont_util.c index 15be292eb7..08704702b6 100644 --- a/cores/esp8266/cont_util.c +++ b/cores/esp8266/cont_util.c @@ -20,12 +20,15 @@ #include "cont.h" #include +#include #include "ets_sys.h" #define CONT_STACKGUARD 0xfeefeffe void cont_init(cont_t* cont) { + memset(cont, 0, sizeof(cont_t)); + cont->stack_guard1 = CONT_STACKGUARD; cont->stack_guard2 = CONT_STACKGUARD; cont->stack_end = cont->stack + (sizeof(cont->stack) / 4); diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index cb7401366e..52ba57857b 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -37,11 +37,30 @@ extern "C" { #define LOOP_TASK_PRIORITY 1 #define LOOP_QUEUE_SIZE 1 - #define OPTIMISTIC_YIELD_TIME_US 16000 +extern "C" void call_user_start(); +extern void loop(); +extern void setup(); +extern void (*__init_array_start)(void); +extern void (*__init_array_end)(void); + +/* Not static, used in Esp.cpp */ struct rst_info resetInfo; +/* Not static, used in core_esp8266_postmortem.c. + * Placed into noinit section because we assign value to this variable + * before .bss is zero-filled, and need to preserve the value. + */ +cont_t* g_pcont __attribute__((section(".noinit"))); + +/* Event queue used by the main (arduino) task */ +static os_event_t s_loop_queue[LOOP_QUEUE_SIZE]; + +/* Used to implement optimistic_yield */ +static uint32_t s_micros_at_task_start; + + extern "C" { extern const uint32_t __attribute__((section(".ver_number"))) core_version = ARDUINO_ESP8266_GIT_VER; const char* core_release = @@ -52,19 +71,10 @@ const char* core_release = #endif } // extern "C" -int atexit(void (*func)()) { - (void) func; - return 0; -} - -extern "C" void ets_update_cpu_frequency(int freqmhz); void initVariant() __attribute__((weak)); void initVariant() { } -extern void loop(); -extern void setup(); - void preloop_update_frequency() __attribute__((weak)); void preloop_update_frequency() { #if defined(F_CPU) && (F_CPU == 160000000L) @@ -73,17 +83,10 @@ void preloop_update_frequency() { #endif } -extern void (*__init_array_start)(void); -extern void (*__init_array_end)(void); - -cont_t g_cont __attribute__ ((aligned (16))); -static os_event_t g_loop_queue[LOOP_QUEUE_SIZE]; - -static uint32_t g_micros_at_task_start; extern "C" void esp_yield() { - if (cont_can_yield(&g_cont)) { - cont_yield(&g_cont); + if (cont_can_yield(g_pcont)) { + cont_yield(g_pcont); } } @@ -92,7 +95,7 @@ extern "C" void esp_schedule() { } extern "C" void __yield() { - if (cont_can_yield(&g_cont)) { + if (cont_can_yield(g_pcont)) { esp_schedule(); esp_yield(); } @@ -104,8 +107,8 @@ extern "C" void __yield() { extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); extern "C" void optimistic_yield(uint32_t interval_us) { - if (cont_can_yield(&g_cont) && - (system_get_time() - g_micros_at_task_start) > interval_us) + if (cont_can_yield(g_pcont) && + (system_get_time() - s_micros_at_task_start) > interval_us) { yield(); } @@ -125,9 +128,9 @@ static void loop_wrapper() { static void loop_task(os_event_t *events) { (void) events; - g_micros_at_task_start = system_get_time(); - cont_run(&g_cont, &loop_wrapper); - if (cont_check(&g_cont) != 0) { + s_micros_at_task_start = system_get_time(); + cont_run(g_pcont, &loop_wrapper); + if (cont_check(g_pcont) != 0) { panic(); } } @@ -145,6 +148,22 @@ void init_done() { esp_schedule(); } +/* This is the entry point of the application. + * It gets called on the default stack, which grows down from the top + * of DRAM area. + * .bss has not been zeroed out yet, but .data and .rodata are in place. + * Cache is not enabled, so only ROM and IRAM functions can be called. + * Peripherals (except for SPI0 and UART0) are not initialized. + * This function does not return. + */ +extern "C" void ICACHE_RAM_ATTR app_entry(void) +{ + /* Allocate continuation context on this stack, and save pointer to it. */ + cont_t s_cont __attribute__((aligned(16))); + g_pcont = &s_cont; + /* Call the entry point of the SDK code. */ + call_user_start(); +} extern "C" void user_init(void) { struct rst_info *rtc_info_ptr = system_get_rst_info(); @@ -156,10 +175,10 @@ extern "C" void user_init(void) { initVariant(); - cont_init(&g_cont); + cont_init(g_pcont); ets_task(loop_task, - LOOP_TASK_PRIORITY, g_loop_queue, + LOOP_TASK_PRIORITY, s_loop_queue, LOOP_QUEUE_SIZE); system_init_done_cb(&init_done); diff --git a/cores/esp8266/core_esp8266_postmortem.c b/cores/esp8266/core_esp8266_postmortem.c index 83976918a3..3878cf1b9d 100644 --- a/cores/esp8266/core_esp8266_postmortem.c +++ b/cores/esp8266/core_esp8266_postmortem.c @@ -32,7 +32,7 @@ extern void __real_system_restart_local(); -extern cont_t g_cont; +extern cont_t* g_pcont; // These will be pointers to PROGMEM const strings static const char* s_panic_file = 0; @@ -131,8 +131,8 @@ void __wrap_system_restart_local() { ets_printf_P("\nSoft WDT reset\n"); } - uint32_t cont_stack_start = (uint32_t) &(g_cont.stack); - uint32_t cont_stack_end = (uint32_t) g_cont.stack_end; + uint32_t cont_stack_start = (uint32_t) &(g_pcont->stack); + uint32_t cont_stack_end = (uint32_t) g_pcont->stack_end; uint32_t stack_end; // amount of stack taken by interrupt or exception handler diff --git a/cores/esp8266/libc_replacements.c b/cores/esp8266/libc_replacements.c index 1d7c3f9f2d..fe111ba4cb 100644 --- a/cores/esp8266/libc_replacements.c +++ b/cores/esp8266/libc_replacements.c @@ -122,39 +122,7 @@ void _exit(int status) { abort(); } -#if 0 - -int ICACHE_RAM_ATTR printf(const char* format, ...) { - va_list arglist; - va_start(arglist, format); - int ret = ets_vprintf(ets_putc, format, arglist); - va_end(arglist); - return ret; -} - -int ICACHE_RAM_ATTR sprintf(char* buffer, const char* format, ...) { - int ret; - va_list arglist; - va_start(arglist, format); - ret = ets_vsprintf(buffer, format, arglist); - va_end(arglist); - return ret; -} - -int ICACHE_RAM_ATTR snprintf(char* buffer, size_t size, const char* format, ...) { - int ret; - va_list arglist; - va_start(arglist, format); - ret = ets_vsnprintf(buffer, size, format, arglist); - va_end(arglist); - return ret; -} - -int ICACHE_RAM_ATTR vprintf(const char * format, va_list arg) { - return ets_vprintf(ets_putc, format, arg); -} - -int ICACHE_RAM_ATTR vsnprintf(char * buffer, size_t size, const char * format, va_list arg) { - return ets_vsnprintf(buffer, size, format, arg); +int atexit(void (*func)()) { + (void) func; + return 0; } -#endif diff --git a/platform.txt b/platform.txt index 2b2c587447..e4de798c5b 100644 --- a/platform.txt +++ b/platform.txt @@ -37,7 +37,7 @@ compiler.c.flags=-c {compiler.warning_flags} -Os -g -Wpointer-arith -Wno-implici compiler.S.cmd=xtensa-lx106-elf-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD -mlongcalls -compiler.c.elf.flags=-g {compiler.warning_flags} -Os -nostdlib -Wl,--no-check-sections -u call_user_start {build.float} -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-L{compiler.libc.path}/lib" "-T{build.flash_ld}" -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,spi_flash_read +compiler.c.elf.flags=-g {compiler.warning_flags} -Os -nostdlib -Wl,--no-check-sections -u app_entry {build.float} -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-L{compiler.libc.path}/lib" "-T{build.flash_ld}" -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,spi_flash_read compiler.c.elf.cmd=xtensa-lx106-elf-gcc compiler.c.elf.libs=-lhal -lphy -lpp -lnet80211 {build.lwip_lib} -lwpa -lcrypto -lmain -lwps -laxtls -lespnow -lsmartconfig -lairkiss -lwpa2 -lstdc++ -lm -lc -lgcc diff --git a/tools/platformio-build.py b/tools/platformio-build.py index fbc2ef4ade..283a915836 100644 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -80,7 +80,8 @@ def scons_patched_match_splitext(path, suffixes=None): ], LINKFLAGS=[ "-Wl,-wrap,system_restart_local", - "-Wl,-wrap,spi_flash_read" + "-Wl,-wrap,spi_flash_read", + "-u,app_entry" ] ) diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index c4bb25990d..731e562b4f 100644 --- a/tools/sdk/include/ets_sys.h +++ b/tools/sdk/include/ets_sys.h @@ -215,6 +215,7 @@ int ets_vprintf(int (*print_function)(int), const char * format, va_list arg) __ int ets_putc(int); bool ets_task(ETSTask task, uint8 prio, ETSEvent *queue, uint8 qlen); bool ets_post(uint8 prio, ETSSignal sig, ETSParam par); +void ets_update_cpu_frequency(uint32_t ticks_per_us); #ifdef __cplusplus diff --git a/tools/sdk/ld/eagle.app.v6.common.ld b/tools/sdk/ld/eagle.app.v6.common.ld index ad1d10364c..0a7f1ba89f 100644 --- a/tools/sdk/ld/eagle.app.v6.common.ld +++ b/tools/sdk/ld/eagle.app.v6.common.ld @@ -9,7 +9,7 @@ PHDRS irom0_0_phdr PT_LOAD; } /* Default entry point: */ -ENTRY(call_user_start) +ENTRY(app_entry) EXTERN(_DebugExceptionVector) EXTERN(_DoubleExceptionVector) EXTERN(_KernelExceptionVector) @@ -75,6 +75,10 @@ SECTIONS _Pri_3_HandlerAddress = ABSOLUTE(.); _data_end = ABSOLUTE(.); } >dram0_0_seg :dram0_0_phdr + .noinit : ALIGN(4) + { + *(.noinit) + } >dram0_0_seg :dram0_0_phdr .irom0.text : ALIGN(4) { _irom0_text_start = ABSOLUTE(.); diff --git a/tools/sdk/ld/eagle.app.v6.common.ld.h b/tools/sdk/ld/eagle.app.v6.common.ld.h index 8b515c7e06..0d46fdc241 100644 --- a/tools/sdk/ld/eagle.app.v6.common.ld.h +++ b/tools/sdk/ld/eagle.app.v6.common.ld.h @@ -12,7 +12,7 @@ PHDRS /* Default entry point: */ -ENTRY(call_user_start) +ENTRY(app_entry) EXTERN(_DebugExceptionVector) EXTERN(_DoubleExceptionVector) EXTERN(_KernelExceptionVector) @@ -83,6 +83,11 @@ SECTIONS _Pri_3_HandlerAddress = ABSOLUTE(.); _data_end = ABSOLUTE(.); } >dram0_0_seg :dram0_0_phdr + + .noinit : ALIGN(4) + { + *(.noinit) + } >dram0_0_seg :dram0_0_phdr #ifdef VTABLES_IN_DRAM #include "eagle.app.v6.common.ld.vtables.h"