summaryrefslogtreecommitdiff
path: root/components/libc/compilers/newlib
diff options
context:
space:
mode:
authorbernard <[email protected]>2017-10-10 17:12:03 +0800
committerbernard <[email protected]>2017-10-10 17:12:03 +0800
commitdb88c0b6a23fa6d56094b6d6f5e9c3e577e9a88d (patch)
tree2573ed87aa2c25f9bf8149d981b57e9be27a9050 /components/libc/compilers/newlib
parent5c6a6e5db825905befa9ca903aa557ea3577b7af (diff)
[libc] Change libc stubs to compiler folder.
Diffstat (limited to 'components/libc/compilers/newlib')
-rw-r--r--components/libc/compilers/newlib/SConscript18
-rw-r--r--components/libc/compilers/newlib/libc.c56
-rw-r--r--components/libc/compilers/newlib/libc.h21
-rw-r--r--components/libc/compilers/newlib/libc_sym.c47
-rw-r--r--components/libc/compilers/newlib/sys/dirent.h57
-rw-r--r--components/libc/compilers/newlib/sys/fcntl.h18
-rw-r--r--components/libc/compilers/newlib/sys/statfs.h13
-rw-r--r--components/libc/compilers/newlib/syscalls.c464
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);
+}