Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move continuation stack from .bss onto sys stack #4622

Merged
merged 3 commits into from
Apr 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cores/esp8266/cont_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@

#include "cont.h"
#include <stddef.h>
#include <string.h>
#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);
Expand Down
73 changes: 46 additions & 27 deletions cores/esp8266/core_esp8266_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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)
Expand All @@ -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);
}
}

Expand All @@ -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();
}
Expand All @@ -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();
}
Expand All @@ -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();
}
}
Expand All @@ -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();
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions cores/esp8266/core_esp8266_postmortem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
38 changes: 3 additions & 35 deletions cores/esp8266/libc_replacements.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion platform.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion tools/platformio-build.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
)

Expand Down
1 change: 1 addition & 0 deletions tools/sdk/include/ets_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion tools/sdk/ld/eagle.app.v6.common.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(.);
Expand Down
7 changes: 6 additions & 1 deletion tools/sdk/ld/eagle.app.v6.common.ld.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ PHDRS


/* Default entry point: */
ENTRY(call_user_start)
ENTRY(app_entry)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
Expand Down Expand Up @@ -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"
Expand Down