From 194b8e420ae695af6fb968cd5cb5f65ae20d5b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oto=20Pet=C5=99=C3=ADk?= Date: Mon, 5 Dec 2016 18:40:40 +0100 Subject: [PATCH] Allow changing write function of stdout. Required for stdout redirection. Works on blocks, not chars - does _not_ use sdk_os_putc ! Should work even when linking with SPIFFS. --- core/include/stdout_redirect.h | 24 +++++++++++++++++ core/newlib_syscalls.c | 48 +++++++++++++++++++++++++++++----- extras/spiffs/esp_spiffs.c | 25 +++--------------- 3 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 core/include/stdout_redirect.h diff --git a/core/include/stdout_redirect.h b/core/include/stdout_redirect.h new file mode 100644 index 0000000..2179b5a --- /dev/null +++ b/core/include/stdout_redirect.h @@ -0,0 +1,24 @@ +/* + * Part of esp-open-rtos + * Copyright (C) 2016 Oto Petrik + * BSD Licensed as described in the file LICENSE + */ + +#ifndef _STDOUT_REDIRECT_H_ +#define _STDOUT_REDIRECT_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef long _WriteFunction(struct _reent *r, int fd, const char *ptr, int len ); + +void set_write_stdout(_WriteFunction *f); +_WriteFunction *get_write_stdout(); + +#ifdef __cplusplus +} +#endif + +#endif /* _STDOUT_REDIRECT_H_ */ diff --git a/core/newlib_syscalls.c b/core/newlib_syscalls.c index f526bea..45e6991 100644 --- a/core/newlib_syscalls.c +++ b/core/newlib_syscalls.c @@ -12,6 +12,7 @@ #include #include #include +#include extern void *xPortSupervisorStackPointer; @@ -41,12 +42,8 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr) } /* syscall implementation for stdio write to UART */ -__attribute__((weak)) long _write_r(struct _reent *r, int fd, const char *ptr, int len ) +__attribute__((weak)) long _write_stdout_r(struct _reent *r, int fd, const char *ptr, int len ) { - if(fd != r->_stdout->_file) { - r->_errno = EBADF; - return -1; - } for(int i = 0; i < len; i++) { /* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */ if(ptr[i] == '\r') @@ -58,6 +55,37 @@ __attribute__((weak)) long _write_r(struct _reent *r, int fd, const char *ptr, i return len; } +_WriteFunction *_current_stdout_write_r = &_write_stdout_r; + +void set_write_stdout(_WriteFunction *f) +{ + if (f != NULL) { + _current_stdout_write_r = f; + } else { + _current_stdout_write_r = &_write_stdout_r; + } +} + +_WriteFunction *get_write_stdout() +{ + return _current_stdout_write_r; +} + +/* default implementation, replace in a filesystem */ +__attribute__((weak)) long _write_filesystem_r(struct _reent *r, int fd, const char *ptr, int len ) +{ + r->_errno = EBADF; + return -1; +} + +__attribute__((weak)) long _write_r(struct _reent *r, int fd, const char *ptr, int len ) +{ + if(fd != r->_stdout->_file) { + return _write_filesystem_r(r, fd, ptr, len); + } + return _current_stdout_write_r(r, fd, ptr, len); +} + /* syscall implementation for stdio read from UART */ __attribute__((weak)) long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len) { @@ -71,11 +99,17 @@ __attribute__((weak)) long _read_stdin_r(struct _reent *r, int fd, char *ptr, in return i; } +/* default implementation, replace in a filesystem */ +__attribute__((weak)) long _read_filesystem_r( struct _reent *r, int fd, char *ptr, int len ) +{ + r->_errno = EBADF; + return -1; +} + __attribute__((weak)) long _read_r( struct _reent *r, int fd, char *ptr, int len ) { if(fd != r->_stdin->_file) { - r->_errno = EBADF; - return -1; + return _read_filesystem_r(r, fd, ptr, len); } return _read_stdin_r(r, fd, ptr, len); } diff --git a/extras/spiffs/esp_spiffs.c b/extras/spiffs/esp_spiffs.c index 96ec743..3d81218 100644 --- a/extras/spiffs/esp_spiffs.c +++ b/extras/spiffs/esp_spiffs.c @@ -125,32 +125,15 @@ int32_t esp_spiffs_mount() } // This implementation replaces implementation in core/newlib_syscals.c -long _write_r(struct _reent *r, int fd, const char *ptr, int len ) +long _write_filesystem_r(struct _reent *r, int fd, const char *ptr, int len ) { - if(fd != r->_stdout->_file) { - return SPIFFS_write(&fs, (spiffs_file)fd, (char*)ptr, len); - } - for(int i = 0; i < len; i++) { - /* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */ - if(ptr[i] == '\r') - continue; - if(ptr[i] == '\n') - uart_putc(0, '\r'); - uart_putc(0, ptr[i]); - } - return len; + return SPIFFS_write(&fs, (spiffs_file)fd, (char*)ptr, len); } -// This function is weakly defined in core/newlib_syscalls.c -long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len); - // This implementation replaces implementation in core/newlib_syscals.c -long _read_r( struct _reent *r, int fd, char *ptr, int len ) +long _read_filesystem_r( struct _reent *r, int fd, char *ptr, int len ) { - if(fd != r->_stdin->_file) { - return SPIFFS_read(&fs, (spiffs_file)fd, ptr, len); - } - return _read_stdin_r(r, fd, ptr, len); + return SPIFFS_read(&fs, (spiffs_file)fd, ptr, len); } int _open_r(struct _reent *r, const char *pathname, int flags, int mode)