From ae8afaf42ea09ea09949750285a6bf259bf25d68 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 31 Aug 2019 12:35:36 +0200 Subject: [PATCH 1/5] cpu/esp8266: remove overridden stdio functions The overridden stdio functions `puts`, `putchar` and `printf` were removed. Instead, the corresponding newlib functions are always used. Using the newlib functions fixes output conflicts when using `f *` functions like `fprintf`,` fputs`, ... with `stdout` as the file parameter. --- cpu/esp8266/sdk/main.c | 2 +- cpu/esp8266/syscalls.c | 36 ------------------------------------ 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/cpu/esp8266/sdk/main.c b/cpu/esp8266/sdk/main.c index f88a815009..3c62ed12bb 100644 --- a/cpu/esp8266/sdk/main.c +++ b/cpu/esp8266/sdk/main.c @@ -35,7 +35,7 @@ #include "sdk/main.h" #include "sdk/rom.h" -extern char* _printf_buf; +static char _printf_buf[PRINTF_BUFSIZ]; int IRAM os_printf_plus (const char* format, ...) { diff --git a/cpu/esp8266/syscalls.c b/cpu/esp8266/syscalls.c index c84efb62a3..7f40113b4b 100644 --- a/cpu/esp8266/syscalls.c +++ b/cpu/esp8266/syscalls.c @@ -52,42 +52,6 @@ #include "sdk/sdk.h" -int IRAM puts(const char * str) -{ - char c; - while ((c = *str) != 0) { - ets_putc(c); - ++str; - } - ets_putc('\n'); - return true; -} - -int IRAM putchar(int c) -{ - /* function is neccessary to avoid unproducable results */ - ets_putc(c); - return true; -} - -char _printf_buf[PRINTF_BUFSIZ]; - -int /* IRAM */ printf(const char* format, ...) -{ - va_list arglist; - va_start(arglist, format); - - int ret = vsnprintf(_printf_buf, PRINTF_BUFSIZ, format, arglist); - - if (ret > 0) { - ets_printf (_printf_buf); - } - - va_end(arglist); - - return ret; -} - #ifdef MODULE_ESP_SDK /** * Map memory management functions to SDK memory management functions. From 69a5cc753d28e6699053d4d6bfa2082a7dcc8c89 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 31 Aug 2019 13:29:21 +0200 Subject: [PATCH 2/5] cpu/esp8266: use always newlib stdio functions The modules `newlib, `newlib_syscalls_default` and `stdio_uart` are now used by default for output to the UART interface. This also reduces the dependency rules. --- cpu/esp8266/Makefile.dep | 31 ---------- cpu/esp8266/Makefile.include | 3 + cpu/esp8266/syscalls.c | 106 ----------------------------------- 3 files changed, 3 insertions(+), 137 deletions(-) diff --git a/cpu/esp8266/Makefile.dep b/cpu/esp8266/Makefile.dep index cc2422d6f6..f817b2f6ff 100644 --- a/cpu/esp8266/Makefile.dep +++ b/cpu/esp8266/Makefile.dep @@ -25,38 +25,7 @@ ifneq (, $(filter esp_wifi, $(USEMODULE))) USEMODULE += netdev_eth endif -ifneq (, $(filter lua, $(USEPKG))) - USEMODULE += newlib_syscalls_default - USEMODULE += xtimer -endif - -ifneq (, $(filter lwip%, $(USEMODULE))) - USEMODULE += newlib_syscalls_default -endif - ifneq (,$(filter ndn-riot,$(USEPKG))) USEMODULE += crypto USEMODULE += cipher_modes endif - -ifneq (, $(filter posix%, $(USEMODULE))) - USEMODULE += newlib_syscalls_default -endif - -ifneq (, $(filter shell, $(USEMODULE))) - USEMODULE += newlib_syscalls_default - USEMODULE += xtimer -endif - -ifneq (, $(filter xtimer, $(USEMODULE))) - USEMODULE += newlib_syscalls_default -endif - -ifneq (, $(filter vfs, $(USEMODULE))) - USEMODULE += newlib_syscalls_default - USEMODULE += xtimer -endif - -ifneq (, $(filter newlib_syscalls_default, $(USEMODULE))) - USEMODULE += stdio_uart -endif diff --git a/cpu/esp8266/Makefile.include b/cpu/esp8266/Makefile.include index 55915b0e5b..7460e9c8d0 100644 --- a/cpu/esp8266/Makefile.include +++ b/cpu/esp8266/Makefile.include @@ -61,10 +61,13 @@ PSEUDOMODULES += esp_spiffs USEMODULE += esp USEMODULE += mtd +USEMODULE += newlib +USEMODULE += newlib_syscalls_default USEMODULE += periph USEMODULE += ps USEMODULE += random USEMODULE += sdk +USEMODULE += stdio_uart USEMODULE += xtensa ifneq (, $(filter pthread, $(USEMODULE))) diff --git a/cpu/esp8266/syscalls.c b/cpu/esp8266/syscalls.c index 7f40113b4b..c903ea899a 100644 --- a/cpu/esp8266/syscalls.c +++ b/cpu/esp8266/syscalls.c @@ -339,54 +339,12 @@ void IRAM _lock_release_recursive(_lock_t *lock) rmutex_unlock ((rmutex_t*)*lock); } - -#ifdef MODULE_NEWLIB_SYSCALLS_DEFAULT - #define _cheap heap_top extern char *heap_top; extern char _eheap; /* end of heap (defined in esp8266.riot-os.app.ld) */ extern char _sheap; /* start of heap (defined in esp8266.riot-os.app.ld) */ -#else /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - -static uint8_t* _cheap = 0; /* last allocated chunk of heap */ -extern uint8_t _eheap; /* end of heap (defined in esp8266.riot-os.app.ld) */ -extern uint8_t _sheap; /* start of heap (defined in esp8266.riot-os.app.ld) */ - -void* IRAM _sbrk_r (struct _reent *r, ptrdiff_t incr) -{ - uint8_t* _cheap_old; - - /* initial _cheap */ - if (_cheap == NULL) { - _cheap = &_sheap; - } - - /* save old _cheap */ - _cheap_old = _cheap; - - /* check whether _cheap + incr overflows the heap */ - if (_cheap + incr >= &_eheap) { - r->_errno = ENOMEM; - return (caddr_t)-1; - } - - /* set new _cheap */ - _cheap += incr; - - #if ENABLE_DEBUG - uint32_t remaining = &_eheap - _cheap; - printf ("%s %lu byte allocated in %p .. %p, remaining %u\n", - __func__, incr, _cheap_old, _cheap, remaining); - #endif - - /* return allocated memory */ - return (void*) _cheap_old; -} - -#endif /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - unsigned int IRAM get_free_heap_size (void) { return (_cheap) ? &_eheap - _cheap : 0; @@ -402,70 +360,6 @@ void heap_stats(void) #endif /* MODULE_ESP_SDK */ -#if !defined(MODULE_NEWLIB_SYSCALLS_DEFAULT) - -NORETURN void _exit(int status) -{ - UNREACHABLE(); -} - -static int _no_sys_func (struct _reent *r, const char* f) -{ - LOG_ERROR("system function %s does not exist\n", f); - r->_errno = ENOSYS; - return -1; -} - -int _open_r(struct _reent *r, const char *path, int flag, int m) -{ - return _no_sys_func (r, __func__); -} - -int _close_r(struct _reent *r, int fd) -{ - return _no_sys_func (r, __func__); -} - -int _fstat_r(struct _reent *r, int fdes, struct stat *stat) -{ - return _no_sys_func (r, __func__); -} - -int _stat_r(struct _reent *r, const char *path, struct stat *buff) -{ - return _no_sys_func (r, __func__); -} - -int _lseek_r(struct _reent *r, int fdes, int off, int w) -{ - return _no_sys_func (r, __func__); -} - -int _write_r(struct _reent *r, int fd, const void *buff, size_t cnt) -{ - return _no_sys_func (r, __func__); -} - -int _read_r(struct _reent *r, int fd, void *buff, size_t cnt) -{ - return _no_sys_func (r, __func__); -} - -#include - -int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) -{ - (void) tz; - if (tv) { - uint32_t microseconds = system_get_time(); - tv->tv_sec = microseconds / 1000000; - tv->tv_usec = microseconds % 1000000; - } - return 0; -} - -#endif /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - int _rename_r (struct _reent *r, const char* old, const char* new) { DEBUG("%s: system function does not exist\n", __func__); From 646a173738bf27b16981facdbc2aaa0063b87d79 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 31 Aug 2019 13:33:45 +0200 Subject: [PATCH 3/5] cpu/esp8266: fix unresolved symbols To avoid unresolved symbols for unused functions during linking, compiler option `-ffunction-sections` is used now. Linker option `--warn-unresolved-symbols` is removed to get errors if required symbols cannot be resolved. --- cpu/esp8266/Makefile.include | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpu/esp8266/Makefile.include b/cpu/esp8266/Makefile.include index 7460e9c8d0..80667f74fc 100644 --- a/cpu/esp8266/Makefile.include +++ b/cpu/esp8266/Makefile.include @@ -85,7 +85,7 @@ INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/espressif CFLAGS += -DESP_OPEN_SDK -DSCHED_PRIO_LEVELS=32 -DCONTEXT_SWITCH_BY_INT CFLAGS += -Wno-unused-parameter -Wformat=0 CFLAGS += -mlongcalls -mtext-section-literals -CFLAGS += -fdata-sections -fzero-initialized-in-bss +CFLAGS += -ffunction-sections -fdata-sections -fzero-initialized-in-bss ASFLAGS += --longcalls --text-section-literals ifneq (, $(filter esp_sdk, $(USEMODULE))) @@ -135,7 +135,6 @@ endif LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/eagle.rom.addr.v6.ld LINKFLAGS += -nostdlib -lgcc -u ets_run -Wl,-gc-sections # -Wl,--print-gc-sections -LINKFLAGS += -Wl,--warn-unresolved-symbols # The ELFFILE is the base one used for flashing FLASHFILE ?= $(ELFFILE) From 7fe1056aa71a3113301f13a0104ecf601ec228b5 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Wed, 4 Sep 2019 14:39:49 +0200 Subject: [PATCH 4/5] cpu/esp8266: enable newlib with nano-formatted-io --- cpu/esp8266/Makefile.include | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/esp8266/Makefile.include b/cpu/esp8266/Makefile.include index 80667f74fc..7fbba01f7a 100644 --- a/cpu/esp8266/Makefile.include +++ b/cpu/esp8266/Makefile.include @@ -62,6 +62,7 @@ PSEUDOMODULES += esp_spiffs USEMODULE += esp USEMODULE += mtd USEMODULE += newlib +USEMODULE += newlib_nano USEMODULE += newlib_syscalls_default USEMODULE += periph USEMODULE += ps From 37ecb4fc5da3cd14d296c36f952ac8f7fad0e5b7 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Wed, 4 Sep 2019 14:52:13 +0200 Subject: [PATCH 5/5] cpu/esp8266: periph/uart FIFO resized to 1 byte UART FIFO must contain only 1 byte when newlib's `printf` function is used. Otherwise, outputs that are still not sent over UART are lost when `printf` is called asynchronousely. --- cpu/esp8266/periph/uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/esp8266/periph/uart.c b/cpu/esp8266/periph/uart.c index c4ee15d761..58a17e6440 100644 --- a/cpu/esp8266/periph/uart.c +++ b/cpu/esp8266/periph/uart.c @@ -127,7 +127,7 @@ void IRAM __uart_intr_handler (void *arg) } /* RX/TX FIFO capacity is 128 byte */ -#define UART_FIFO_MAX 127 +#define UART_FIFO_MAX 1 /* receive one data byte with wait */ static uint8_t IRAM __uart_rx_one_char (uart_t uart)