summaryrefslogtreecommitdiff
path: root/components/libc/compilers/common
diff options
context:
space:
mode:
authorlizhirui <[email protected]>2021-05-18 09:54:11 +0800
committerlizhirui <[email protected]>2021-05-18 09:54:11 +0800
commit9a4e270f9770f778128ffdabe94f101416ce8c61 (patch)
tree9df43fbcc25c3f288ed6fdecd65909d4094d849f /components/libc/compilers/common
parente7fc0c89d2367533dcd1b77e46acaeea7bc3f876 (diff)
parent4e9e3f79a565bb4fdc1d96deda18f9c771aeb0c9 (diff)
Merge branch 'RT-Thread:master' into master
Diffstat (limited to 'components/libc/compilers/common')
-rw-r--r--components/libc/compilers/common/SConscript10
-rw-r--r--components/libc/compilers/common/dirent.h65
-rw-r--r--components/libc/compilers/common/none-gcc/SConscript13
-rw-r--r--components/libc/compilers/common/none-gcc/fcntl.h18
-rw-r--r--components/libc/compilers/common/none-gcc/readme.md3
-rw-r--r--components/libc/compilers/common/none-gcc/sys/stat.h8
-rw-r--r--components/libc/compilers/common/none-gcc/sys/types.h36
-rw-r--r--components/libc/compilers/common/none-gcc/sys/unistd.h81
-rw-r--r--components/libc/compilers/common/none-gcc/unistd.h10
-rw-r--r--components/libc/compilers/common/readme.md4
-rw-r--r--components/libc/compilers/common/stdlib.c27
-rw-r--r--components/libc/compilers/common/sys/ioctl.h18
-rw-r--r--components/libc/compilers/common/sys/mman.h60
-rw-r--r--components/libc/compilers/common/sys/statfs.h21
-rw-r--r--components/libc/compilers/common/sys/termios.h8
-rw-r--r--components/libc/compilers/common/sys/time.h63
-rw-r--r--components/libc/compilers/common/termios.h2
-rw-r--r--components/libc/compilers/common/time.c431
-rw-r--r--components/libc/compilers/common/unistd.c88
19 files changed, 852 insertions, 114 deletions
diff --git a/components/libc/compilers/common/SConscript b/components/libc/compilers/common/SConscript
index ecdee2637e..039e53a0b3 100644
--- a/components/libc/compilers/common/SConscript
+++ b/components/libc/compilers/common/SConscript
@@ -10,7 +10,7 @@ CPPPATH = [cwd]
if GetDepend('RT_USING_LIBC'):
src += Glob('*.c')
else:
- if GetDepend('RT_LIBC_USING_TIME') and not GetDepend('RT_USING_MINILIBC'):
+ if GetDepend('RT_LIBC_USING_TIME'):
src += ['time.c']
if GetDepend('RT_USING_POSIX') == False:
@@ -21,7 +21,13 @@ if rtconfig.CROSS_TOOL == 'keil':
else:
CPPDEFINES = []
-if not GetDepend('RT_USING_MINILIBC') and (GetDepend('RT_USING_LIBC') or GetDepend('RT_LIBC_USING_TIME')):
+if GetDepend('RT_USING_LIBC') or GetDepend('RT_LIBC_USING_TIME'):
group = DefineGroup('libc', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
+list = os.listdir(cwd)
+for d in list:
+ path = os.path.join(cwd, d)
+ if os.path.isfile(os.path.join(path, 'SConscript')):
+ group = group + SConscript(os.path.join(d, 'SConscript'))
+
Return('group')
diff --git a/components/libc/compilers/common/dirent.h b/components/libc/compilers/common/dirent.h
new file mode 100644
index 0000000000..bfba586093
--- /dev/null
+++ b/components/libc/compilers/common/dirent.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
+#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/common/none-gcc/SConscript b/components/libc/compilers/common/none-gcc/SConscript
new file mode 100644
index 0000000000..c5838f8949
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/SConscript
@@ -0,0 +1,13 @@
+from building import *
+
+Import('rtconfig')
+
+src = []
+cwd = GetCurrentDir()
+CPPPATH = [cwd]
+group = []
+src += Glob('*.c')
+
+if rtconfig.PLATFORM != 'gcc' or rtconfig.ARCH == 'sim':
+ group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], CPPPATH = CPPPATH)
+Return('group')
diff --git a/components/libc/compilers/common/none-gcc/fcntl.h b/components/libc/compilers/common/none-gcc/fcntl.h
new file mode 100644
index 0000000000..f247b926e9
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/fcntl.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
+#ifndef FCNTL_H__
+#define FCNTL_H__
+
+#include <rtconfig.h>
+
+#ifdef RT_USING_DFS
+#include <dfs_posix.h>
+#endif
+
+#endif
diff --git a/components/libc/compilers/common/none-gcc/readme.md b/components/libc/compilers/common/none-gcc/readme.md
new file mode 100644
index 0000000000..b10940d003
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/readme.md
@@ -0,0 +1,3 @@
+## Attentions
+
+This folder is "common" for toolchains excluding gcc. \ No newline at end of file
diff --git a/components/libc/compilers/common/none-gcc/sys/stat.h b/components/libc/compilers/common/none-gcc/sys/stat.h
new file mode 100644
index 0000000000..c4b42083c4
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/sys/stat.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
diff --git a/components/libc/compilers/common/none-gcc/sys/types.h b/components/libc/compilers/common/none-gcc/sys/types.h
new file mode 100644
index 0000000000..7222326a2a
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/sys/types.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-09-05 Meco Man fix bugs
+ * 2020-12-16 Meco Man add useconds_t
+ */
+#ifndef __TYPES_H__
+#define __TYPES_H__
+
+#include <stdint.h>
+
+typedef int32_t clockid_t;
+typedef int32_t key_t; /* Used for interprocess communication. */
+typedef int pid_t; /* Used for process IDs and process group IDs. */
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+typedef signed long off_t;
+typedef int mode_t;
+#ifndef ARCH_CPU_64BIT
+typedef signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#else
+typedef long signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#endif
+typedef unsigned long useconds_t; /* microseconds (unsigned) */
+
+typedef unsigned long dev_t;
+
+typedef unsigned int u_int;
+typedef unsigned char u_char;
+typedef unsigned long u_long;
+
+#endif
diff --git a/components/libc/compilers/common/none-gcc/sys/unistd.h b/components/libc/compilers/common/none-gcc/sys/unistd.h
new file mode 100644
index 0000000000..2f01f660b3
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/sys/unistd.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-12-16 Meco Man add usleep
+ */
+#ifndef _SYS_UNISTD_H
+#define _SYS_UNISTD_H
+
+#include <rtconfig.h>
+#include "types.h"
+
+#ifdef RT_USING_DFS
+
+#define STDIN_FILENO 0 /* standard input file descriptor */
+#define STDOUT_FILENO 1 /* standard output file descriptor */
+#define STDERR_FILENO 2 /* standard error file descriptor */
+
+#include <dfs_posix.h>
+#else
+#define _FREAD 0x0001 /* read enabled */
+#define _FWRITE 0x0002 /* write enabled */
+#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */
+#define _FMARK 0x0010 /* internal; mark during gc() */
+#define _FDEFER 0x0020 /* internal; defer for next gc pass */
+#define _FASYNC 0x0040 /* signal pgrp when data ready */
+#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */
+#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */
+#define _FCREAT 0x0200 /* open with file create */
+#define _FTRUNC 0x0400 /* open with truncation */
+#define _FEXCL 0x0800 /* error on open if file exists */
+#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
+#define _FSYNC 0x2000 /* do all writes synchronously */
+#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
+#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */
+#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
+
+
+#ifndef O_RDONLY
+#define O_RDONLY 0 /* +1 == FREAD */
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY 1 /* +1 == FWRITE */
+#endif
+#ifndef O_RDWR
+#define O_RDWR 2 /* +1 == FREAD|FWRITE */
+#endif
+#ifndef O_APPEND
+#define O_APPEND _FAPPEND
+#endif
+#ifndef O_CREAT
+#define O_CREAT _FCREAT
+#endif
+#ifndef O_TRUNC
+#define O_TRUNC _FTRUNC
+#endif
+#ifndef O_EXCL
+#define O_EXCL _FEXCL
+#endif
+#ifndef O_SYNC
+#define O_SYNC _FSYNC
+#endif
+
+#endif
+
+int isatty (int fd);
+char * ttyname (int desc);
+unsigned int sleep(unsigned int seconds);
+int usleep(useconds_t usec);
+pid_t gettid(void);
+pid_t getpid(void);
+pid_t getppid(void);
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
+
+#endif /* _SYS_UNISTD_H */
diff --git a/components/libc/compilers/common/none-gcc/unistd.h b/components/libc/compilers/common/none-gcc/unistd.h
new file mode 100644
index 0000000000..cd77a12e3b
--- /dev/null
+++ b/components/libc/compilers/common/none-gcc/unistd.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
+#include "sys/unistd.h"
+
diff --git a/components/libc/compilers/common/readme.md b/components/libc/compilers/common/readme.md
index 99797d933c..856ddeb045 100644
--- a/components/libc/compilers/common/readme.md
+++ b/components/libc/compilers/common/readme.md
@@ -1,8 +1,8 @@
## Attentions
-1. This folder is "common" for armlibc newlibc and dlib. It's not "common" for minilibc.
+1. This folder is "common" for all toolchains.
-2. If you want to add new .c files, please do not forget to fix SConscript file too. eg:
+2. If you want to add new `.c` files, please do not forget to fix SConscript file too. eg:
```python
if GetDepend('RT_USING_POSIX') == False:
diff --git a/components/libc/compilers/common/stdlib.c b/components/libc/compilers/common/stdlib.c
index b485bbd836..9d8952e99e 100644
--- a/components/libc/compilers/common/stdlib.c
+++ b/components/libc/compilers/common/stdlib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -9,39 +9,18 @@
*/
#include <rtthread.h>
-#include <stdlib.h>
void __rt_libc_exit(int status)
{
rt_thread_t self = rt_thread_self();
-#ifdef RT_USING_MODULE
- if (dlmodule_self())
- {
- dlmodule_exit(status);
- }
-#endif
-
if (self != RT_NULL)
{
- if(status == EXIT_FAILURE) /* abort() */
- {
- rt_kprintf("thread:%s abort!\n", self->name);
- }
- else /* exit() */
- {
- rt_kprintf("thread:%s exit:%d!\n", self->name, status);
- }
- rt_thread_suspend(self);
- rt_schedule();
+ rt_kprintf("thread:%s exit:%d!\n", self->name, status);
+ rt_thread_control(self, RT_THREAD_CTRL_CLOSE, RT_NULL);
}
}
-void __rt_libc_abort(void)
-{
- __rt_libc_exit(EXIT_FAILURE);
-}
-
int __rt_libc_system(const char *string)
{
/* TODO */
diff --git a/components/libc/compilers/common/sys/ioctl.h b/components/libc/compilers/common/sys/ioctl.h
new file mode 100644
index 0000000000..648d90230d
--- /dev/null
+++ b/components/libc/compilers/common/sys/ioctl.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-09-01 Meco Man First Version
+ */
+#ifndef _SYS_IOCTL_H
+#define _SYS_IOCTL_H
+
+#include <rtconfig.h>
+#ifdef RT_USING_POSIX
+#include <dfs_posix.h>
+#endif
+
+#endif
diff --git a/components/libc/compilers/common/sys/mman.h b/components/libc/compilers/common/sys/mman.h
new file mode 100644
index 0000000000..2da2ddf716
--- /dev/null
+++ b/components/libc/compilers/common/sys/mman.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017/11/30 Bernard The first version.
+ */
+
+#ifndef _SYS_MMAN_H
+#define _SYS_MMAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+#define MAP_FAILED ((void *) -1)
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+#define MAP_TYPE 0x0f
+#define MAP_FIXED 0x10
+#define MAP_ANON 0x20
+#define MAP_ANONYMOUS MAP_ANON
+#define MAP_NORESERVE 0x4000
+#define MAP_GROWSDOWN 0x0100
+#define MAP_DENYWRITE 0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED 0x2000
+#define MAP_POPULATE 0x8000
+#define MAP_NONBLOCK 0x10000
+#define MAP_STACK 0x20000
+#define MAP_HUGETLB 0x40000
+#define MAP_FILE 0
+
+#define PROT_NONE 0
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP 0x02000000
+
+#define MS_ASYNC 1
+#define MS_INVALIDATE 2
+#define MS_SYNC 4
+
+#define MCL_CURRENT 1
+#define MCL_FUTURE 2
+#define MCL_ONFAULT 4
+
+void *mmap (void *start, size_t len, int prot, int flags, int fd, off_t off);
+int munmap (void *start, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/components/libc/compilers/common/sys/statfs.h b/components/libc/compilers/common/sys/statfs.h
new file mode 100644
index 0000000000..0996af9a18
--- /dev/null
+++ b/components/libc/compilers/common/sys/statfs.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
+#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/common/sys/termios.h b/components/libc/compilers/common/sys/termios.h
new file mode 100644
index 0000000000..c4b42083c4
--- /dev/null
+++ b/components/libc/compilers/common/sys/termios.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
diff --git a/components/libc/compilers/common/sys/time.h b/components/libc/compilers/common/sys/time.h
index 599b8b5262..bb1a9c96fd 100644
--- a/components/libc/compilers/common/sys/time.h
+++ b/components/libc/compilers/common/sys/time.h
@@ -1,28 +1,34 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-09-07 Meco Man combine gcc armcc iccarm
+ * 2021-02-12 Meco Man move all definitions located in <clock_time.h> to this file
*/
#ifndef _SYS_TIME_H_
#define _SYS_TIME_H_
+#include <rtconfig.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * Skip define timespec for IAR version over 8.10.1 where __VER__ is 8010001.
- */
-#if defined ( __ICCARM__ ) && (__VER__ >= 8010001)
-#define _TIMESPEC_DEFINED
-#endif
-
+#define DST_NONE 0 /* not on dst */
+#define DST_USA 1 /* USA style dst */
+#define DST_AUST 2 /* Australian style dst */
+#define DST_WET 3 /* Western European dst */
+#define DST_MET 4 /* Middle European dst */
+#define DST_EET 5 /* Eastern European dst */
+#define DST_CAN 6 /* Canada */
+#define DST_GB 7 /* Great Britain and Eire */
+#define DST_RUM 8 /* Rumania */
+#define DST_TUR 9 /* Turkey */
+#define DST_AUSTALT 10 /* Australian style with shift in 1986 */
#ifndef _TIMEVAL_DEFINED
#define _TIMEVAL_DEFINED
@@ -30,13 +36,15 @@ extern "C" {
* Structure returned by gettimeofday(2) system call,
* and used in other calls.
*/
+#if !(defined(_WIN32))
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
+#endif
#endif /* _TIMEVAL_DEFINED */
-#if !defined __GNUC__ && !defined __ICCARM__
+#if !(defined(__GNUC__) && !defined(__ARMCC_VERSION)/*GCC*/) && !(defined(__ICCARM__) && (__VER__ >= 8010001)) && !defined(_WIN32)
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
@@ -52,6 +60,43 @@ int stime(const time_t *t);
time_t timegm(struct tm * const t);
int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv, const struct timezone *tz);
+#if defined(__ARMCC_VERSION) || defined (__ICCARM__)
+struct tm *gmtime_r(const time_t *timep, struct tm *r);
+#endif
+
+#ifdef RT_USING_POSIX
+#include <sys/types.h>
+/* posix clock and timer */
+#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)
+
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME 1
+#endif
+
+#define CLOCK_CPUTIME_ID 2
+
+#ifndef CLOCK_PROCESS_CPUTIME_ID
+#define CLOCK_PROCESS_CPUTIME_ID CLOCK_CPUTIME_ID
+#endif
+#ifndef CLOCK_THREAD_CPUTIME_ID
+#define CLOCK_THREAD_CPUTIME_ID CLOCK_CPUTIME_ID
+#endif
+
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC 4
+#endif
+
+int clock_getres (clockid_t clockid, struct timespec *res);
+int clock_gettime (clockid_t clockid, struct timespec *tp);
+int clock_settime (clockid_t clockid, const struct timespec *tp);
+int clock_time_to_tick(const struct timespec *time);
+#endif /* RT_USING_POSIX */
#ifdef __cplusplus
}
diff --git a/components/libc/compilers/common/termios.h b/components/libc/compilers/common/termios.h
index 414d0c0cb3..2960d52c58 100644
--- a/components/libc/compilers/common/termios.h
+++ b/components/libc/compilers/common/termios.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c
index a980f742fb..9996212444 100644
--- a/components/libc/compilers/common/time.c
+++ b/components/libc/compilers/common/time.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -12,21 +12,34 @@
* 2021-02-08 Meco Man add settimeofday() stime()
* 2021-02-10 Meco Man add ctime_r() and re-implement ctime()
* 2021-02-11 Meco Man fix bug #3183 - align days[] and months[] to 4 bytes
- * add difftime()
* 2021-02-12 Meco Man add errno
+ * 2012-12-08 Bernard <clock_time.c> fix the issue of _timevalue.tv_usec initialization,
+ * which found by Rob <[email protected]>
+ * 2021-02-12 Meco Man move all of the functions located in <clock_time.c> to this file
+ * 2021-03-15 Meco Man fixed a bug of leaking memory in asctime()
+ * 2021-05-01 Meco Man support fixed timezone
*/
-#include <sys/time.h>
+#include "sys/time.h"
#include <rtthread.h>
+
#ifdef RT_USING_DEVICE
#include <rtdevice.h>
#endif
+#define DBG_TAG "TIME"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#ifndef RT_LIBC_FIXED_TIMEZONE
+#define RT_LIBC_FIXED_TIMEZONE 8 /* UTC+8 */
+#endif
+
/* seconds per day */
#define SPD 24*60*60
/* days per month -- nonleap! */
-const short __spm[13] =
+static const short __spm[13] =
{
0,
(31),
@@ -60,6 +73,100 @@ static void num2str(char *c, int i)
c[1] = i % 10 + '0';
}
+/**
+ * Get time from RTC device (without timezone, UTC+0)
+ * @param tv: struct timeval
+ * @return the operation status, RT_EOK on successful
+ */
+static rt_err_t get_timeval(struct timeval *tv)
+{
+#ifdef RT_USING_RTC
+ static rt_device_t device = RT_NULL;
+ rt_err_t rst = -RT_ERROR;
+
+ if (tv == RT_NULL)
+ return -RT_EINVAL;
+
+ /* default is 0 */
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+
+ /* optimization: find rtc device only first */
+ if (device == RT_NULL)
+ {
+ device = rt_device_find("rtc");
+ }
+
+ /* read timestamp from RTC device */
+ if (device != RT_NULL)
+ {
+ if (rt_device_open(device, 0) == RT_EOK)
+ {
+ rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &tv->tv_sec);
+ rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME_US, &tv->tv_usec);
+ rt_device_close(device);
+ }
+ }
+ else
+ {
+ /* LOG_W will cause a recursive printing if ulog timestamp function is enabled */
+ rt_kprintf("Cannot find a RTC device to provide time!\r\n");
+ return -RT_ENOSYS;
+ }
+
+ return rst;
+
+#else
+ /* LOG_W will cause a recursive printing if ulog timestamp function is enabled */
+ rt_kprintf("Cannot find a RTC device to provide time!\r\n");
+ return -RT_ENOSYS;
+#endif /* RT_USING_RTC */
+}
+
+/**
+ * Set time to RTC device (without timezone)
+ * @param tv: struct timeval
+ * @return the operation status, RT_EOK on successful
+ */
+static int set_timeval(struct timeval *tv)
+{
+#ifdef RT_USING_RTC
+ static rt_device_t device = RT_NULL;
+ rt_err_t rst = -RT_ERROR;
+
+ if (tv == RT_NULL)
+ return -RT_EINVAL;
+
+ /* optimization: find rtc device only first */
+ if (device == RT_NULL)
+ {
+ device = rt_device_find("rtc");
+ }
+
+ /* read timestamp from RTC device */
+ if (device != RT_NULL)
+ {
+ if (rt_device_open(device, 0) == RT_EOK)
+ {
+ rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &tv->tv_sec);
+ rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME_US, &tv->tv_usec);
+ rt_device_close(device);
+ }
+ }
+ else
+ {
+ LOG_W("Cannot find a RTC device to provide time!");
+ return -RT_ENOSYS;
+ }
+
+ return rst;
+
+#else
+ LOG_W("Cannot find a RTC device to provide time!");
+ return -RT_ENOSYS;
+#endif /* RT_USING_RTC */
+}
+
struct tm *gmtime_r(const time_t *timep, struct tm *r)
{
time_t i;
@@ -97,35 +204,40 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r)
r->tm_isdst = 0;
return r;
}
+RTM_EXPORT(gmtime_r);
struct tm* gmtime(const time_t* t)
{
static struct tm tmp;
return gmtime_r(t, &tmp);
}
+RTM_EXPORT(gmtime);
-/*TODO: timezone */
struct tm* localtime_r(const time_t* t, struct tm* r)
{
time_t local_tz;
- int utc_plus;
- utc_plus = 0; /* GTM: UTC+0 */
- local_tz = *t + utc_plus * 3600;
+ local_tz = *t + RT_LIBC_FIXED_TIMEZONE * 3600;
return gmtime_r(&local_tz, r);
}
+RTM_EXPORT(localtime_r);
struct tm* localtime(const time_t* t)
{
static struct tm tmp;
return localtime_r(t, &tmp);
}
+RTM_EXPORT(localtime);
-/* TODO: timezone */
time_t mktime(struct tm * const t)
{
- return timegm(t);
+ time_t timestamp;
+
+ timestamp = timegm(t);
+ timestamp = timestamp - 3600 * RT_LIBC_FIXED_TIMEZONE;
+ return timestamp;
}
+RTM_EXPORT(mktime);
char* asctime_r(const struct tm *t, char *buf)
{
@@ -145,107 +257,88 @@ char* asctime_r(const struct tm *t, char *buf)
num2str(buf + 20, (t->tm_year + 1900) / 100);
num2str(buf + 22, (t->tm_year + 1900) % 100);
buf[24] = '\n';
+ buf[25] = '\0';
return buf;
}
+RTM_EXPORT(asctime_r);
char* asctime(const struct tm *timeptr)
{
- static char buf[25];
+ static char buf[26];
return asctime_r(timeptr, buf);
}
+RTM_EXPORT(asctime);
-char *ctime_r (const time_t * tim_p, char * result)
+char *ctime_r(const time_t * tim_p, char * result)
{
struct tm tm;
- return asctime_r (localtime_r (tim_p, &tm), result);
+ return asctime_r(localtime_r(tim_p, &tm), result);
}
+RTM_EXPORT(ctime_r);
char* ctime(const time_t *tim_p)
{
- return asctime (localtime (tim_p));
-}
-
-double difftime (time_t tim1, time_t tim2)
-{
- return (double)(tim1 - tim2);
+ return asctime(localtime(tim_p));
}
+RTM_EXPORT(ctime);
/**
* Returns the current time.
*
* @param time_t * t the timestamp pointer, if not used, keep NULL.
*
- * @return The value ((time_t)-1) is returned if the calendar time is not available.
+ * @return The value ((time_t)-1) is returned if the calendar time is not available.
* If timer is not a NULL pointer, the return value is also stored in timer.
*
*/
RT_WEAK time_t time(time_t *t)
{
- time_t time_now = ((time_t)-1); /* default is not available */
+ struct timeval now;
-#ifdef RT_USING_RTC
- static rt_device_t device = RT_NULL;
-
- /* optimization: find rtc device only first */
- if (device == RT_NULL)
- {
- device = rt_device_find("rtc");
- }
-
- /* read timestamp from RTC device */
- if (device != RT_NULL)
+ if(get_timeval(&now) == RT_EOK)
{
- if (rt_device_open(device, 0) == RT_EOK)
+ if (t)
{
- rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
- rt_device_close(device);
+ *t = now.tv_sec;
}
+ return now.tv_sec;
}
-#endif /* RT_USING_RTC */
-
- /* if t is not NULL, write timestamp to *t */
- if (t != RT_NULL)
- {
- *t = time_now;
- }
-
- if(time_now == (time_t)-1)
+ else
{
- errno = ENOSYS;
+ rt_set_errno(EFAULT);
+ return ((time_t)-1);
}
-
- return time_now;
}
+RTM_EXPORT(time);
RT_WEAK clock_t clock(void)
{
return rt_tick_get();
}
+RTM_EXPORT(clock);
int stime(const time_t *t)
{
-#ifdef RT_USING_RTC
- rt_device_t device;
+ struct timeval tv;
- /* read timestamp from RTC device. */
- device = rt_device_find("rtc");
- if (rt_device_open(device, 0) == RT_EOK)
+ if (!t)
+ {
+ rt_set_errno(EFAULT);
+ return -1;
+ }
+
+ tv.tv_sec = *t;
+ if (set_timeval(&tv) == RT_EOK)
{
- rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, (void*)t);
- rt_device_close(device);
+ return 0;
}
else
{
- errno = ENOSYS;
+ rt_set_errno(EFAULT);
return -1;
}
- return 0;
-
-#else
- errno = ENOSYS;
- return -1;
-#endif /* RT_USING_RTC */
}
+RTM_EXPORT(stime);
time_t timegm(struct tm * const t)
{
@@ -320,35 +413,231 @@ time_t timegm(struct tm * const t)
i = 60;
return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec;
}
+RTM_EXPORT(timegm);
-/* TODO: timezone */
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
- time_t t = time(RT_NULL);
+ /* The use of the timezone structure is obsolete;
+ * the tz argument should normally be specified as NULL.
+ * The tz_dsttime field has never been used under Linux.
+ * Thus, the following is purely of historic interest.
+ */
+ if(tz != RT_NULL)
+ {
+ tz->tz_dsttime = DST_NONE;
+ tz->tz_minuteswest = -(RT_LIBC_FIXED_TIMEZONE * 60);
+ }
- if (tv != RT_NULL && t != (time_t)-1)
+ if (tv != RT_NULL && get_timeval(tv) == RT_EOK)
{
- tv->tv_sec = t;
- tv->tv_usec = 0;
return 0;
}
else
{
- errno = ENOSYS;
+ rt_set_errno(EFAULT);
return -1;
}
}
+RTM_EXPORT(gettimeofday);
-/* TODO: timezone */
int settimeofday(const struct timeval *tv, const struct timezone *tz)
{
- if (tv != RT_NULL)
+ /* The use of the timezone structure is obsolete;
+ * the tz argument should normally be specified as NULL.
+ * The tz_dsttime field has never been used under Linux.
+ * Thus, the following is purely of historic interest.
+ */
+ if (tv != RT_NULL
+ && tv->tv_sec >= 0
+ && tv->tv_usec >= 0
+ && set_timeval((struct timeval *)tv) == RT_EOK)
{
- return stime((const time_t *)&tv->tv_sec);
+ return 0;
}
else
{
- errno = ENOSYS;
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+}
+RTM_EXPORT(settimeofday);
+
+/* inherent in the toolchain */
+RTM_EXPORT(difftime);
+RTM_EXPORT(strftime);
+
+#ifdef RT_USING_POSIX
+static struct timeval _timevalue;
+static int clock_time_system_init()
+{
+ 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 = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
+ _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
+
+ return 0;
+}
+INIT_COMPONENT_EXPORT(clock_time_system_init);
+
+int clock_getres(clockid_t clockid, struct timespec *res)
+{
+ int ret = 0;
+
+ if (res == RT_NULL)
+ {
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+
+ switch (clockid)
+ {
+ case CLOCK_REALTIME:
+ res->tv_sec = 0;
+ res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND;
+ break;
+
+#ifdef RT_USING_CPUTIME
+ case CLOCK_CPUTIME_ID:
+ res->tv_sec = 0;
+ res->tv_nsec = clock_cpu_getres();
+ break;
+#endif
+
+ default:
+ ret = -1;
+ rt_set_errno(EINVAL);
+ break;
+ }
+
+ return ret;
+}
+RTM_EXPORT(clock_getres);
+
+int clock_gettime(clockid_t clockid, struct timespec *tp)
+{
+ int ret = 0;
+
+ if (tp == RT_NULL)
+ {
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+
+ switch (clockid)
+ {
+ case CLOCK_REALTIME:
+ {
+ /* get tick */
+ int tick = rt_tick_get();
+
+ tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
+ tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000;
+ }
+ break;
+
+#ifdef RT_USING_CPUTIME
+ case CLOCK_CPUTIME_ID:
+ {
+ float unit = 0;
+ long long cpu_tick;
+
+ unit = clock_cpu_getres();
+ cpu_tick = clock_cpu_gettime();
+
+ tp->tv_sec = ((int)(cpu_tick * unit)) / NANOSECOND_PER_SECOND;
+ tp->tv_nsec = ((int)(cpu_tick * unit)) % NANOSECOND_PER_SECOND;
+ }
+ break;
+#endif
+ default:
+ rt_set_errno(EINVAL);
+ ret = -1;
+ }
+
+ return ret;
+}
+RTM_EXPORT(clock_gettime);
+
+int clock_settime(clockid_t clockid, const struct timespec *tp)
+{
+ int second;
+ rt_tick_t tick;
+ rt_device_t device;
+
+ if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
+ {
+ rt_set_errno(EINVAL);
+
return -1;
}
+
+ /* get second */
+ second = tp->tv_sec;
+ /* get tick */
+ tick = rt_tick_get();
+
+ /* update timevalue */
+ _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
+ _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1;
+
+ /* update for RTC device */
+ device = rt_device_find("rtc");
+ if (device != RT_NULL)
+ {
+ /* set realtime seconds */
+ rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second);
+ }
+ else
+ return -1;
+
+ return 0;
}
+RTM_EXPORT(clock_settime);
+
+int clock_time_to_tick(const struct timespec *time)
+{
+ int tick;
+ int nsecond, second;
+ struct timespec tp;
+
+ RT_ASSERT(time != RT_NULL);
+
+ tick = RT_WAITING_FOREVER;
+ if (time != NULL)
+ {
+ /* get current tp */
+ clock_gettime(CLOCK_REALTIME, &tp);
+
+ if ((time->tv_nsec - tp.tv_nsec) < 0)
+ {
+ nsecond = NANOSECOND_PER_SECOND - (tp.tv_nsec - time->tv_nsec);
+ second = time->tv_sec - tp.tv_sec - 1;
+ }
+ else
+ {
+ nsecond = time->tv_nsec - tp.tv_nsec;
+ second = time->tv_sec - tp.tv_sec;
+ }
+
+ tick = second * RT_TICK_PER_SECOND + nsecond * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;
+ if (tick < 0) tick = 0;
+ }
+
+ return tick;
+}
+RTM_EXPORT(clock_time_to_tick);
+
+#endif /* RT_USING_POSIX */
diff --git a/components/libc/compilers/common/unistd.c b/components/libc/compilers/common/unistd.c
index df970b2b59..6c81fc7662 100644
--- a/components/libc/compilers/common/unistd.c
+++ b/components/libc/compilers/common/unistd.c
@@ -1,26 +1,104 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
- * 2020-09-01 Meco Man First Version
+ * 2020-09-01 Meco Man first Version
+ * 2021-02-12 Meco Man move all functions located in <pthread_sleep.c> to this file
*/
#include <unistd.h>
+#include <rtthread.h>
+#include <rthw.h>
#ifdef RT_USING_POSIX_TERMIOS
#include "termios.h"
-
int isatty(int fd)
{
struct termios ts;
- return(tcgetattr(fd,&ts) != -1);/*true if no error (is a tty)*/
+ return(tcgetattr(fd, &ts) != -1); /*true if no error (is a tty)*/
+}
+#else
+int isatty(int fd)
+{
+ if (fd >=0 && fd < 3)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
}
#endif
+RTM_EXPORT(isatty);
char *ttyname(int fd)
{
- return "/dev/tty0"; /*TODO: need to add more specific*/
+ return "/dev/tty"; /*TODO: need to add more specific*/
+}
+RTM_EXPORT(ttyname);
+
+unsigned int sleep(unsigned int seconds)
+{
+ rt_tick_t delta_tick;
+
+ delta_tick = rt_tick_get();
+ rt_thread_delay(seconds * RT_TICK_PER_SECOND);
+ delta_tick = rt_tick_get() - delta_tick;
+
+ return seconds - delta_tick/RT_TICK_PER_SECOND;
+}
+RTM_EXPORT(sleep);
+
+int usleep(useconds_t usec)
+{
+ rt_thread_mdelay(usec / 1000u);
+ rt_hw_us_delay(usec % 1000u);
+ return 0;
+}
+RTM_EXPORT(usleep);
+
+pid_t gettid(void)
+{
+ /*TODO*/
+ return 0;
+}
+
+pid_t getpid(void)
+{
+ return gettid();
+}
+RTM_EXPORT(getpid);
+
+pid_t getppid(void)
+{
+ return 0;
+}
+RTM_EXPORT(getppid);
+
+uid_t getuid(void)
+{
+ return 0; /*ROOT*/
+}
+RTM_EXPORT(getuid);
+
+uid_t geteuid(void)
+{
+ return 0; /*ROOT*/
+}
+RTM_EXPORT(geteuid);
+
+gid_t getgid(void)
+{
+ return 0; /*ROOT*/
+}
+RTM_EXPORT(getgid);
+
+gid_t getegid(void)
+{
+ return 0; /*ROOT*/
}
+RTM_EXPORT(getegid);