From e2345e4700b60aacc51b8789de73f26c691fd6ce Mon Sep 17 00:00:00 2001 From: Hugues Kamba Date: Sun, 15 Sep 2019 16:14:50 +0100 Subject: [PATCH] mbed-retarget: Make filehandles optional to reduce code size The retarget code allocates an array of FileHandle* for console and file handling (filehandles). A tiny target only needs a console (putc/getc). There is no need for file handling. The POSIX layer and the array of FileHandle* is not required for small targets that only need a console ; this code should be optionally compiled out if the configuration parameter `platform.stdio-console-only` is selected instead of `platform-stdio-buffered-serial`. --- platform/mbed_lib.json | 5 ++ platform/source/mbed_retarget.cpp | 109 +++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index b571f3781ba2..743d3006790a 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -16,6 +16,11 @@ "value": false }, + "stdio-console-only": { + "help": "Enable this instead of `stdio-buffered-serial` if filehandles are not required to access the serial interface as console to only to print.", + "value": false + }, + "stdio-baud-rate": { "help": "(Applies if target.console-uart is true.) Baud rate for stdio", "value": 9600 diff --git a/platform/source/mbed_retarget.cpp b/platform/source/mbed_retarget.cpp index 61adeeb0f906..5341430641e9 100644 --- a/platform/source/mbed_retarget.cpp +++ b/platform/source/mbed_retarget.cpp @@ -30,6 +30,7 @@ #include "platform/mbed_critical.h" #include "platform/mbed_poll.h" #include "drivers/UARTSerial.h" +#include "drivers/RawSerial.h" #include "hal/us_ticker_api.h" #include "hal/lp_ticker_api.h" #include @@ -104,6 +105,7 @@ extern const char __stderr_name[] = "/stderr"; unsigned char *mbed_heap_start = 0; uint32_t mbed_heap_size = 0; +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) /* newlib has the filehandle field in the FILE struct as a short, so * we can't just return a Filehandle* from _open and instead have to * put it in a filehandles array and return the index into that array @@ -112,12 +114,14 @@ static FileHandle *filehandles[OPEN_MAX] = { FILE_HANDLE_RESERVED, FILE_HANDLE_R static char stdio_in_prev[OPEN_MAX]; static char stdio_out_prev[OPEN_MAX]; static SingletonPtr filehandle_mutex; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) namespace mbed { void mbed_set_unbuffered_stream(std::FILE *_file); void remove_filehandle(FileHandle *file) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) filehandle_mutex->lock(); /* Remove all open filehandles for this */ for (unsigned int fh_i = 0; fh_i < sizeof(filehandles) / sizeof(*filehandles); fh_i++) { @@ -126,9 +130,11 @@ void remove_filehandle(FileHandle *file) } } filehandle_mutex->unlock(); +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } } +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #if DEVICE_SERIAL extern int stdio_uart_inited; extern serial_t stdio_uart; @@ -391,9 +397,11 @@ static int reserve_filehandle() return fh_i; } +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) int mbed::bind_to_fd(FileHandle *fh) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) int fildes = reserve_filehandle(); if (fildes < 0) { return fildes; @@ -404,10 +412,14 @@ int mbed::bind_to_fd(FileHandle *fh) stdio_out_prev[fildes] = 0; return fildes; +#else + return -1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } static int unbind_from_fd(int fd, FileHandle *fh) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) if (filehandles[fd] == fh) { filehandles[fd] = NULL; return 0; @@ -415,8 +427,12 @@ static int unbind_from_fd(int fd, FileHandle *fh) errno = EBADF; return -1; } +#else + return -1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } + #ifndef __IAR_SYSTEMS_ICC__ /* IAR provides fdopen itself */ extern "C" std::FILE *fdopen(int fildes, const char *mode) @@ -456,6 +472,40 @@ std::FILE *fdopen(FileHandle *fh, const char *mode) } } +#if MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY +/** Write the contents of a buffer to a serial interface + * + * + * * if blocking, block until all data is written + * * if no data can be written, and nonblocking set, return -EAGAIN + * * if some data can be written, and nonblocking set, write partial + * + * @param buffer The buffer to write from + * @param length The number of bytes to read + * @return The number of bytes written, negative error on failure + */ +static ssize_t mbed_serial_write(const void *buffer, size_t size) +{ + ssize_t ret = 0; + const unsigned char *buf = static_cast(buffer); + static RawSerial console( + STDIO_UART_TX, + STDIO_UART_RX, + MBED_CONF_PLATFORM_STDIO_BAUD_RATE + ); + + for (size_t i = 0; i < size; i++) { + ret = console.putc(buf[i]); + if (ret) { + break; + } + } + + return ret; +} +#endif // MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY + + /* @brief standard c library fopen() retargeting function. * * This function is invoked by the standard c library retargeting to handle fopen() @@ -469,6 +519,7 @@ std::FILE *fdopen(FileHandle *fh, const char *mode) * */ extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) #if !defined(MBED_CONF_RTOS_PRESENT) // valid only for mbed 2 @@ -516,8 +567,13 @@ extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags) } #endif return open(name, openflags_to_posix(openflags)); +#else + // Everything goes to the same output + return 1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) extern "C" int open(const char *name, int oflag, ...) { int fildes = reserve_filehandle(); @@ -554,12 +610,18 @@ extern "C" int open(const char *name, int oflag, ...) return fildes; } +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) extern "C" int PREFIX(_close)(FILEHANDLE fh) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) return close(fh); +#else + return 0; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) extern "C" int close(int fildes) { FileHandle *fhc = mbed_file_handle(fildes); @@ -588,6 +650,7 @@ static bool convert_crlf(int fd) return false; #endif } +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #if defined(__ICCARM__) extern "C" size_t __write(int fh, const unsigned char *buffer, size_t length) @@ -603,6 +666,7 @@ extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsign } #endif +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) if (length > SSIZE_MAX) { errno = EINVAL; return -1; @@ -669,11 +733,15 @@ extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsign #else return written; #endif + +#else + return mbed_serial_write(buffer, length); +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } extern "C" ssize_t write(int fildes, const void *buf, size_t length) { - +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) FileHandle *fhc = mbed_file_handle(fildes); if (fhc == NULL) { errno = EBADF; @@ -687,6 +755,9 @@ extern "C" ssize_t write(int fildes, const void *buf, size_t length) } else { return ret; } +#else + return mbed_serial_write(buf, length); +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) @@ -698,7 +769,11 @@ extern "C" void PREFIX(_exit)(int return_code) extern "C" void _ttywrch(int ch) { char c = ch; +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) write(STDOUT_FILENO, &c, 1); +#else + mbed_serial_write(&c, 1); +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } #endif @@ -710,6 +785,7 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int { #endif +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT) if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) { MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PROHIBITED_IN_ISR_CONTEXT), "Error - reading from a file in an ISR or critical section\r\n", fh); @@ -764,8 +840,13 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int #else return bytes_read; #endif +#else + // Not supported + return -1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) extern "C" ssize_t read(int fildes, void *buf, size_t length) { FileHandle *fhc = mbed_file_handle(fildes); @@ -782,7 +863,7 @@ extern "C" ssize_t read(int fildes, void *buf, size_t length) return ret; } } - +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #ifdef __ARMCC_VERSION extern "C" int PREFIX(_istty)(FILEHANDLE fh) @@ -795,6 +876,7 @@ extern "C" int _isatty(FILEHANDLE fh) extern "C" int isatty(int fildes) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) FileHandle *fhc = mbed_file_handle(fildes); if (fhc == NULL) { errno = EBADF; @@ -808,6 +890,10 @@ extern "C" int isatty(int fildes) } else { return tty; } +#else + // Is not attached to an interactive device + return 0; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } extern "C" @@ -819,6 +905,7 @@ long __lseek(int fh, long offset, int whence) int _lseek(FILEHANDLE fh, int offset, int whence) #endif { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #if defined(__ARMCC_VERSION) int whence = SEEK_SET; #endif @@ -832,8 +919,13 @@ int _lseek(FILEHANDLE fh, int offset, int whence) return -1; } return off; +#else + // Not supported + return -1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) extern "C" off_t lseek(int fildes, off_t offset, int whence) { FileHandle *fhc = mbed_file_handle(fildes); @@ -873,9 +965,11 @@ extern "C" int PREFIX(_ensure)(FILEHANDLE fh) return fsync(fh); } #endif +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) extern "C" int fsync(int fildes) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) FileHandle *fhc = mbed_file_handle(fildes); if (fhc == NULL) { errno = EBADF; @@ -889,11 +983,15 @@ extern "C" int fsync(int fildes) } else { return 0; } +#else + return -1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } #ifdef __ARMCC_VERSION extern "C" long PREFIX(_flen)(FILEHANDLE fh) { +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) FileHandle *fhc = mbed_file_handle(fh); if (fhc == NULL) { errno = EBADF; @@ -910,6 +1008,10 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh) return -1; } return size; +#else + // Not supported + return -1; +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) } // Do not compile this code for TFM secure target @@ -983,7 +1085,7 @@ extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uin #endif - +#if !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) extern "C" int _fstat(int fh, struct stat *st) { @@ -1060,6 +1162,7 @@ extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout) } return ret; } +#endif // !(MBED_CONF_PLATFORM_STDIO_CONSOLE_ONLY) namespace std { extern "C" int remove(const char *path)