From 87cd181f5620d63d4d8e2f072ec7109b6d82391e Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Mon, 19 Aug 2019 14:29:28 +0200 Subject: [PATCH 1/2] cpu/esp32: use always newlib_syscalls_default Modules newlib and newlib_syscalls_default are now used by default. Conditional compilations for MODULE_NEWLIB_SYSCALLS_DEFAULT as well as alternative code are removed completely. --- cpu/esp32/Makefile.include | 2 +- cpu/esp32/startup.c | 4 -- cpu/esp32/syscalls.c | 100 ++----------------------------------- 3 files changed, 5 insertions(+), 101 deletions(-) diff --git a/cpu/esp32/Makefile.include b/cpu/esp32/Makefile.include index 850a724022..87bb89ff16 100644 --- a/cpu/esp32/Makefile.include +++ b/cpu/esp32/Makefile.include @@ -68,7 +68,7 @@ USEMODULE += esp_idf_driver USEMODULE += esp_idf_esp32 USEMODULE += esp_idf_soc USEMODULE += log -USEMODULE += newlib_syscalls_default +USEMODULE += newlib USEMODULE += periph USEMODULE += periph_adc_ctrl USEMODULE += periph_hwrng diff --git a/cpu/esp32/startup.c b/cpu/esp32/startup.c index b073a56d27..747fdc5e46 100644 --- a/cpu/esp32/startup.c +++ b/cpu/esp32/startup.c @@ -294,16 +294,12 @@ static NORETURN void IRAM system_init (void) /* init random number generator */ srand(hwrand()); - #if defined(MODULE_NEWLIB_SYSCALLS_DEFAULT) /* * initialization as it should be called from newlibc (includes the * execution of stdio_init) */ extern void _init(void); _init(); - #elif defined(MODULE_STDIO_UART) - stdio_init(); - #endif /* add SPI RAM to heap if enabled */ #if CONFIG_SPIRAM_SUPPORT && CONFIG_SPIRAM_BOOT_INIT diff --git a/cpu/esp32/syscalls.c b/cpu/esp32/syscalls.c index 99850fa964..cd484aed97 100644 --- a/cpu/esp32/syscalls.c +++ b/cpu/esp32/syscalls.c @@ -273,15 +273,6 @@ void* IRAM_ATTR __wrap__calloc_r(struct _reent *r, size_t count, size_t size) return result; } -#ifndef MODULE_NEWLIB_SYSCALLS_DEFAULT -/* this should not happen when MODULE_ESP_IDF_HEAP is activated since heap_caps - doesn't use _sbrk_r to allocate memory blocks */ -void* _sbrk_r (struct _reent *r, ptrdiff_t sz) -{ - _exit(ENOSYS); -} -#endif /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - #else /* MODULE_ESP_IDF_HEAP */ /* for compatibiliy with ESP-IDF heap functions */ @@ -304,48 +295,8 @@ void* IRAM heap_caps_realloc( void *ptr, size_t size ) extern uint8_t _eheap; /* end of heap (defined in esp32.common.ld) */ extern uint8_t _sheap; /* start of heap (defined in esp32.common.ld) */ +extern uint8_t *heap_top; /* current top of heap as defined in newlib_syscalls_default */ -#ifdef MODULE_NEWLIB_SYSCALLS_DEFAULT - -extern uint8_t *heap_top; -#define _cheap heap_top - -#else /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - -static uint8_t* _cheap = 0; /* last allocated chunk of heap */ - -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 %i byte allocated in %p .. %p, remaining %u\n", - __func__, incr, _cheap_old, _cheap, remaining); - #endif - - /* return allocated memory */ - return (caddr_t) _cheap_old; -} - -#endif /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ #endif /* MODULE_ESP_IDF_HEAP */ unsigned int IRAM get_free_heap_size (void) @@ -353,7 +304,7 @@ unsigned int IRAM get_free_heap_size (void) #if MODULE_ESP_IDF_HEAP return heap_caps_get_free_size( MALLOC_CAP_DEFAULT ); #else - return &_eheap - ((_cheap) ? _cheap : &_sheap); + return &_eheap - ((heap_top) ? heap_top : &_sheap); #endif } @@ -365,39 +316,6 @@ uint32_t esp_get_free_heap_size( void ) __attribute__((alias("get_free_heap_size * @name Other system functions */ -#ifndef MODULE_NEWLIB_SYSCALLS_DEFAULT - -int _getpid_r(struct _reent *r) -{ - return sched_active_pid; -} - -int _kill_r(struct _reent *r, int pid, int sig) -{ - DEBUG("%s: system function not yet implemented\n", __func__); - r->_errno = ESRCH; /* no such process */ - return -1; -} - -void _exit(int __status) -{ - ets_printf("#! exit %d: powering off\n", __status); - pm_off(); - while(1); -} - -clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms) -{ - ptms->tms_cstime = 0; - ptms->tms_cutime = 0; - ptms->tms_stime = system_get_time() / (US_PER_SEC / CLK_TCK); - ptms->tms_utime = 0; - - return ptms->tms_stime / MHZ; -} - -#endif /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - void _abort(void) { ets_printf("#! abort called: powering off\n"); @@ -441,8 +359,8 @@ static struct syscall_stub_table s_stub_table = ._kill_r = &_kill_r, ._times_r = &_times_r, - #ifdef MODULE_NEWLIB_SYSCALLS_DEFAULT ._gettimeofday_r = _gettimeofday_r, + ._open_r = &_open_r, ._close_r = &_close_r, ._lseek_r = (int (*)(struct _reent *r, int, int, int))&_lseek_r, @@ -451,17 +369,6 @@ static struct syscall_stub_table s_stub_table = ._write_r = (int (*)(struct _reent *r, int, const void *, int))&_write_r, ._read_r = (int (*)(struct _reent *r, int, void *, int))&_read_r, ._unlink_r = &_unlink_r, - #else /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ - ._gettimeofday_r = (int (*)(struct _reent *r, struct timeval *, void *))&_no_sys_func, - ._open_r = (int (*)(struct _reent *r, const char *, int, int))&_no_sys_func, - ._close_r = (int (*)(struct _reent *r, int))&_no_sys_func, - ._lseek_r = (int (*)(struct _reent *r, int, int, int))&_no_sys_func, - ._fstat_r = (int (*)(struct _reent *r, int, struct stat *))&_no_sys_func, - ._stat_r = (int (*)(struct _reent *r, const char*, struct stat *))&_no_sys_func, - ._write_r = (int (*)(struct _reent *r, int, const void *, int))&_no_sys_func, - ._read_r = (int (*)(struct _reent *r, int, void *, int))&_no_sys_func, - ._unlink_r = (int (*)(struct _reent *r, const char*))&_no_sys_func, - #endif /* MODULE_NEWLIB_SYSCALLS_DEFAULT */ ._link_r = (int (*)(struct _reent *r, const char*, const char*))&_no_sys_func, ._rename_r = (int (*)(struct _reent *r, const char*, const char*))&_no_sys_func, @@ -475,6 +382,7 @@ static struct syscall_stub_table s_stub_table = ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, ._lock_release = &_lock_release, ._lock_release_recursive = &_lock_release_recursive, + #if CONFIG_NEWLIB_NANO_FORMAT ._printf_float = &_printf_float, ._scanf_float = &_scanf_float, From bf331bd54b51d58a071e67fb1d9664c70b590fd4 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Mon, 19 Aug 2019 15:09:43 +0200 Subject: [PATCH 2/2] cpu/esp32: use printf/puts from newlib Initializing the stdio file descriptors in global reent structure with newlib fake stdio file descriptors led to the problem that newlib stdio functions printf and puts were not working since they can't operate on these fake stdio file descriptors. Therefore, this initialization was removed. Now, the real stdio file descriptors as created automatically by newlib are used. Specific functions `printf`, `puts`, `getchar`and `putchar` are not required any longer and are removed now. --- cpu/esp32/Makefile.include | 5 --- cpu/esp32/include/syscalls.h | 3 -- cpu/esp32/log_module.c | 2 +- cpu/esp32/startup.c | 6 --- cpu/esp32/syscalls.c | 55 ---------------------------- cpu/esp32/vendor/esp-idf/esp_funcs.c | 28 -------------- 6 files changed, 1 insertion(+), 98 deletions(-) diff --git a/cpu/esp32/Makefile.include b/cpu/esp32/Makefile.include index 87bb89ff16..fdf445a7c0 100644 --- a/cpu/esp32/Makefile.include +++ b/cpu/esp32/Makefile.include @@ -142,11 +142,6 @@ LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp32.rom.ld LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp32.rom.nanofmt.ld LINKFLAGS += -nostdlib -lgcc -Wl,-gc-sections -ifneq (,$(filter stdio_uart,$(USEMODULE))) - LINKFLAGS += -Wl,-wrap,putchar - LINKFLAGS += -Wl,-wrap,getchar -endif - # The ELFFILE is the base one used for flashing FLASHFILE ?= $(ELFFILE) diff --git a/cpu/esp32/include/syscalls.h b/cpu/esp32/include/syscalls.h index 0151453b70..038492d2cb 100644 --- a/cpu/esp32/include/syscalls.h +++ b/cpu/esp32/include/syscalls.h @@ -35,9 +35,6 @@ extern "C" { /** Necessary initializations of system call functions */ void syscalls_init (void); -/** System standard printf function */ -int printf(const char* format, ...); - /** Determine free heap size */ unsigned int get_free_heap_size (void); diff --git a/cpu/esp32/log_module.c b/cpu/esp32/log_module.c index 9d1659e273..b90b26850f 100644 --- a/cpu/esp32/log_module.c +++ b/cpu/esp32/log_module.c @@ -25,7 +25,7 @@ #include "log.h" #include "syscalls.h" -extern char _printf_buf[PRINTF_BUFSIZ]; +char _printf_buf[PRINTF_BUFSIZ]; bool _new_line = true; void log_write(unsigned level, const char *format, ...) diff --git a/cpu/esp32/startup.c b/cpu/esp32/startup.c index 747fdc5e46..1b85a1e041 100644 --- a/cpu/esp32/startup.c +++ b/cpu/esp32/startup.c @@ -279,12 +279,6 @@ static NORETURN void IRAM system_init (void) /* Disable the hold flag of all RTC GPIO pins */ RTCCNTL.hold_force.val = 0; - /* initialize newlib data structure */ - esp_reent_init(_GLOBAL_REENT); - _GLOBAL_REENT->_stdin = (FILE*) &__sf_fake_stdin; - _GLOBAL_REENT->_stdout = (FILE*) &__sf_fake_stdout; - _GLOBAL_REENT->_stderr = (FILE*) &__sf_fake_stderr; - /* execute constructors */ do_global_ctors(); diff --git a/cpu/esp32/syscalls.c b/cpu/esp32/syscalls.c index cd484aed97..4691564b83 100644 --- a/cpu/esp32/syscalls.c +++ b/cpu/esp32/syscalls.c @@ -64,61 +64,6 @@ #define MHZ 1000000UL -#ifdef MODULE_STDIO_UART -#include "stdio_uart.h" - -int IRAM __wrap_putchar(int c) -{ - char tmp = c; - if (stdio_write(&tmp, 1) > 0) { - return c; - } - return -EOF; -} - -int IRAM __wrap_getchar(void) -{ - char tmp; - if (stdio_read(&tmp, 1) > 0) { - return tmp; - } - return -EOF; -} -#endif /* MODULE_STDIO_UART */ - -int IRAM puts(const char *s) -{ - if (!s) { - return EOF; - } - int len = strlen(s); - for (int i = 0; i < len; i++) { - __wrap_putchar(s[i]); - } - __wrap_putchar('\n'); - return len; -} - -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) { - for (int i = 0; i < ret; i++) { - __wrap_putchar(_printf_buf[i]); - } - } - - va_end(arglist); - - return ret; -} - #ifndef MODULE_PTHREAD #define PTHREAD_CANCEL_DISABLE 1 diff --git a/cpu/esp32/vendor/esp-idf/esp_funcs.c b/cpu/esp32/vendor/esp-idf/esp_funcs.c index 9f929d0756..204eaea107 100644 --- a/cpu/esp32/vendor/esp-idf/esp_funcs.c +++ b/cpu/esp32/vendor/esp-idf/esp_funcs.c @@ -50,34 +50,6 @@ #include "syscalls.h" -/* This function is not part on newlib API, it is defined in libc/stdio/local.h - * There is no nice way to get __cleanup member populated while avoiding __sinit, - * so extern declaration is used here. - */ -extern void _cleanup_r(struct _reent* r); - -/** - * This is the replacement for newlib's _REENT_INIT_PTR and __sinit. - * The problem with __sinit is that it allocates three FILE structures - * (stdin, stdout, stderr). Having individual standard streams for each task - * is a bit too much on a small embedded system. So we point streams - * to the streams of the global struct _reent, which are initialized in - * startup code. - */ -void IRAM_ATTR esp_reent_init(struct _reent* r) -{ - memset(r, 0, sizeof(*r)); - r->_stdout = _GLOBAL_REENT->_stdout; - r->_stderr = _GLOBAL_REENT->_stderr; - r->_stdin = _GLOBAL_REENT->_stdin; - r->__cleanup = &_cleanup_r; - r->__sdidinit = 1; - r->__sglue._next = NULL; - r->__sglue._niobs = 0; - r->__sglue._iobs = NULL; - r->_current_locale = "C"; -} - /* source: /path/to/esp-idf/components/esp32/panic.c */ void IRAM_ATTR esp_panic_wdt_stop (void) {