diff options
| author | bernard <[email protected]> | 2017-10-10 17:12:03 +0800 |
|---|---|---|
| committer | bernard <[email protected]> | 2017-10-10 17:12:03 +0800 |
| commit | db88c0b6a23fa6d56094b6d6f5e9c3e577e9a88d (patch) | |
| tree | 2573ed87aa2c25f9bf8149d981b57e9be27a9050 /components/libc/compilers/newlib | |
| parent | 5c6a6e5db825905befa9ca903aa557ea3577b7af (diff) | |
[libc] Change libc stubs to compiler folder.
Diffstat (limited to 'components/libc/compilers/newlib')
| -rw-r--r-- | components/libc/compilers/newlib/SConscript | 18 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/libc.c | 56 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/libc.h | 21 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/libc_sym.c | 47 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/sys/dirent.h | 57 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/sys/fcntl.h | 18 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/sys/statfs.h | 13 | ||||
| -rw-r--r-- | components/libc/compilers/newlib/syscalls.c | 464 |
8 files changed, 694 insertions, 0 deletions
diff --git a/components/libc/compilers/newlib/SConscript b/components/libc/compilers/newlib/SConscript new file mode 100644 index 0000000000..574c2a8d1f --- /dev/null +++ b/components/libc/compilers/newlib/SConscript @@ -0,0 +1,18 @@ +from building import * + +src = Glob('*.c') +cwd = GetCurrentDir() + +CPPPATH = [cwd] +CPPDEFINES = ['RT_USING_NEWLIB'] + +# link with libc and libm: +# libm is a frequently used lib. Newlib is compiled with -ffunction-sections in +# recent GCC tool chains. The linker would just link in the functions that have +# been referenced. So setting this won't result in bigger text size. +LIBS = ['c', 'm'] + +group = DefineGroup('newlib', src, depend = ['RT_USING_LIBC'], + CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS) + +Return('group') diff --git a/components/libc/compilers/newlib/libc.c b/components/libc/compilers/newlib/libc.c new file mode 100644 index 0000000000..8f97e1c8b4 --- /dev/null +++ b/components/libc/compilers/newlib/libc.c @@ -0,0 +1,56 @@ +#include <rtthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/time.h> +#include "libc.h" + +#ifdef RT_USING_PTHREADS +#include <pthread.h> +#endif + +#ifdef RT_USING_DFS +#include <dfs_posix.h> + +#ifdef RT_USING_DFS_DEVFS +#include <devfs.h> +#endif + +#endif + +int libc_system_init(void) +{ +#ifdef RT_USING_DFS + int fd; + struct rt_device *console_dev; + +#ifndef RT_USING_DFS_DEVFS +#error Please enable devfs by defining RT_USING_DFS_DEVFS in rtconfig.h +#endif + + console_dev = rt_console_get_device(); + if (console_dev) + { + /* initialize console device */ + rt_console_init(console_dev->parent.name); + + /* open console as stdin/stdout/stderr */ + fd = open("/dev/console", O_RDONLY, 0); /* for stdin */ + fd = open("/dev/console", O_WRONLY, 0); /* for stdout */ + fd = open("/dev/console", O_WRONLY, 0); /* for stderr */ + + /* skip warning */ + fd = fd; + } +#endif + + /* set PATH and HOME */ + putenv("PATH=/bin"); + putenv("HOME=/home"); +#if defined RT_USING_PTHREADS && !defined RT_USING_COMPONENTS_INIT + pthread_system_init(); +#endif + + return 0; +} +INIT_COMPONENT_EXPORT(libc_system_init); diff --git a/components/libc/compilers/newlib/libc.h b/components/libc/compilers/newlib/libc.h new file mode 100644 index 0000000000..a4f342df33 --- /dev/null +++ b/components/libc/compilers/newlib/libc.h @@ -0,0 +1,21 @@ +#ifndef __RTT_LIBC_H__ +#define __RTT_LIBC_H__ + +#include <sys/time.h> + +#define MILLISECOND_PER_SECOND 1000UL +#define MICROSECOND_PER_SECOND 1000000UL +#define NANOSECOND_PER_SECOND 1000000000UL + +#define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) + +int libc_system_init(void); + +/* some time related function */ +int libc_set_time(const struct timespec *time); +int libc_get_time(struct timespec *time); +int libc_time_to_tick(const struct timespec *time); + +#endif diff --git a/components/libc/compilers/newlib/libc_sym.c b/components/libc/compilers/newlib/libc_sym.c new file mode 100644 index 0000000000..48e488f5d8 --- /dev/null +++ b/components/libc/compilers/newlib/libc_sym.c @@ -0,0 +1,47 @@ +#include <rtthread.h> +#include <rtm.h> + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +RTM_EXPORT(strcpy); +RTM_EXPORT(strncpy); +RTM_EXPORT(strlen); +RTM_EXPORT(strcat); +RTM_EXPORT(strstr); +RTM_EXPORT(strchr); +RTM_EXPORT(strcmp); +RTM_EXPORT(strtol); +RTM_EXPORT(strtoul); +RTM_EXPORT(strncmp); + +RTM_EXPORT(memcpy); +RTM_EXPORT(memcmp); +RTM_EXPORT(memmove); +RTM_EXPORT(memset); +RTM_EXPORT(memchr); + +RTM_EXPORT(putchar); +RTM_EXPORT(puts); +RTM_EXPORT(printf); +RTM_EXPORT(sprintf); +RTM_EXPORT(snprintf); + +RTM_EXPORT(fwrite); + +#include <time.h> +RTM_EXPORT(localtime); +RTM_EXPORT(time); + +#include <setjmp.h> +RTM_EXPORT(longjmp); +RTM_EXPORT(setjmp); + +RTM_EXPORT(exit); +RTM_EXPORT(abort); + +RTM_EXPORT(rand); + +#include <assert.h> +RTM_EXPORT(__assert_func); diff --git a/components/libc/compilers/newlib/sys/dirent.h b/components/libc/compilers/newlib/sys/dirent.h new file mode 100644 index 0000000000..2efc683579 --- /dev/null +++ b/components/libc/compilers/newlib/sys/dirent.h @@ -0,0 +1,57 @@ +#ifndef __RTT_DIRENT_H__ +#define __RTT_DIRENT_H__ + +#include <rtthread.h> + +/* +* dirent.h - format of directory entries + * Ref: http://www.opengroup.org/onlinepubs/009695399/basedefs/dirent.h.html + */ + +/* File types */ +#define FT_REGULAR 0 /* regular file */ +#define FT_SOCKET 1 /* socket file */ +#define FT_DIRECTORY 2 /* directory */ +#define FT_USER 3 /* user defined */ + +#define DT_UNKNOWN 0x00 +#define DT_REG 0x01 +#define DT_DIR 0x02 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_DIR_STRUCTURE +typedef struct +{ + int fd; /* directory file */ + char buf[512]; + int num; + int cur; +} DIR; +#endif + +#ifndef HAVE_DIRENT_STRUCTURE +struct dirent +{ + rt_uint8_t d_type; /* The type of the file */ + rt_uint8_t d_namlen; /* The length of the not including the terminating null file name */ + rt_uint16_t d_reclen; /* length of this record */ + char d_name[256]; /* The null-terminated file name */ +}; +#endif + +int closedir(DIR *); +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +int readdir_r(DIR *, struct dirent *, struct dirent **); +void rewinddir(DIR *); +void seekdir(DIR *, long int); +long telldir(DIR *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/libc/compilers/newlib/sys/fcntl.h b/components/libc/compilers/newlib/sys/fcntl.h new file mode 100644 index 0000000000..a53ca808b2 --- /dev/null +++ b/components/libc/compilers/newlib/sys/fcntl.h @@ -0,0 +1,18 @@ +#ifndef __RTT_FCNTL_H__ +#define __RTT_FCNTL_H__ + +/* Operation flags */ +#define O_RDONLY 0x0000000 +#define O_WRONLY 0x0000001 +#define O_RDWR 0x0000002 +#define O_ACCMODE 0x0000003 +#define O_CREAT 0x0000100 +#define O_EXCL 0x0000200 +#define O_TRUNC 0x0001000 +#define O_APPEND 0x0002000 +#define O_DIRECTORY 0x0200000 +#define O_BINARY 0x0008000 + +#include <unistd.h> + +#endif diff --git a/components/libc/compilers/newlib/sys/statfs.h b/components/libc/compilers/newlib/sys/statfs.h new file mode 100644 index 0000000000..95772b5ead --- /dev/null +++ b/components/libc/compilers/newlib/sys/statfs.h @@ -0,0 +1,13 @@ +#ifndef __RTT_STATFS_H__ +#define __RTT_STATFS_H__ + +#include <rtthread.h> + +struct statfs +{ + rt_size_t f_bsize; /* block size */ + rt_size_t f_blocks; /* total data blocks in file system */ + rt_size_t f_bfree; /* free blocks in file system */ +}; + +#endif diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c new file mode 100644 index 0000000000..ff09a4fe80 --- /dev/null +++ b/components/libc/compilers/newlib/syscalls.c @@ -0,0 +1,464 @@ +#include <reent.h> +#include <sys/errno.h> +#include <sys/time.h> +#include <rtthread.h> + +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif + +#ifdef RT_USING_PTHREADS +#include <pthread.h> +#endif + +/* Reentrant versions of system calls. */ + +int +_close_r(struct _reent *ptr, int fd) +{ +#ifndef RT_USING_DFS + return 0; +#else + return close(fd); +#endif +} + +int +_execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_fcntl_r(struct _reent *ptr, int fd, int cmd, int arg) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_fork_r(struct _reent *ptr) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_fstat_r(struct _reent *ptr, int fd, struct stat *pstat) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_getpid_r(struct _reent *ptr) +{ + return 0; +} + +int +_isatty_r(struct _reent *ptr, int fd) +{ + if (fd >=0 && fd < 3) return 1; + + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_kill_r(struct _reent *ptr, int pid, int sig) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_link_r(struct _reent *ptr, const char *old, const char *new) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +_off_t +_lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence) +{ +#ifndef RT_USING_DFS + return 0; +#else + _off_t rc; + + rc = lseek(fd, pos, whence); + return rc; +#endif +} + +int +_mkdir_r(struct _reent *ptr, const char *name, int mode) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = mkdir(name, mode); + return rc; +#endif +} + +int +_open_r(struct _reent *ptr, const char *file, int flags, int mode) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = open(file, flags, mode); + return rc; +#endif +} + +_ssize_t +_read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) +{ +#ifndef RT_USING_DFS + return 0; +#else + _ssize_t rc; + + rc = read(fd, buf, nbytes); + return rc; +#endif +} + +int +_rename_r(struct _reent *ptr, const char *old, const char *new) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = rename(old, new); + return rc; +#endif +} + +void * +_sbrk_r(struct _reent *ptr, ptrdiff_t incr) +{ + /* no use this routine to get memory */ + return RT_NULL; +} + +int +_stat_r(struct _reent *ptr, const char *file, struct stat *pstat) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = stat(file, pstat); + return rc; +#endif +} + +_CLOCK_T_ +_times_r(struct _reent *ptr, struct tms *ptms) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_unlink_r(struct _reent *ptr, const char *file) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = unlink(file); + return rc; +#endif +} + +int +_wait_r(struct _reent *ptr, int *status) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +#ifdef RT_USING_DEVICE +_ssize_t +_write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) +{ + if (fd < 3) + { +#ifdef RT_USING_CONSOLE + rt_device_t console_device; + extern rt_device_t rt_console_get_device(void); + + console_device = rt_console_get_device(); + if (console_device != 0) rt_device_write(console_device, 0, buf, nbytes); + return nbytes; +#else + return 0; +#endif + } + else + { +#ifdef RT_USING_DFS + _ssize_t rc; + + rc = write(fd, buf, nbytes); + return rc; +#else + return 0; +#endif + } +} +#endif + +#ifndef RT_USING_PTHREADS + +#ifndef MILLISECOND_PER_SECOND +#define MILLISECOND_PER_SECOND 1000UL +#endif + +#ifndef MICROSECOND_PER_SECOND +#define MICROSECOND_PER_SECOND 1000000UL +#endif + +#ifndef NANOSECOND_PER_SECOND +#define NANOSECOND_PER_SECOND 1000000000UL +#endif + +#define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) + + +struct timeval _timevalue = {0}; +#ifdef RT_USING_DEVICE +static void libc_system_time_init(void) +{ + time_t time; + rt_tick_t tick; + rt_device_t device; + + time = 0; + device = rt_device_find("rtc"); + if (device != RT_NULL) + { + /* get realtime seconds */ + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + } + + /* get tick */ + tick = rt_tick_get(); + + _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; + _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; +} +#endif + +int libc_get_time(struct timespec *time) +{ + rt_tick_t tick; + static rt_bool_t inited = 0; + + RT_ASSERT(time != RT_NULL); + + /* initialize system time */ + if (inited == 0) + { + libc_system_time_init(); + inited = 1; + } + + /* get tick */ + tick = rt_tick_get(); + + time->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND; + time->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000; + + return 0; +} + +int +_gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp) +{ + struct timespec tp; + + if (libc_get_time(&tp) == 0) + { + if (__tp != RT_NULL) + { + __tp->tv_sec = tp.tv_sec; + __tp->tv_usec = tp.tv_nsec / 1000UL; + } + + return tp.tv_sec; + } + + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} +#else +/* POSIX thread provides clock_gettime function */ +#include <time.h> +int +_gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp) +{ + struct timespec tp; + + if (clock_gettime(CLOCK_REALTIME, &tp) == 0) + { + if (__tp != RT_NULL) + { + __tp->tv_sec = tp.tv_sec; + __tp->tv_usec = tp.tv_nsec / 1000UL; + } + + return tp.tv_sec; + } + + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} +#endif + +/* Memory routine */ +void * +_malloc_r (struct _reent *ptr, size_t size) +{ + void* result; + + result = (void*)rt_malloc (size); + if (result == RT_NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void * +_realloc_r (struct _reent *ptr, void *old, size_t newlen) +{ + void* result; + + result = (void*)rt_realloc (old, newlen); + if (result == RT_NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void *_calloc_r (struct _reent *ptr, size_t size, size_t len) +{ + void* result; + + result = (void*)rt_calloc (size, len); + if (result == RT_NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void +_free_r (struct _reent *ptr, void *addr) +{ + rt_free (addr); +} + +void +_exit (int status) +{ +#ifdef RT_USING_MODULE + rt_module_t module; + + module = rt_module_self(); + if (module != RT_NULL) + { + struct rt_list_node *list; + struct rt_object *object; + + rt_enter_critical(); + + /* delete all threads in the module */ + list = &module->module_object[RT_Object_Class_Thread].object_list; + while (list->next != list) + { + object = rt_list_entry(list->next, struct rt_object, list); + if (rt_object_is_systemobject(object) == RT_TRUE) + { + /* detach static object */ + rt_thread_detach((rt_thread_t)object); + } + else + { + /* delete dynamic object */ + rt_thread_delete((rt_thread_t)object); + } + } + /* delete main thread */ + rt_thread_delete(module->module_thread); + rt_exit_critical(); + + /* re-schedule */ + rt_schedule(); + } +#endif + + rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status); + RT_ASSERT(0); + + while (1); +} + +void +_system(const char *s) +{ + /* not support this call */ + return; +} + +void __libc_init_array(void) +{ + /* we not use __libc init_aray to initialize C++ objects */ +} + +void abort(void) +{ + if (rt_thread_self()) + { + rt_thread_t self = rt_thread_self(); + + rt_kprintf("thread:%-8.*s abort!\n", RT_NAME_MAX, self->name); + rt_thread_suspend(self); + + rt_schedule(); + } + + while (1); +} |
