diff options
| author | lizhirui <[email protected]> | 2021-05-18 09:54:11 +0800 |
|---|---|---|
| committer | lizhirui <[email protected]> | 2021-05-18 09:54:11 +0800 |
| commit | 9a4e270f9770f778128ffdabe94f101416ce8c61 (patch) | |
| tree | 9df43fbcc25c3f288ed6fdecd65909d4094d849f /components/libc/compilers/common | |
| parent | e7fc0c89d2367533dcd1b77e46acaeea7bc3f876 (diff) | |
| parent | 4e9e3f79a565bb4fdc1d96deda18f9c771aeb0c9 (diff) | |
Merge branch 'RT-Thread:master' into master
Diffstat (limited to 'components/libc/compilers/common')
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); |
