diff --git a/components/libc/Kconfig b/components/libc/Kconfig index 4506001d428..a6000295e7d 100644 --- a/components/libc/Kconfig +++ b/components/libc/Kconfig @@ -2,7 +2,8 @@ menu "POSIX layer and C standard library" config RT_USING_LIBC bool "Enable libc APIs from toolchain" - default y + select RT_USING_HEAP + default n if RT_USING_LIBC config RT_LIBC_USING_TIME diff --git a/components/libc/compilers/armlibc/mem_std.c b/components/libc/compilers/armlibc/mem_std.c index fbfd17eee16..f8a81c78734 100644 --- a/components/libc/compilers/armlibc/mem_std.c +++ b/components/libc/compilers/armlibc/mem_std.c @@ -4,40 +4,68 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * 2014-08-03 bernard Add file header. + * Date Author Notes + * 2014-08-03 bernard Add file header + * 2021-11-13 Meco Man implement no-heap warning */ #include #include -#ifdef RT_USING_HEAP +#ifndef RT_USING_HEAP +#define DBG_TAG "armlibc.mem" +#define DBG_LVL DBG_INFO +#include + +#define _NO_HEAP_ERROR() do{LOG_E("Please enable RT_USING_HEAP");\ + RT_ASSERT(0);\ + }while(0) +#endif /* RT_USING_HEAP */ #ifdef __CC_ARM /* avoid the heap and heap-using library functions supplied by arm */ #pragma import(__use_no_heap) -#endif +#endif /* __CC_ARM */ void *malloc(size_t n) { +#ifdef RT_USING_HEAP return rt_malloc(n); +#else + _NO_HEAP_ERROR(); + return RT_NULL; +#endif } RTM_EXPORT(malloc); void *realloc(void *rmem, size_t newsize) { +#ifdef RT_USING_HEAP return rt_realloc(rmem, newsize); +#else + _NO_HEAP_ERROR(); + return RT_NULL; +#endif } RTM_EXPORT(realloc); void *calloc(size_t nelem, size_t elsize) { +#ifdef RT_USING_HEAP return rt_calloc(nelem, elsize); +#else + _NO_HEAP_ERROR(); + return RT_NULL; +#endif } RTM_EXPORT(calloc); void free(void *rmem) { +#ifdef RT_USING_HEAP rt_free(rmem); +#else + _NO_HEAP_ERROR(); +#endif } RTM_EXPORT(free); -#endif diff --git a/components/libc/compilers/armlibc/syscalls.c b/components/libc/compilers/armlibc/syscalls.c index 62657a4b649..b6448f21653 100644 --- a/components/libc/compilers/armlibc/syscalls.c +++ b/components/libc/compilers/armlibc/syscalls.c @@ -144,38 +144,48 @@ int _sys_close(FILEHANDLE fh) */ int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode) { -#ifdef RT_USING_POSIX_STDIO +#ifdef RT_USING_POSIX int size; if (fh == STDIN) { +#ifdef RT_USING_POSIX_STDIO if (libc_stdio_get_console() < 0) { LOG_W("Do not invoke standard output before initializing libc"); - return 0; + return 0; /* error, but keep going */ } size = read(STDIN_FILENO, buf, len); - return len - size; + return 0; /* success */ +#else + return 0; /* error */ +#endif } - else if ((fh == STDOUT) || (fh == STDERR)) + else if (fh == STDOUT || fh == STDERR) { return 0; /* error */ } - - size = read(fh, buf, len); - if (size >= 0) - return len - size; else - return 0; /* error */ + { + size = read(fh, buf, len); + if (size >= 0) + return len - size; /* success */ + else + return 0; /* error */ + } #else return 0; /* error */ -#endif /* RT_USING_POSIX_STDIO */ +#endif /* RT_USING_POSIX */ } /* * Write to a file. Returns 0 on success, negative on error, and * the number of characters _not_ written on partial success. * `mode' exists for historical reasons and must be ignored. + * The return value is either: + * A positive number representing the number of characters not written + * (so any nonzero return value denotes a failure of some sort). + * A negative number indicating an error. */ int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode) { @@ -183,39 +193,36 @@ int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode) int size; #endif /* RT_USING_POSIX */ - if ((fh == STDOUT) || (fh == STDERR)) + if (fh == STDOUT || fh == STDERR) { -#ifdef RT_USING_POSIX_STDIO - if (libc_stdio_get_console() < 0) - { - LOG_W("Do not invoke standard input before initializing libc"); - return 0; - } - size = write(STDOUT_FILENO, buf, len); - return len - size; -#elif defined(RT_USING_CONSOLE) - if (rt_console_get_device()) +#ifdef RT_USING_CONSOLE + rt_device_t console; + console = rt_console_get_device(); + if (console) { - rt_device_write(rt_console_get_device(), -1, buf, len); + rt_device_write(console, -1, buf, len); } - + return 0; /* success */ +#else return 0; /* error */ -#endif /* RT_USING_POSIX_STDIO */ +#endif /* RT_USING_CONSOLE */ } else if (fh == STDIN) { return 0; /* error */ } - -#ifdef RT_USING_POSIX - size = write(fh, buf, len); - if (size >= 0) - return len - size; else - return 0; /* error */ + { +#ifdef RT_USING_POSIX + size = write(fh, buf, len); + if (size >= 0) + return 0; /* success */ + else + return 0; /* error */ #else - return 0; + return 0; /* error */ #endif /* RT_USING_POSIX */ + } } /* diff --git a/components/libc/compilers/dlib/syscall_close.c b/components/libc/compilers/dlib/syscall_close.c index 2897c2418a0..aef9673153f 100644 --- a/components/libc/compilers/dlib/syscall_close.c +++ b/components/libc/compilers/dlib/syscall_close.c @@ -8,10 +8,16 @@ * 2015-01-28 Bernard first version */ #include -#include +#include #include +/* + * The "__close" function should close the file corresponding to + * "handle". It should return 0 on success and nonzero on failure. + */ + #pragma module_name = "?__close" + int __close(int handle) { if (handle == _LLIO_STDOUT || diff --git a/components/libc/compilers/dlib/syscall_lseek.c b/components/libc/compilers/dlib/syscall_lseek.c index 4ea55ef1c38..b1547f699eb 100644 --- a/components/libc/compilers/dlib/syscall_lseek.c +++ b/components/libc/compilers/dlib/syscall_lseek.c @@ -8,10 +8,25 @@ * 2015-01-28 Bernard first version */ #include -#include +#include #include +/* + * The "__lseek" function makes the next file operation (__read or + * __write) act on a new location. The parameter "whence" specifies + * how the "offset" parameter should be interpreted according to the + * following table: + * + * 0 (=SEEK_SET) - Goto location "offset". + * 1 (=SEEK_CUR) - Go "offset" bytes from the current location. + * 2 (=SEEK_END) - Go to "offset" bytes from the end. + * + * This function should return the current file position, or -1 on + * failure. + */ + #pragma module_name = "?__lseek" + long __lseek(int handle, long offset, int whence) { if (handle == _LLIO_STDOUT || diff --git a/components/libc/compilers/dlib/syscall_mem.c b/components/libc/compilers/dlib/syscall_mem.c index 9c6de64455f..74b960f0b92 100644 --- a/components/libc/compilers/dlib/syscall_mem.c +++ b/components/libc/compilers/dlib/syscall_mem.c @@ -6,27 +6,55 @@ * Change Logs: * Date Author Notes * 2015-01-28 Bernard first version + * 2021-11-13 Meco Man implement no-heap warning */ #include +#include -#ifdef RT_USING_HEAP -void *malloc(rt_size_t n) +#ifndef RT_USING_HEAP +#define DBG_TAG "dlib.syscall_mem" +#define DBG_LVL DBG_INFO +#include +#define _NO_HEAP_ERROR() do{LOG_E("Please enable RT_USING_HEAP");\ + RT_ASSERT(0);\ + }while(0) +#endif /* RT_USING_HEAP */ + +void *malloc(size_t n) { +#ifdef RT_USING_HEAP return rt_malloc(n); +#else + _NO_HEAP_ERROR(); + return RT_NULL; +#endif } -void *realloc(void *rmem, rt_size_t newsize) +void *realloc(void *rmem, size_t newsize) { +#ifdef RT_USING_HEAP return rt_realloc(rmem, newsize); +#else + _NO_HEAP_ERROR(); + return RT_NULL; +#endif } -void *calloc(rt_size_t nelem, rt_size_t elsize) +void *calloc(size_t nelem, size_t elsize) { +#ifdef RT_USING_HEAP return rt_calloc(nelem, elsize); +#else + _NO_HEAP_ERROR(); + return RT_NULL; +#endif } void free(void *rmem) { +#ifdef RT_USING_HEAP rt_free(rmem); -} +#else + _NO_HEAP_ERROR(); #endif +} diff --git a/components/libc/compilers/dlib/syscall_open.c b/components/libc/compilers/dlib/syscall_open.c index 8fb3c3a11f8..3336bc8885d 100644 --- a/components/libc/compilers/dlib/syscall_open.c +++ b/components/libc/compilers/dlib/syscall_open.c @@ -9,9 +9,14 @@ */ #include -#include +#include #include +/* + * The "__open" function opens the file named "filename" as specified + * by "mode". + */ + #pragma module_name = "?__open" int __open(const char *filename, int mode) diff --git a/components/libc/compilers/dlib/syscall_read.c b/components/libc/compilers/dlib/syscall_read.c index c926c577b58..e88f88ead43 100644 --- a/components/libc/compilers/dlib/syscall_read.c +++ b/components/libc/compilers/dlib/syscall_read.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #ifdef RT_USING_POSIX_STDIO #include "libc.h" @@ -19,20 +19,36 @@ #define DBG_LVL DBG_INFO #include +/* + * The "__read" function reads a number of bytes, at most "size" into + * the memory area pointed to by "buffer". It returns the number of + * bytes read, 0 at the end of the file, or _LLIO_ERROR if failure + * occurs. + * + * The template implementation below assumes that the application + * provides the function "MyLowLevelGetchar". It should return a + * character value, or -1 on failure. + */ + #pragma module_name = "?__read" + size_t __read(int handle, unsigned char *buf, size_t len) { -#ifdef RT_USING_POSIX_STDIO +#ifdef RT_USING_POSIX int size; if (handle == _LLIO_STDIN) { +#ifdef RT_USING_POSIX_STDIO if (libc_stdio_get_console() < 0) { LOG_W("Do not invoke standard input before initializing libc"); - return 0; + return 0; /* error, but keep going */ } - return read(STDIN_FILENO, buf, len); + return read(STDIN_FILENO, buf, len); /* return the length of the data read */ +#else + return _LLIO_ERROR; +#endif /* RT_USING_POSIX_STDIO */ } else if ((handle == _LLIO_STDOUT) || (handle == _LLIO_STDERR)) { @@ -40,7 +56,7 @@ size_t __read(int handle, unsigned char *buf, size_t len) } size = read(handle, buf, len); - return size; + return size; /* return the length of the data read */ #else return _LLIO_ERROR; #endif /* RT_USING_POSIX */ diff --git a/components/libc/compilers/dlib/syscall_remove.c b/components/libc/compilers/dlib/syscall_remove.c index 05bfbb67ae4..cf6541132ac 100644 --- a/components/libc/compilers/dlib/syscall_remove.c +++ b/components/libc/compilers/dlib/syscall_remove.c @@ -8,15 +8,21 @@ * 2015-01-28 Bernard first version */ #include -#include +#include #include +/* + * The "remove" function should remove the file named "filename". It + * should return 0 on success and nonzero on failure. + */ + #pragma module_name = "?remove" -int remove(const char *val) + +int remove(const char *filename) { #ifdef RT_USING_POSIX - return unlink(val); + return unlink(filename); #else - return -1; + return _LLIO_ERROR; #endif /* RT_USING_POSIX */ } diff --git a/components/libc/compilers/dlib/syscall_write.c b/components/libc/compilers/dlib/syscall_write.c index 72bac6ba49a..9a7707e9d36 100644 --- a/components/libc/compilers/dlib/syscall_write.c +++ b/components/libc/compilers/dlib/syscall_write.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #ifdef RT_USING_POSIX_STDIO #include "libc.h" @@ -19,6 +19,20 @@ #define DBG_LVL DBG_INFO #include +/* + * The "__write" function should output "size" number of bytes from + * "buffer" in some application-specific way. It should return the + * number of characters written, or _LLIO_ERROR on failure. + * + * If "buffer" is zero then __write should perform flushing of + * internal buffers, if any. In this case "handle" can be -1 to + * indicate that all handles should be flushed. + * + * The template implementation below assumes that the application + * provides the function "MyLowLevelPutchar". It should return the + * character written, or -1 on failure. + */ + #pragma module_name = "?__write" size_t __write(int handle, const unsigned char *buf, size_t len) @@ -29,36 +43,31 @@ size_t __write(int handle, const unsigned char *buf, size_t len) if ((handle == _LLIO_STDOUT) || (handle == _LLIO_STDERR)) { -#ifdef RT_USING_POSIX_STDIO - if (libc_stdio_get_console() < 0) - { - LOG_W("Do not invoke standard output before initializing libc"); - return 0; - } - return write(STDOUT_FILENO, (void*)buf, len); -#elif defined(RT_USING_CONSOLE) +#ifdef RT_USING_CONSOLE rt_device_t console_device; console_device = rt_console_get_device(); - if (console_device != 0) + if (console_device) { rt_device_write(console_device, 0, buf, len); } - return len; + return len; /* return the length of the data written */ #else return _LLIO_ERROR; -#endif /* RT_USING_POSIX */ +#endif /* RT_USING_CONSOLE */ } else if (handle == _LLIO_STDIN) { return _LLIO_ERROR; } - + else + { #ifdef RT_USING_POSIX - size = write(handle, buf, len); - return size; + size = write(handle, buf, len); + return size; /* return the length of the data written */ #else - return _LLIO_ERROR; + return _LLIO_ERROR; #endif /* RT_USING_POSIX */ + } } diff --git a/components/libc/compilers/gcc/newlib/syscalls.c b/components/libc/compilers/gcc/newlib/syscalls.c index e957aaf0037..f3a2f5bfcf0 100644 --- a/components/libc/compilers/gcc/newlib/syscalls.c +++ b/components/libc/compilers/gcc/newlib/syscalls.c @@ -80,7 +80,7 @@ void _free_r (struct _reent *ptr, void *addr) void * _sbrk_r(struct _reent *ptr, ptrdiff_t incr) { - LOG_E("Please enable RT_USING_HEAP or RT_USING_LIBC"); + LOG_E("Please enable RT_USING_HEAP"); RT_ASSERT(0); return RT_NULL; } @@ -109,7 +109,12 @@ int _getpid_r(struct _reent *ptr) int _close_r(struct _reent *ptr, int fd) { +#ifdef RT_USING_POSIX return close(fd); +#else + ptr->_errno = ENOTSUP; + return -1; +#endif } int _execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env) @@ -216,13 +221,27 @@ int _open_r(struct _reent *ptr, const char *file, int flags, int mode) _ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) { -#ifdef RT_USING_POSIX_STDIO +#ifdef RT_USING_POSIX _ssize_t rc; - if (libc_stdio_get_console() < 0 && fd == STDIN_FILENO) + if (fd == STDIN_FILENO) { - LOG_W("Do not invoke standard input before initializing libc"); - return 0; +#ifdef RT_USING_POSIX_STDIO + if (libc_stdio_get_console() < 0) + { + LOG_W("Do not invoke standard input before initializing libc"); + return 0; + } +#else + ptr->_errno = ENOTSUP; + return -1; +#endif /* RT_USING_POSIX_STDIO */ + } + else if (fd == STDOUT_FILENO || fd == STDERR_FILENO) + { + ptr->_errno = ENOTSUP; + return -1; } + rc = read(fd, buf, nbytes); return rc; #else @@ -271,27 +290,34 @@ _ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) { #ifdef RT_USING_POSIX _ssize_t rc; -#ifdef RT_USING_POSIX_STDIO - if (libc_stdio_get_console() < 0 && fd == STDOUT_FILENO) - { - LOG_W("Do not invoke standard output before initializing libc"); - return 0; - } -#endif /* RT_USING_POSIX_STDIO */ - rc = write(fd, buf, nbytes); - return rc; -#elif defined(RT_USING_CONSOLE) - if (STDOUT_FILENO == fd) +#endif /* RT_USING_POSIX */ + + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { +#ifdef RT_USING_CONSOLE rt_device_t console; console = rt_console_get_device(); if (console) return rt_device_write(console, -1, buf, nbytes); +#else + ptr->_errno = ENOTSUP; + return -1; +#endif /* RT_USING_CONSOLE */ } -#endif /* RT_USING_POSIX */ + else if (fd == STDIN_FILENO) + { + ptr->_errno = ENOTSUP; + return -1; + } + +#ifdef RT_USING_POSIX + rc = write(fd, buf, nbytes); + return rc; +#else ptr->_errno = ENOTSUP; return -1; +#endif /* RT_USING_POSIX */ } /* for exit() and abort() */