diff options
| author | yangjie11 <[email protected]> | 2020-11-18 09:56:35 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-11-18 09:56:35 +0800 |
| commit | d4a682e8d97fa131e5a8d795f8c5451d55cdd5b0 (patch) | |
| tree | 4773b40cb012475c5daf74bfd55707e141477669 /components/libc | |
| parent | 2b98f4720c827ae1850df78299f6b273d568c8c7 (diff) | |
| parent | 2ef3c9d861f55253620996a94831a4be31ca6620 (diff) | |
Merge pull request #3 from RT-Thread/master
sync
Diffstat (limited to 'components/libc')
55 files changed, 1474 insertions, 809 deletions
diff --git a/components/libc/Kconfig b/components/libc/Kconfig index b2abe69850..65c8d44225 100644 --- a/components/libc/Kconfig +++ b/components/libc/Kconfig @@ -8,6 +8,12 @@ config RT_USING_PTHREADS bool "Enable pthreads APIs" default n +if RT_USING_PTHREADS + config PTHREAD_NUM_MAX + int "Maximum number of pthreads" + default 8 +endif + if RT_USING_LIBC && RT_USING_DFS config RT_USING_POSIX bool "Enable POSIX layer for poll/select, stdin etc" @@ -16,11 +22,15 @@ if RT_USING_LIBC && RT_USING_DFS if RT_USING_POSIX config RT_USING_POSIX_MMAP - bool "Enable mmap() api" + bool "Enable mmap() API" default n config RT_USING_POSIX_TERMIOS - bool "Enable termios feature" + bool "Enable termios APIs" + default n + + config RT_USING_POSIX_GETLINE + bool "Enable getline()/getdelim() APIs" default n config RT_USING_POSIX_AIO @@ -28,9 +38,25 @@ if RT_USING_LIBC && RT_USING_DFS default n endif +endif + +if RT_USING_LIBC config RT_USING_MODULE bool "Enable dynamic module with dlopen/dlsym/dlclose feature" default n + + if RT_USING_MODULE + config RT_USING_CUSTOM_DLMODULE + bool "Enable load dynamic module by custom" + default n + endif + +endif + +if RT_USING_LIBC != y + config RT_LIBC_USING_TIME + bool "Enable TIME FUNCTIONS WITHOUT COMPILER'S LIBC" + default y endif endmenu diff --git a/components/libc/aio/posix_aio.c b/components/libc/aio/posix_aio.c index 75e7de9ce3..3eb7634495 100644 --- a/components/libc/aio/posix_aio.c +++ b/components/libc/aio/posix_aio.c @@ -170,7 +170,7 @@ static void aio_read_work(struct rt_work* work, void* work_data) if (len <= 0) cb->aio_result = errno; else - cb->aio_result = 0; + cb->aio_result = len; rt_hw_interrupt_enable(level); return ; @@ -321,6 +321,7 @@ static void aio_write_work(struct rt_work* work, void* work_data) return; } + /** * The aio_write() function shall write aiocbp->aio_nbytes to the file associated * with aiocbp->aio_fildes from the buffer pointed to by aiocbp->aio_buf. The diff --git a/components/libc/compilers/armlibc/README.md b/components/libc/compilers/armlibc/README.md new file mode 100644 index 0000000000..4d2a73b6be --- /dev/null +++ b/components/libc/compilers/armlibc/README.md @@ -0,0 +1,9 @@ +# ARMLIB (Keil-MDK) porting for RT-Thread + +Please define RT_USING_LIBC and compile RT-Thread with Keil-MDK compiler. + + + +## More Information + +https://www.keil.com/support/man/docs/armlib/
\ No newline at end of file diff --git a/components/libc/compilers/armlibc/SConscript b/components/libc/compilers/armlibc/SConscript index 081efa7358..52f7a6d93a 100644 --- a/components/libc/compilers/armlibc/SConscript +++ b/components/libc/compilers/armlibc/SConscript @@ -14,7 +14,7 @@ if GetDepend('RT_USING_DFS') == False: if GetDepend('RT_USING_MODULE') == False: SrcRemove(src, ['libc_syms.c']) -if rtconfig.PLATFORM == 'armcc': +if rtconfig.PLATFORM == 'armcc' or rtconfig.PLATFORM == 'armclang': group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) diff --git a/components/libc/compilers/armlibc/fcntl.h b/components/libc/compilers/armlibc/fcntl.h index 80cf1b4409..3e650a8471 100644 --- a/components/libc/compilers/armlibc/fcntl.h +++ b/components/libc/compilers/armlibc/fcntl.h @@ -9,6 +9,8 @@ #ifndef FCNTL_H__ #define FCNTL_H__ +#include <rtconfig.h> + #ifdef RT_USING_DFS #include <dfs_posix.h> #endif diff --git a/components/libc/compilers/armlibc/libc.h b/components/libc/compilers/armlibc/libc.h index 158fe06c3e..b9b1b6212d 100644 --- a/components/libc/compilers/armlibc/libc.h +++ b/components/libc/compilers/armlibc/libc.h @@ -12,11 +12,17 @@ #include <stddef.h> +#ifdef __cplusplus +extern "C" { +#endif int libc_system_init(void); int libc_stdio_set_console(const char* device_name, int mode); int libc_stdio_get_console(void); -int libc_stdio_read (void *buffer, size_t size); -int libc_stdio_write(const void *buffer, size_t size); +int libc_stdio_read(void* buffer, size_t size); +int libc_stdio_write(const void* buffer, size_t size); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/libc/compilers/armlibc/stubs.c b/components/libc/compilers/armlibc/stubs.c index 6e9f13d143..b4cc13799e 100644 --- a/components/libc/compilers/armlibc/stubs.c +++ b/components/libc/compilers/armlibc/stubs.c @@ -9,6 +9,8 @@ * 2013-11-24 aozima fixed _sys_read()/_sys_write() issues. * 2014-08-03 bernard If using msh, use system() implementation * in msh. + * 2020-08-05 Meco Man fixed _sys_flen() compiling-warning when + * RT_USING_DFS is not defined */ #include <string.h> @@ -251,7 +253,7 @@ void _ttywrch(int ch) #endif } -void _sys_exit(int return_code) +RT_WEAK void _sys_exit(int return_code) { /* TODO: perhaps exit the thread which is invoking this function */ while (1); @@ -265,12 +267,25 @@ void _sys_exit(int return_code) */ long _sys_flen(FILEHANDLE fh) { +#ifdef RT_USING_DFS + struct stat stat; + + if (fh < STDERR) + return -1; + + fstat(fh, &stat); + return stat.st_size; +#else return -1; +#endif } int _sys_istty(FILEHANDLE fh) { - return 0; + if((STDIN <= fh) && (fh <= STDERR)) + return 1; + else + return 0; } int remove(const char *filename) diff --git a/components/libc/compilers/armlibc/termios.h b/components/libc/compilers/armlibc/sys/ioctl.h index 1956121225..033a57014a 100644 --- a/components/libc/compilers/armlibc/termios.h +++ b/components/libc/compilers/armlibc/sys/ioctl.h @@ -5,11 +5,11 @@ * * Change Logs: * Date Author Notes + * 2020-09-01 Meco Man First Version */ -#ifndef _TERMIOS_H__ -#define _TERMIOS_H__ +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + -#include <sys/types.h> -#include <posix_termios.h> #endif diff --git a/components/libc/compilers/armlibc/sys/time.h b/components/libc/compilers/armlibc/sys/time.h deleted file mode 100644 index bac122e183..0000000000 --- a/components/libc/compilers/armlibc/sys/time.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef _SYS_TIME_H_ -#define _SYS_TIME_H_ - -#include <time.h> -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _TIMEVAL_DEFINED -#define _TIMEVAL_DEFINED -/* - * Structure returned by gettimeofday(2) system call, - * and used in other calls. - */ -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif /* _TIMEVAL_DEFINED */ - -#ifndef _TIMESPEC_DEFINED -#define _TIMESPEC_DEFINED -/* - * Structure defined by POSIX.1b to be like a timeval. - */ -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* and nanoseconds */ -}; -#endif /* _TIMESPEC_DEFINED */ - -struct timezone { - int tz_minuteswest; /* minutes west of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; - -int gettimeofday(struct timeval *tp, void *ignore); -struct tm *gmtime_r(const time_t *timep, struct tm *r); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_TIME_H_ */ diff --git a/components/libc/compilers/armlibc/sys/types.h b/components/libc/compilers/armlibc/sys/types.h index 4c76dfc429..2aad77c99d 100644 --- a/components/libc/compilers/armlibc/sys/types.h +++ b/components/libc/compilers/armlibc/sys/types.h @@ -5,16 +5,20 @@ * * Change Logs: * Date Author Notes + * 2020-09-05 Meco Man fix bugs */ #ifndef __TYPES_H__ #define __TYPES_H__ #include <stdint.h> -#include <rtthread.h> -typedef rt_int32_t clockid_t; -typedef rt_int32_t key_t; /* Used for interprocess communication. */ -typedef rt_int32_t pid_t; /* Used for process IDs and process group IDs. */ -typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */ +typedef int32_t clockid_t; +typedef int32_t key_t; /* Used for interprocess communication. */ +typedef int32_t pid_t; /* Used for process IDs and process group IDs. */ +#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 #endif diff --git a/components/libc/compilers/armlibc/sys/unistd.h b/components/libc/compilers/armlibc/sys/unistd.h index 33f0561e72..524de2cf83 100644 --- a/components/libc/compilers/armlibc/sys/unistd.h +++ b/components/libc/compilers/armlibc/sys/unistd.h @@ -36,14 +36,36 @@ #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); + #endif /* _SYS_UNISTD_H */ diff --git a/components/libc/compilers/armlibc/time.c b/components/libc/compilers/armlibc/time.c deleted file mode 100644 index 29c5c6cdd2..0000000000 --- a/components/libc/compilers/armlibc/time.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include <sys/time.h> -#include <rtthread.h> - -#ifdef RT_USING_DEVICE -int gettimeofday(struct timeval *tp, void *ignore) -{ - time_t time; - rt_device_t device; - - device = rt_device_find("rtc"); - if (device != RT_NULL) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - if (tp != RT_NULL) - { - tp->tv_sec = time; - tp->tv_usec = 0; - } - - return time; - } - - return 0; -} -#endif - -/** - * Returns the current time. - * - * @param time_t * t the timestamp pointer, if not used, keep NULL. - * - * @return time_t return timestamp current. - * - */ -/* for IAR 6.2 later Compiler */ -#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 -#pragma module_name = "?time" -time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */ -#else -time_t time(time_t *t) -#endif -{ - time_t time_now = 0; - -#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 (rt_device_open(device, 0) == RT_EOK) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); - rt_device_close(device); - } - } -#endif /* RT_USING_RTC */ - - /* if t is not NULL, write timestamp to *t */ - if (t != RT_NULL) - { - *t = time_now; - } - - return time_now; -} - -RT_WEAK clock_t clock(void) -{ - return rt_tick_get(); -} diff --git a/components/libc/compilers/armlibc/unistd.h b/components/libc/compilers/armlibc/unistd.h index 70187722d8..736fc219a8 100644 --- a/components/libc/compilers/armlibc/unistd.h +++ b/components/libc/compilers/armlibc/unistd.h @@ -7,3 +7,4 @@ * Date Author Notes */ #include "sys/unistd.h" + diff --git a/components/libc/compilers/common/SConscript b/components/libc/compilers/common/SConscript index 02bf49941d..2407301405 100644 --- a/components/libc/compilers/common/SConscript +++ b/components/libc/compilers/common/SConscript @@ -2,11 +2,21 @@ from building import * Import('rtconfig') -src = Glob('*.c') +src = [] cwd = GetCurrentDir() group = [] CPPPATH = [cwd] -group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], CPPPATH = CPPPATH) +if GetDepend('RT_USING_LIBC'): + src += Glob('*.c') +else: + if GetDepend('RT_LIBC_USING_TIME') and not GetDepend('RT_USING_MINILIBC'): + src += ['time.c'] + +if GetDepend('RT_USING_POSIX') == False: + SrcRemove(src, ['unistd.c']) + +if not GetDepend('RT_USING_MINILIBC') and (GetDepend('RT_USING_LIBC') or GetDepend('RT_LIBC_USING_TIME')): + group = DefineGroup('libc', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/components/libc/compilers/common/gmtime_r.c b/components/libc/compilers/common/gmtime_r.c deleted file mode 100644 index dff251ab6c..0000000000 --- a/components/libc/compilers/common/gmtime_r.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-10-26 zylx first version - */ - -#if defined(__CC_ARM) || defined(__CLANG_ARM) || defined (__IAR_SYSTEMS_ICC__) -#include <sys/time.h> - -/* seconds per day */ -#define SPD 24*60*60 - -/* days per month -- nonleap! */ -const short __spm[13] = -{ - 0, - (31), - (31 + 28), - (31 + 28 + 31), - (31 + 28 + 31 + 30), - (31 + 28 + 31 + 30 + 31), - (31 + 28 + 31 + 30 + 31 + 30), - (31 + 28 + 31 + 30 + 31 + 30 + 31), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30), - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), -}; - -int __isleap(int year) -{ - /* every fourth year is a leap year except for century years that are - * not divisible by 400. */ - /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ - return (!(year % 4) && ((year % 100) || !(year % 400))); -} - -/** - * This function will convert Time (Restartable) - * - * @param timep the timestamp - * @param the structure to stores information - * - * @return the structure to stores information - * - */ -struct tm *gmtime_r(const time_t *timep, struct tm *r) -{ - time_t i; - register time_t work = *timep % (SPD); - r->tm_sec = work % 60; - work /= 60; - r->tm_min = work % 60; - r->tm_hour = work / 60; - work = *timep / (SPD); - r->tm_wday = (4 + work) % 7; - for (i = 1970;; ++i) - { - register time_t k = __isleap(i) ? 366 : 365; - if (work >= k) - work -= k; - else - break; - } - r->tm_year = i - 1900; - r->tm_yday = work; - - r->tm_mday = 1; - if (__isleap(i) && (work > 58)) - { - if (work == 59) - r->tm_mday = 2; /* 29.2. */ - work -= 1; - } - - for (i = 11; i && (__spm[i] > work); --i) - ; - r->tm_mon = i; - r->tm_mday += work - __spm[i]; - return r; -} -#endif /* end of __CC_ARM or __CLANG_ARM or __IAR_SYSTEMS_ICC__ */ - diff --git a/components/libc/compilers/common/readme.md b/components/libc/compilers/common/readme.md new file mode 100644 index 0000000000..99797d933c --- /dev/null +++ b/components/libc/compilers/common/readme.md @@ -0,0 +1,10 @@ +## Attentions + +1. This folder is "common" for armlibc newlibc and dlib. It's not "common" for minilibc. + +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: + SrcRemove(src, ['unistd.c']) +```
\ No newline at end of file diff --git a/components/libc/compilers/dlib/sys/time.h b/components/libc/compilers/common/sys/time.h index baf566936b..22f1c17f5e 100644 --- a/components/libc/compilers/dlib/sys/time.h +++ b/components/libc/compilers/common/sys/time.h @@ -5,17 +5,25 @@ * * Change Logs: * Date Author Notes + * 2020-09-07 Meco Man combine gcc armcc iccarm */ #ifndef _SYS_TIME_H_ #define _SYS_TIME_H_ #include <time.h> -#include <sys/types.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 + + #ifndef _TIMEVAL_DEFINED #define _TIMEVAL_DEFINED /* @@ -28,23 +36,6 @@ struct timeval { }; #endif /* _TIMEVAL_DEFINED */ -/* - * Skip define timespec for IAR version over 8.10.1 where __VER__ is 8010001. - */ -#if defined ( __ICCARM__ ) && (__VER__ >= 8010001) -#define _TIMESPEC_DEFINED -#endif - -#ifndef _TIMESPEC_DEFINED -#define _TIMESPEC_DEFINED -/* - * Structure defined by POSIX.1b to be like a timeval. - */ -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* and nanoseconds */ -}; -#endif /* _TIMESPEC_DEFINED */ struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ diff --git a/components/libc/compilers/dlib/termios.h b/components/libc/compilers/common/termios.h index 1956121225..ee2b4d5718 100644 --- a/components/libc/compilers/dlib/termios.h +++ b/components/libc/compilers/common/termios.h @@ -9,7 +9,9 @@ #ifndef _TERMIOS_H__ #define _TERMIOS_H__ +#ifdef RT_USING_POSIX_TERMIOS #include <sys/types.h> #include <posix_termios.h> +#endif #endif diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c new file mode 100644 index 0000000000..99dab71eb4 --- /dev/null +++ b/components/libc/compilers/common/time.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-21 zhangjun copy from minilibc + * 2020-09-07 Meco Man combine gcc armcc iccarm + */ + +#include <sys/time.h> +#include <rtthread.h> + +#if !defined (__IAR_SYSTEMS_ICC__) + +/* days per month -- nonleap! */ +const short __spm[13] = +{ + 0, + (31), + (31 + 28), + (31 + 28 + 31), + (31 + 28 + 31 + 30), + (31 + 28 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), +}; +static const char days[] = "Sun Mon Tue Wed Thu Fri Sat "; +static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; + +/* seconds per day */ +#define SPD 24*60*60 + +int __isleap(int year) +{ + /* every fourth year is a leap year except for century years that are + * not divisible by 400. */ + /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ + return (!(year % 4) && ((year % 100) || !(year % 400))); +} + +struct tm *gmtime_r(const time_t *timep, struct tm *r) +{ + time_t i; + register time_t work = *timep % (SPD); + r->tm_sec = work % 60; + work /= 60; + r->tm_min = work % 60; + r->tm_hour = work / 60; + work = *timep / (SPD); + r->tm_wday = (4 + work) % 7; + for (i = 1970;; ++i) + { + register time_t k = __isleap(i) ? 366 : 365; + if (work >= k) + work -= k; + else + break; + } + r->tm_year = i - 1900; + r->tm_yday = work; + + r->tm_mday = 1; + if (__isleap(i) && (work > 58)) + { + if (work == 59) + r->tm_mday = 2; /* 29.2. */ + work -= 1; + } + + for (i = 11; i && (__spm[i] > work); --i) + ; + r->tm_mon = i; + r->tm_mday += work - __spm[i]; + return r; +} + +struct tm* gmtime(const time_t* t) +{ + static struct tm tmp; + return gmtime_r(t, &tmp); +} + +/*TODO timezone is not supprt now */ +struct tm* localtime_r(const time_t* t, struct tm* r) +{ + return gmtime_r(t, r); +} + +struct tm* localtime(const time_t* t) +{ + static struct tm tmp; + return localtime_r(t, &tmp); +} + +time_t mktime(struct tm * const t) +{ + register time_t day; + register time_t i; + register time_t years = t->tm_year - 70; + + if (t->tm_sec > 60) + { + t->tm_min += t->tm_sec / 60; + t->tm_sec %= 60; + } + if (t->tm_min > 60) + { + t->tm_hour += t->tm_min / 60; + t->tm_min %= 60; + } + if (t->tm_hour > 24) + { + t->tm_mday += t->tm_hour / 24; + t->tm_hour %= 24; + } + if (t->tm_mon > 12) + { + t->tm_year += t->tm_mon / 12; + t->tm_mon %= 12; + } + while (t->tm_mday > __spm[1 + t->tm_mon]) + { + if (t->tm_mon == 1 && __isleap(t->tm_year + 1900)) + { + --t->tm_mday; + } + t->tm_mday -= __spm[t->tm_mon]; + ++t->tm_mon; + if (t->tm_mon > 11) + { + t->tm_mon = 0; + ++t->tm_year; + } + } + + if (t->tm_year < 70) + return (time_t) - 1; + + /* Days since 1970 is 365 * number of years + number of leap years since 1970 */ + day = years * 365 + (years + 1) / 4; + + /* After 2100 we have to substract 3 leap years for every 400 years + This is not intuitive. Most mktime implementations do not support + dates after 2059, anyway, so we might leave this out for it's + bloat. */ + if (years >= 131) + { + years -= 131; + years /= 100; + day -= (years >> 2) * 3 + 1; + if ((years &= 3) == 3) + years--; + day -= years; + } + + day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 + + (__isleap(t->tm_year + 1900) & (t->tm_mon > 1)); + + /* day is now the number of days since 'Jan 1 1970' */ + i = 7; + t->tm_wday = (day + 4) % i; /* Sunday=0, Monday=1, ..., Saturday=6 */ + + i = 24; + day *= i; + i = 60; + return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec; +} + +static void num2str(char *c, int i) +{ + c[0] = i / 10 + '0'; + c[1] = i % 10 + '0'; +} + +char* asctime_r(const struct tm *t, char *buf) +{ + /* "Wed Jun 30 21:49:08 1993\n" */ + *(int*) buf = *(int*) (days + (t->tm_wday << 2)); + *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2)); + num2str(buf + 8, t->tm_mday); + if (buf[8] == '0') + buf[8] = ' '; + buf[10] = ' '; + num2str(buf + 11, t->tm_hour); + buf[13] = ':'; + num2str(buf + 14, t->tm_min); + buf[16] = ':'; + num2str(buf + 17, t->tm_sec); + buf[19] = ' '; + num2str(buf + 20, (t->tm_year + 1900) / 100); + num2str(buf + 22, (t->tm_year + 1900) % 100); + buf[24] = '\n'; + return buf; +} + +char* asctime(const struct tm *timeptr) +{ + static char buf[25]; + return asctime_r(timeptr, buf); +} + +char* ctime(const time_t *timep) +{ + return asctime(localtime(timep)); +} + +#endif /* __IAR_SYSTEMS_ICC__ */ + +int gettimeofday(struct timeval *tp, void *ignore) +{ + time_t time = 0; +#ifdef RT_USING_DEVICE + rt_device_t device; + device = rt_device_find("rtc"); + RT_ASSERT(device != RT_NULL); + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + if (tp != RT_NULL) + { + tp->tv_sec = time; + tp->tv_usec = 0; + } +#else + tv->tv_sec = 0; + tv->tv_usec = 0; +#endif + + return time; +} + + +/** + * Returns the current time. + * + * @param time_t * t the timestamp pointer, if not used, keep NULL. + * + * @return time_t return timestamp current. + * + */ +/* for IAR 6.2 later Compiler */ +#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 +#pragma module_name = "?time" +#if _DLIB_TIME_USES_64 +time_t __time64(time_t *t) +#else +time_t __time32(time_t *t) +#endif +#else +time_t time(time_t *t) +#endif +{ + time_t time_now = 0; + +#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 (rt_device_open(device, 0) == RT_EOK) + { + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); + rt_device_close(device); + } + } +#endif /* RT_USING_RTC */ + + /* if t is not NULL, write timestamp to *t */ + if (t != RT_NULL) + { + *t = time_now; + } + + return time_now; +} + +RT_WEAK clock_t clock(void) +{ + return rt_tick_get(); +} diff --git a/components/libc/compilers/common/unistd.c b/components/libc/compilers/common/unistd.c new file mode 100644 index 0000000000..df970b2b59 --- /dev/null +++ b/components/libc/compilers/common/unistd.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-09-01 Meco Man First Version + */ + +#include <unistd.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)*/ +} +#endif + +char *ttyname(int fd) +{ + return "/dev/tty0"; /*TODO: need to add more specific*/ +} diff --git a/components/libc/compilers/dlib/README.md b/components/libc/compilers/dlib/README.md index 846eb3f5c0..acd08f9074 100644 --- a/components/libc/compilers/dlib/README.md +++ b/components/libc/compilers/dlib/README.md @@ -1,4 +1,9 @@ -Dlib(IAR) porting for RT-Thread. +# DLIB (IAR) porting for RT-Thread Please define RT_USING_LIBC and compile RT-Thread with IAR compiler. + + +## More Information + +http://www.iarsys.co.jp/download/LMS2/arm/7502/ewarm7502doc/arm/doc/EWARM_DevelopmentGuide.ENU.pdf P.130
\ No newline at end of file diff --git a/components/libc/compilers/dlib/libc.h b/components/libc/compilers/dlib/libc.h index 7b2665c32b..5b46bee0c8 100644 --- a/components/libc/compilers/dlib/libc.h +++ b/components/libc/compilers/dlib/libc.h @@ -13,11 +13,17 @@ #include <stddef.h> +#ifdef __cplusplus +extern "C" { +#endif int libc_system_init(void); int libc_stdio_set_console(const char* device_name, int mode); int libc_stdio_get_console(void); -int libc_stdio_read (void *buffer, size_t size); -int libc_stdio_write(const void *buffer, size_t size); +int libc_stdio_read(void* buffer, size_t size); +int libc_stdio_write(const void* buffer, size_t size); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/libc/compilers/dlib/sys/errno.h b/components/libc/compilers/dlib/sys/errno.h index 1ecb58b74c..1ad4c8acc0 100644 --- a/components/libc/compilers/dlib/sys/errno.h +++ b/components/libc/compilers/dlib/sys/errno.h @@ -5,11 +5,12 @@ * * Change Logs: * Date Author Notes + * 2019-07-08 Bernard The first version */ + #ifndef SYS_ERRNO_H__ #define SYS_ERRNO_H__ -#include <rtthread.h> - +#include <errno.h> #endif diff --git a/components/libc/compilers/newlib/termios.h b/components/libc/compilers/dlib/sys/signal.h index 1956121225..22adb1228b 100644 --- a/components/libc/compilers/newlib/termios.h +++ b/components/libc/compilers/dlib/sys/signal.h @@ -5,11 +5,12 @@ * * Change Logs: * Date Author Notes + * 2019-07-08 Bernard The first version */ -#ifndef _TERMIOS_H__ -#define _TERMIOS_H__ -#include <sys/types.h> -#include <posix_termios.h> +#ifndef SYS_SIGNAL_H__ +#define SYS_SIGNAL_H__ + +#include <libc/libc_signal.h> #endif diff --git a/components/libc/compilers/dlib/sys/types.h b/components/libc/compilers/dlib/sys/types.h index 4c76dfc429..001ace4dd2 100644 --- a/components/libc/compilers/dlib/sys/types.h +++ b/components/libc/compilers/dlib/sys/types.h @@ -15,6 +15,10 @@ typedef rt_int32_t clockid_t; typedef rt_int32_t key_t; /* Used for interprocess communication. */ typedef rt_int32_t pid_t; /* Used for process IDs and process group IDs. */ -typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */ +#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 #endif diff --git a/components/libc/compilers/dlib/sys/unistd.h b/components/libc/compilers/dlib/sys/unistd.h index 5985a42996..9564daba8d 100644 --- a/components/libc/compilers/dlib/sys/unistd.h +++ b/components/libc/compilers/dlib/sys/unistd.h @@ -34,14 +34,10 @@ #define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */ #define _FNOCTTY 0x8000 /* don't assign a ctty on this open */ -#define O_RDONLY 0 /* +1 == FREAD */ -#define O_WRONLY 1 /* +1 == FWRITE */ -#define O_RDWR 2 /* +1 == FREAD|FWRITE */ -#define O_APPEND _FAPPEND -#define O_CREAT _FCREAT -#define O_TRUNC _FTRUNC -#define O_EXCL _FEXCL -#define O_SYNC _FSYNC #endif + +int isatty (int fd); +char * ttyname (int desc); + #endif /* _SYS_UNISTD_H */ diff --git a/components/libc/compilers/dlib/time.c b/components/libc/compilers/dlib/time.c deleted file mode 100644 index 87574df851..0000000000 --- a/components/libc/compilers/dlib/time.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include <sys/time.h> -#include <rtthread.h> - -#ifdef RT_USING_DEVICE -int gettimeofday(struct timeval *tp, void *ignore) -{ - time_t time; - rt_device_t device; - - device = rt_device_find("rtc"); - if (device != RT_NULL) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - if (tp != RT_NULL) - { - tp->tv_sec = time; - tp->tv_usec = 0; - } - - return time; - } - - return 0; -} -#endif - -/** - * Returns the current time. - * - * @param time_t * t the timestamp pointer, if not used, keep NULL. - * - * @return time_t return timestamp current. - * - */ -#pragma module_name = "?time" -#if _DLIB_TIME_USES_64 -time_t __time64(time_t *t) -#else -/* for IAR 6.2 later Compiler */ -#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 -time_t __time32(time_t *t) -#else -time_t time(time_t *t) -#endif -#endif -{ - time_t time_now = 0; - -#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 (rt_device_open(device, 0) == RT_EOK) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); - rt_device_close(device); - } - } -#endif /* RT_USING_RTC */ - - /* if t is not NULL, write timestamp to *t */ - if (t != RT_NULL) - { - *t = time_now; - } - - return time_now; -} - -RT_WEAK clock_t clock(void) -{ - return rt_tick_get(); -} diff --git a/components/libc/compilers/minilibc/SConscript b/components/libc/compilers/minilibc/SConscript index 518d800571..dec657028f 100644 --- a/components/libc/compilers/minilibc/SConscript +++ b/components/libc/compilers/minilibc/SConscript @@ -8,7 +8,7 @@ group = [] CPPPATH = [cwd] CPPDEFINES = ['RT_USING_MINILIBC'] -if rtconfig.PLATFORM == 'gcc' and rtconfig.ARCH != 'sim' and not GetDepend('RT_USING_LIBC'): +if rtconfig.PLATFORM == 'gcc' and rtconfig.ARCH != 'sim' and not GetDepend('RT_USING_LIBC') and GetDepend('RT_USING_MINILIBC'): group = DefineGroup('libc', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) diff --git a/components/libc/compilers/minilibc/math.h b/components/libc/compilers/minilibc/math.h index 9ddb9c859b..49b80d8219 100644 --- a/components/libc/compilers/minilibc/math.h +++ b/components/libc/compilers/minilibc/math.h @@ -14,4 +14,7 @@ double sin(double x); double cos(double x); +typedef float float_t; +typedef double double_t; + #endif diff --git a/components/libc/compilers/minilibc/signal.h b/components/libc/compilers/minilibc/signal.h new file mode 100644 index 0000000000..f52f1e1009 --- /dev/null +++ b/components/libc/compilers/minilibc/signal.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-09-12 Bernard The first version + */ + +#ifndef SIGNAL_H__ +#define SIGNAL_H__ + +#include <libc/libc_signal.h> + +#define SIG_DFL ((_sig_func_ptr)0) /* Default action */ +#define SIG_IGN ((_sig_func_ptr)1) /* Ignore action */ +#define SIG_ERR ((_sig_func_ptr)-1) /* Error return */ + +#endif diff --git a/components/libc/compilers/minilibc/sys/types.h b/components/libc/compilers/minilibc/sys/types.h index 0c00a79d1e..746235273c 100644 --- a/components/libc/compilers/minilibc/sys/types.h +++ b/components/libc/compilers/minilibc/sys/types.h @@ -8,18 +8,23 @@ */ #ifndef __TYPES_H__ #define __TYPES_H__ +#include <rtconfig.h> typedef long off_t; -typedef unsigned long size_t; -typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */ + +#ifndef ARCH_CPU_64BIT +typedef unsigned int size_t; +typedef signed int ssize_t; /* Used for a count of bytes or an error indication. */ +#else +typedef long unsigned int size_t; +typedef long signed int ssize_t; /* Used for a count of bytes or an error indication. */ +#endif typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; -typedef int mode_t; - typedef unsigned long clockid_t; typedef int pid_t; diff --git a/components/libc/compilers/minilibc/time.c b/components/libc/compilers/minilibc/time.c index 508558bafc..25e8f0e310 100644 --- a/components/libc/compilers/minilibc/time.c +++ b/components/libc/compilers/minilibc/time.c @@ -11,20 +11,20 @@ /* days per month -- nonleap! */ const short __spm[13] = - { 0, +{ 0, (31), - (31+28), - (31+28+31), - (31+28+31+30), - (31+28+31+30+31), - (31+28+31+30+31+30), - (31+28+31+30+31+30+31), - (31+28+31+30+31+30+31+31), - (31+28+31+30+31+30+31+31+30), - (31+28+31+30+31+30+31+31+30+31), - (31+28+31+30+31+30+31+31+30+31+30), - (31+28+31+30+31+30+31+31+30+31+30+31), - }; + (31 + 28), + (31 + 28 + 31), + (31 + 28 + 31 + 30), + (31 + 28 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30), + (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), +}; static long int timezone; static const char days[] = "Sun Mon Tue Wed Thu Fri Sat "; static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; @@ -34,196 +34,193 @@ static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; int __isleap(int year) { - /* every fourth year is a leap year except for century years that are - * not divisible by 400. */ - /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ - return (!(year % 4) && ((year % 100) || !(year % 400))); + /* every fourth year is a leap year except for century years that are + * not divisible by 400. */ + /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ + return (!(year % 4) && ((year % 100) || !(year % 400))); } struct tm *gmtime_r(const time_t *timep, struct tm *r) { - time_t i; - register time_t work = *timep % (SPD); - r->tm_sec = work % 60; - work /= 60; - r->tm_min = work % 60; - r->tm_hour = work / 60; - work = *timep / (SPD); - r->tm_wday = (4 + work) % 7; - for (i = 1970;; ++i) - { - register time_t k = __isleap(i) ? 366 : 365; - if (work >= k) - work -= k; - else - break; - } - r->tm_year = i - 1900; - r->tm_yday = work; + time_t i; + register time_t work = *timep % (SPD); + r->tm_sec = work % 60; + work /= 60; + r->tm_min = work % 60; + r->tm_hour = work / 60; + work = *timep / (SPD); + r->tm_wday = (4 + work) % 7; + for (i = 1970;; ++i) + { + register time_t k = __isleap(i) ? 366 : 365; + if (work >= k) + work -= k; + else + break; + } + r->tm_year = i - 1900; + r->tm_yday = work; - r->tm_mday = 1; - if (__isleap(i) && (work > 58)) - { - if (work == 59) - r->tm_mday = 2; /* 29.2. */ - work -= 1; - } + r->tm_mday = 1; + if (__isleap(i) && (work > 58)) + { + if (work == 59) + r->tm_mday = 2; /* 29.2. */ + work -= 1; + } - for (i = 11; i && (__spm[i] > work); --i) - ; - r->tm_mon = i; - r->tm_mday += work - __spm[i]; - return r; + for (i = 11; i && (__spm[i] > work); --i) + ; + r->tm_mon = i; + r->tm_mday += work - __spm[i]; + return r; } struct tm* localtime_r(const time_t* t, struct tm* r) { - time_t tmp; - struct timezone tz = {0}; - gettimeofday(0, &tz); - timezone = tz.tz_minuteswest * 60L; - tmp = *t + timezone; - return gmtime_r(&tmp, r); + time_t tmp; + struct timezone tz = {0}; + gettimeofday(0, &tz); + timezone = tz.tz_minuteswest * 60L; + tmp = *t + timezone; + return gmtime_r(&tmp, r); } struct tm* localtime(const time_t* t) { - static struct tm tmp; - return localtime_r(t, &tmp); + static struct tm tmp; + return localtime_r(t, &tmp); } time_t mktime(struct tm * const t) { - register time_t day; - register time_t i; - register time_t years = t->tm_year - 70; + register time_t day; + register time_t i; + register time_t years = t->tm_year - 70; - if (t->tm_sec > 60) - { - t->tm_min += t->tm_sec / 60; - t->tm_sec %= 60; - } - if (t->tm_min > 60) - { - t->tm_hour += t->tm_min / 60; - t->tm_min %= 60; - } - if (t->tm_hour > 24) - { - t->tm_mday += t->tm_hour / 24; - t->tm_hour %= 24; - } - if (t->tm_mon > 12) - { - t->tm_year += t->tm_mon / 12; - t->tm_mon %= 12; - } - while (t->tm_mday > __spm[1 + t->tm_mon]) - { - if (t->tm_mon == 1 && __isleap(t->tm_year + 1900)) - { - --t->tm_mday; - } - t->tm_mday -= __spm[t->tm_mon]; - ++t->tm_mon; - if (t->tm_mon > 11) - { - t->tm_mon = 0; - ++t->tm_year; - } - } + if (t->tm_sec > 60) + { + t->tm_min += t->tm_sec / 60; + t->tm_sec %= 60; + } + if (t->tm_min > 60) + { + t->tm_hour += t->tm_min / 60; + t->tm_min %= 60; + } + if (t->tm_hour > 24) + { + t->tm_mday += t->tm_hour / 24; + t->tm_hour %= 24; + } + if (t->tm_mon > 12) + { + t->tm_year += t->tm_mon / 12; + t->tm_mon %= 12; + } + while (t->tm_mday > __spm[1 + t->tm_mon]) + { + if (t->tm_mon == 1 && __isleap(t->tm_year + 1900)) + { + --t->tm_mday; + } + t->tm_mday -= __spm[t->tm_mon]; + ++t->tm_mon; + if (t->tm_mon > 11) + { + t->tm_mon = 0; + ++t->tm_year; + } + } - if (t->tm_year < 70) - return (time_t) -1; + if (t->tm_year < 70) + return (time_t) - 1; - /* Days since 1970 is 365 * number of years + number of leap years since 1970 */ - day = years * 365 + (years + 1) / 4; + /* Days since 1970 is 365 * number of years + number of leap years since 1970 */ + day = years * 365 + (years + 1) / 4; - /* After 2100 we have to substract 3 leap years for every 400 years - This is not intuitive. Most mktime implementations do not support - dates after 2059, anyway, so we might leave this out for it's - bloat. */ - if (years >= 131) - { - years -= 131; - years /= 100; - day -= (years >> 2) * 3 + 1; - if ((years &= 3) == 3) - years--; - day -= years; - } + /* After 2100 we have to substract 3 leap years for every 400 years + This is not intuitive. Most mktime implementations do not support + dates after 2059, anyway, so we might leave this out for it's + bloat. */ + if (years >= 131) + { + years -= 131; + years /= 100; + day -= (years >> 2) * 3 + 1; + if ((years &= 3) == 3) + years--; + day -= years; + } - day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 + - (__isleap(t->tm_year + 1900) & (t->tm_mon > 1)); + day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 + + (__isleap(t->tm_year + 1900) & (t->tm_mon > 1)); - /* day is now the number of days since 'Jan 1 1970' */ - i = 7; - t->tm_wday = (day + 4) % i; /* Sunday=0, Monday=1, ..., Saturday=6 */ + /* day is now the number of days since 'Jan 1 1970' */ + i = 7; + t->tm_wday = (day + 4) % i; /* Sunday=0, Monday=1, ..., Saturday=6 */ - i = 24; - day *= i; - i = 60; - return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec; + i = 24; + day *= i; + i = 60; + return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec; } static void num2str(char *c, int i) { - c[0] = i / 10 + '0'; - c[1] = i % 10 + '0'; + c[0] = i / 10 + '0'; + c[1] = i % 10 + '0'; } char *asctime_r(const struct tm *t, char *buf) { - /* "Wed Jun 30 21:49:08 1993\n" */ - *(int*) buf = *(int*) (days + (t->tm_wday << 2)); - *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2)); - num2str(buf + 8, t->tm_mday); - if (buf[8] == '0') - buf[8] = ' '; - buf[10] = ' '; - num2str(buf + 11, t->tm_hour); - buf[13] = ':'; - num2str(buf + 14, t->tm_min); - buf[16] = ':'; - num2str(buf + 17, t->tm_sec); - buf[19] = ' '; - num2str(buf + 20, (t->tm_year + 1900) / 100); - num2str(buf + 22, (t->tm_year + 1900) % 100); - buf[24] = '\n'; - return buf; + /* "Wed Jun 30 21:49:08 1993\n" */ + *(int*) buf = *(int*) (days + (t->tm_wday << 2)); + *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2)); + num2str(buf + 8, t->tm_mday); + if (buf[8] == '0') + buf[8] = ' '; + buf[10] = ' '; + num2str(buf + 11, t->tm_hour); + buf[13] = ':'; + num2str(buf + 14, t->tm_min); + buf[16] = ':'; + num2str(buf + 17, t->tm_sec); + buf[19] = ' '; + num2str(buf + 20, (t->tm_year + 1900) / 100); + num2str(buf + 22, (t->tm_year + 1900) % 100); + buf[24] = '\n'; + return buf; } char *asctime(const struct tm *timeptr) { - static char buf[25]; - return asctime_r(timeptr, buf); + static char buf[25]; + return asctime_r(timeptr, buf); } char *ctime(const time_t *timep) { - return asctime(localtime(timep)); + return asctime(localtime(timep)); } #ifdef RT_USING_DEVICE int gettimeofday(struct timeval *tp, void *ignore) { - time_t time; - rt_device_t device; + time_t time; + rt_device_t device; - device = rt_device_find("rtc"); - if (device != RT_NULL) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - if (tp != RT_NULL) - { - tp->tv_sec = time; - tp->tv_usec = 0; - } + device = rt_device_find("rtc"); + RT_ASSERT(device != RT_NULL); - return time; - } + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + if (tp != RT_NULL) + { + tp->tv_sec = time; + tp->tv_usec = 0; + } - return 0; + return time; } #endif diff --git a/components/libc/compilers/newlib/README.md b/components/libc/compilers/newlib/README.md new file mode 100644 index 0000000000..385f329a4f --- /dev/null +++ b/components/libc/compilers/newlib/README.md @@ -0,0 +1,9 @@ +# NEWLIB (GCC) porting for RT-Thread + +Please define RT_USING_LIBC and compile RT-Thread with GCC compiler. + + + +## More Information + +https://sourceware.org/newlib/libc.html#Reentrancy
\ No newline at end of file diff --git a/components/libc/compilers/newlib/libc.h b/components/libc/compilers/newlib/libc.h index ab9334fe26..fdf2ab4f60 100644 --- a/components/libc/compilers/newlib/libc.h +++ b/components/libc/compilers/newlib/libc.h @@ -27,13 +27,19 @@ #define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) #define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#ifdef __cplusplus +extern "C" { +#endif int libc_system_init(void); int libc_stdio_set_console(const char* device_name, int mode); int libc_stdio_get_console(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); +int libc_set_time(const struct timespec* time); +int libc_get_time(struct timespec* time); +int libc_time_to_tick(const struct timespec* time); +#ifdef __cplusplus +} +#endif #endif diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c index e4cda478cb..228fa0d140 100644 --- a/components/libc/compilers/newlib/syscalls.c +++ b/components/libc/compilers/newlib/syscalls.c @@ -9,22 +9,28 @@ #include <reent.h> #include <sys/errno.h> #include <sys/time.h> +#include <stdio.h> + #include <rtthread.h> #ifdef RT_USING_DFS #include <dfs_posix.h> #endif -#ifdef RT_USING_PTHREADS -#include <pthread.h> -#endif - #ifdef RT_USING_MODULE #include <dlmodule.h> #endif /* Reentrant versions of system calls. */ +#ifndef _REENT_ONLY +int * +__errno () +{ + return _rt_errno(); +} +#endif + int _close_r(struct _reent *ptr, int fd) { @@ -218,7 +224,7 @@ _ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) { #ifndef RT_USING_DFS - if (fd == 0) + if (fileno(stdout) == fd) { rt_device_t console; @@ -432,3 +438,18 @@ void abort(void) while (1); } + +uid_t getuid(void) +{ + return 0; +} + +mode_t umask(mode_t mask) +{ + return 022; +} + +int flock(int fd, int operation) +{ + return 0; +} diff --git a/components/libc/compilers/newlib/time.c b/components/libc/compilers/newlib/time.c deleted file mode 100644 index 29c5c6cdd2..0000000000 --- a/components/libc/compilers/newlib/time.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include <sys/time.h> -#include <rtthread.h> - -#ifdef RT_USING_DEVICE -int gettimeofday(struct timeval *tp, void *ignore) -{ - time_t time; - rt_device_t device; - - device = rt_device_find("rtc"); - if (device != RT_NULL) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - if (tp != RT_NULL) - { - tp->tv_sec = time; - tp->tv_usec = 0; - } - - return time; - } - - return 0; -} -#endif - -/** - * Returns the current time. - * - * @param time_t * t the timestamp pointer, if not used, keep NULL. - * - * @return time_t return timestamp current. - * - */ -/* for IAR 6.2 later Compiler */ -#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 -#pragma module_name = "?time" -time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */ -#else -time_t time(time_t *t) -#endif -{ - time_t time_now = 0; - -#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 (rt_device_open(device, 0) == RT_EOK) - { - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); - rt_device_close(device); - } - } -#endif /* RT_USING_RTC */ - - /* if t is not NULL, write timestamp to *t */ - if (t != RT_NULL) - { - *t = time_now; - } - - return time_now; -} - -RT_WEAK clock_t clock(void) -{ - return rt_tick_get(); -} diff --git a/components/libc/getline/README.md b/components/libc/getline/README.md new file mode 100644 index 0000000000..0b279755d3 --- /dev/null +++ b/components/libc/getline/README.md @@ -0,0 +1,30 @@ +# getline/getdelim for RT-Thread POSIX(IEEE Std 1003.1-2008) + +[](https://travis-ci.org/ivanrad/getline) + +https://github.com/ivanrad/getline + +Read a delimited record from stream. + +Yet another (hopefully portable C) implementation of getline/getdelim. +These are ersatz functions, a drop-in replacement, to be used on those occasions when your C library does not already support them. + +For more details, see [Open Group Base Specification for getdelim/getline][opengroup-spec]. + + + +## License + +This code is unlicensed -- free and released into the public domain. See `UNLICENSE` file for more information. + +[opengroup-spec]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html + + + + +## 联系&维护 +Meco Man + + +https://github.com/mysterywolf/getline diff --git a/components/libc/getline/SConscript b/components/libc/getline/SConscript new file mode 100644 index 0000000000..fa4c8618c1 --- /dev/null +++ b/components/libc/getline/SConscript @@ -0,0 +1,13 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('libc', src, + depend = ['RT_USING_LIBC', 'RT_USING_POSIX','RT_USING_POSIX_GETLINE'], + CPPPATH = CPPPATH) + +Return('group') diff --git a/components/libc/getline/UNLICENSE b/components/libc/getline/UNLICENSE new file mode 100644 index 0000000000..68a49daad8 --- /dev/null +++ b/components/libc/getline/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to <http://unlicense.org/> diff --git a/components/libc/getline/posix_getline.c b/components/libc/getline/posix_getline.c new file mode 100644 index 0000000000..e2ac278242 --- /dev/null +++ b/components/libc/getline/posix_getline.c @@ -0,0 +1,79 @@ +/* posix_getline.c + * RT-Thread POSIX + * getdelim(), getline() - read a delimited record from stream, ersatz implementation + * This code is unlicensed -- free and released into the public domain. + * https://man7.org/linux/man-pages/man3/getline.3.html + * Authors: + * https://github.com/ivanrad/getline + * https://github.com/mysterywolf/getline/ + * + * Meco Man 2020-09-03 First Version + */ + +#include "posix_getline.h" +#include <stdlib.h> +#include <errno.h> +#include <rtlibc.h> + +ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream) { + char *cur_pos, *new_lineptr; + size_t new_lineptr_len; + int c; + + if (lineptr == NULL || n == NULL || stream == NULL) { + errno = EINVAL; + return -1; + } + + if (*lineptr == NULL) { + *n = 128; /* init len */ + if ((*lineptr = (char *)malloc(*n)) == NULL) { + errno = ENOMEM; + return -1; + } + } + + cur_pos = *lineptr; + for (;;) { + c = getc(stream); + + if (ferror(stream) || (c == EOF && cur_pos == *lineptr)) + return -1; + + if (c == EOF) + break; + + if ((*lineptr + *n - cur_pos) < 2) { + if (SSIZE_MAX / 2 < *n) { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else + errno = ERANGE; /* no EOVERFLOW defined */ +#endif + return -1; + } + new_lineptr_len = *n * 2; + + if ((new_lineptr = (char *)realloc(*lineptr, new_lineptr_len)) == NULL) { + errno = ENOMEM; + return -1; + } + cur_pos = new_lineptr + (cur_pos - *lineptr); + *lineptr = new_lineptr; + *n = new_lineptr_len; + } + + *cur_pos++ = (char)c; + + if (c == delim) + break; + } + + *cur_pos = '\0'; + return (ssize_t)(cur_pos - *lineptr); +} + +ssize_t getline(char **lineptr, size_t *n, FILE *stream) { + return getdelim(lineptr, n, '\n', stream); +} + diff --git a/components/libc/getline/posix_getline.h b/components/libc/getline/posix_getline.h new file mode 100644 index 0000000000..c7d6021af3 --- /dev/null +++ b/components/libc/getline/posix_getline.h @@ -0,0 +1,24 @@ +/* posix_getline.h + * RT-Thread POSIX + * getdelim(), getline() - read a delimited record from stream, ersatz implementation + * This code is unlicensed -- free and released into the public domain. + * https://man7.org/linux/man-pages/man3/getline.3.html + * Authors: + * https://github.com/ivanrad/getline + * https://github.com/mysterywolf/getline/ + * + * Meco Man 2020-09-03 First Version + */ + + +#ifndef POSIX_GETLINE_H +#define POSIX_GETLINE_H + +#include <stdio.h> +#include <sys/types.h> + +ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); +ssize_t getline(char **lineptr, size_t *n, FILE *stream); + +#endif /* POSIX_GETLINE_H */ + diff --git a/components/libc/libdl/dlelf.c b/components/libc/libdl/dlelf.c index 6d83424b80..55ef0d8951 100644 --- a/components/libc/libdl/dlelf.c +++ b/components/libc/libdl/dlelf.c @@ -11,10 +11,8 @@ #include "dlmodule.h" #include "dlelf.h" -#define DBG_SECTION_NAME "DLMD" -#define DBG_ENABLE // enable debug macro -#define DBG_LEVEL DBG_INFO -#define DBG_COLOR +#define DBG_TAG "DLMD" +#define DBG_LVL DBG_INFO #include <rtdbg.h> // must after of DEBUG_ENABLE or some other options rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_ptr) @@ -228,6 +226,40 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt length); count ++; } + + /* get priority & stack size params*/ + rt_uint32_t flag = 0; + rt_uint16_t priority; + rt_uint32_t stacksize; + for (i = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + { + if (((flag & 0x01) == 0) && + (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_priority") == 0)) + { + flag |= 0x01; + priority = *(rt_uint16_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr); + if (priority < RT_THREAD_PRIORITY_MAX) + { + module->priority = priority; + } + } + + if (((flag & 0x02) == 0) && + (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_stacksize") == 0)) + { + flag |= 0x02; + stacksize = *(rt_uint32_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr); + if ((stacksize < 2048) || (stacksize > 1024 * 32)) + { + module->stack_size = stacksize; + } + } + + if ((flag & 0x03) == 0x03) + { + break; + } + } } return RT_EOK; diff --git a/components/libc/libdl/dlmodule.c b/components/libc/libdl/dlmodule.c index 61ffbfc772..314cf52709 100644 --- a/components/libc/libdl/dlmodule.c +++ b/components/libc/libdl/dlmodule.c @@ -14,12 +14,12 @@ #include "dlmodule.h" #include "dlelf.h" +#if defined(RT_USING_POSIX) #include <dfs_posix.h> +#endif -#define DBG_SECTION_NAME "DLMD" -#define DBG_ENABLE // enable debug macro -#define DBG_LEVEL DBG_INFO -#define DBG_COLOR +#define DBG_TAG "DLMD" +#define DBG_LVL DBG_INFO #include <rtdbg.h> // must after of DEBUG_ENABLE or some other options static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL; @@ -124,7 +124,7 @@ static void _dlmodule_exit(void) rt_thread_t thread = (rt_thread_t)object; /* stop timer and suspend thread*/ - if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE || + if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE && (thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT) { rt_timer_stop(&(thread->thread_timer)); @@ -421,11 +421,14 @@ struct rt_dlmodule *rt_module_self(void) struct rt_dlmodule* dlmodule_load(const char* filename) { - int fd, length = 0; +#if defined(RT_USING_POSIX) + int fd = -1, length = 0; +#endif rt_err_t ret = RT_EOK; rt_uint8_t *module_ptr = RT_NULL; struct rt_dlmodule *module = RT_NULL; +#if defined(RT_USING_POSIX) fd = open(filename, O_RDONLY, 0); if (fd >= 0) { @@ -444,6 +447,13 @@ struct rt_dlmodule* dlmodule_load(const char* filename) close(fd); fd = -1; } + else + { + goto __exit; + } +#endif + + if (!module_ptr) goto __exit; /* check ELF header */ if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && @@ -510,7 +520,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename) return module; __exit: +#if defined(RT_USING_POSIX) if (fd >= 0) close(fd); +#endif if (module_ptr) rt_free(module_ptr); if (module) dlmodule_destroy(module); @@ -556,6 +568,184 @@ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_s return module; } +#if defined(RT_USING_CUSTOM_DLMODULE) +struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops) +{ +#if defined(RT_USING_POSIX) + int fd = -1, length = 0; +#endif + rt_err_t ret = RT_EOK; + rt_uint8_t *module_ptr = RT_NULL; + struct rt_dlmodule *module = RT_NULL; + + if (ops) + { + RT_ASSERT(ops->load); + RT_ASSERT(ops->unload); + module_ptr = ops->load(filename); + } +#if defined(RT_USING_POSIX) + else + { + fd = open(filename, O_RDONLY, 0); + if (fd >= 0) + { + length = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + + if (length == 0) goto __exit; + + module_ptr = (uint8_t*) rt_malloc (length); + if (!module_ptr) goto __exit; + + if (read(fd, module_ptr, length) != length) + goto __exit; + + /* close file and release fd */ + close(fd); + fd = -1; + } + else + { + goto __exit; + } + } +#endif + + if (!module_ptr) goto __exit; + + /* check ELF header */ + if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && + rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0) + { + rt_kprintf("Module: magic error\n"); + goto __exit; + } + + /* check ELF class */ + if (elf_module->e_ident[EI_CLASS] != ELFCLASS32) + { + rt_kprintf("Module: ELF class error\n"); + goto __exit; + } + + module = dlmodule_create(); + if (!module) goto __exit; + + /* set the name of module */ + _dlmodule_set_name(module, filename); + + LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name); + + if (elf_module->e_type == ET_REL) + { + ret = dlmodule_load_relocated_object(module, module_ptr); + } + else if (elf_module->e_type == ET_DYN) + { + ret = dlmodule_load_shared_object(module, module_ptr); + } + else + { + rt_kprintf("Module: unsupported elf type\n"); + goto __exit; + } + + /* check return value */ + if (ret != RT_EOK) goto __exit; + + /* release module data */ + if (ops) + { + ops->unload(module_ptr); + } + else + { + rt_free(module_ptr); + } + + /* increase module reference count */ + module->nref ++; + + /* deal with cache */ +#ifdef RT_USING_CACHE + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size); + rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size); +#endif + + /* set module initialization and cleanup function */ + module->init_func = dlsym(module, "module_init"); + module->cleanup_func = dlsym(module, "module_cleanup"); + module->stat = RT_DLMODULE_STAT_INIT; + /* do module initialization */ + if (module->init_func) + { + module->init_func(module); + } + + return module; + +__exit: +#if defined(RT_USING_POSIX) + if (fd >= 0) close(fd); +#endif + if (module_ptr) + { + if (ops) + { + ops->unload(module_ptr); + } + else + { + rt_free(module_ptr); + } + } + + if (module) dlmodule_destroy(module); + + return RT_NULL; +} + +struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops) +{ + struct rt_dlmodule *module = RT_NULL; + + module = dlmodule_load_custom(pgname, ops); + if (module) + { + if (module->entry_addr) + { + /* exec this module */ + rt_thread_t tid; + + module->cmd_line = rt_strdup(cmd); + + /* check stack size and priority */ + if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1; + if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048; + + tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module, + module->stack_size, module->priority, 10); + if (tid) + { + tid->module_id = module; + module->main_thread = tid; + + rt_thread_startup(tid); + } + else + { + /* destory dl module */ + dlmodule_destroy(module); + module = RT_NULL; + } + } + } + + return module; +} +#endif + void dlmodule_exit(int ret_code) { rt_thread_t thread; diff --git a/components/libc/libdl/dlmodule.h b/components/libc/libdl/dlmodule.h index 4a4ead3303..b366c7603e 100644 --- a/components/libc/libdl/dlmodule.h +++ b/components/libc/libdl/dlmodule.h @@ -59,6 +59,12 @@ struct rt_dlmodule struct rt_module_symtab *symtab; /* module symbol table */ }; +struct rt_dlmodule_ops +{ + rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */ + rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */ +}; + struct rt_dlmodule *dlmodule_create(void); rt_err_t dlmodule_destroy(struct rt_dlmodule* module); @@ -66,6 +72,12 @@ struct rt_dlmodule *dlmodule_self(void); struct rt_dlmodule *dlmodule_load(const char* pgname); struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size); + +#if defined(RT_USING_CUSTOM_DLMODULE) +struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops); +struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops); +#endif + void dlmodule_exit(int ret_code); struct rt_dlmodule *dlmodule_find(const char *name); diff --git a/components/libc/mmap/posix_mmap.c b/components/libc/mmap/posix_mmap.c index 3d405aad77..a16ace8306 100644 --- a/components/libc/mmap/posix_mmap.c +++ b/components/libc/mmap/posix_mmap.c @@ -35,7 +35,7 @@ void *mmap(void *addr, size_t length, int prot, int flags, cur = lseek(fd, 0, SEEK_SET); lseek(fd, offset, SEEK_SET); - read_bytes = read(fd, addr, length); + read_bytes = read(fd, mem, length); if (read_bytes != length) { if (addr == RT_NULL) diff --git a/components/libc/pthreads/SConscript b/components/libc/pthreads/SConscript index 1b7b75bfd1..e154ee0aa9 100644 --- a/components/libc/pthreads/SConscript +++ b/components/libc/pthreads/SConscript @@ -1,10 +1,22 @@ from building import * +from utils import VersionCmp -cwd = GetCurrentDir() -src = Glob('*.c') -CPPPATH = [cwd] +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] +CPPDEFINES = [] + +# only enable POSIX.1b-1993 Real-time extensions +libc_ver = GetDepend('LIBC_VERSION') +try: + ver = libc_ver.split(' ') + ver = ver[1] + if VersionCmp(ver, "2.5.0") == 1: + CPPDEFINES = ['_POSIX_C_SOURCE=199309L'] +except : + pass group = DefineGroup('pthreads', src, - depend = ['RT_USING_PTHREADS', 'RT_USING_LIBC'], CPPPATH = CPPPATH) + depend = ['RT_USING_PTHREADS', 'RT_USING_LIBC'], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) Return('group') diff --git a/components/libc/pthreads/pthread.c b/components/libc/pthreads/pthread.c index 62c110499d..19a511b45b 100644 --- a/components/libc/pthreads/pthread.c +++ b/components/libc/pthreads/pthread.c @@ -7,12 +7,124 @@ * Date Author Notes * 2018-01-26 Bernard Fix pthread_detach issue for a none-joinable * thread. + * 2019-02-07 Bernard Add _pthread_destroy to release pthread resource. */ +#include <rthw.h> #include <pthread.h> #include <sched.h> #include "pthread_internal.h" +RT_DEFINE_SPINLOCK(pth_lock); +_pthread_data_t *pth_table[PTHREAD_NUM_MAX] = {NULL}; + +_pthread_data_t *_pthread_get_data(pthread_t thread) +{ + RT_DECLARE_SPINLOCK(pth_lock); + _pthread_data_t *ptd; + + if (thread >= PTHREAD_NUM_MAX) return NULL; + + rt_hw_spin_lock(&pth_lock); + ptd = pth_table[thread]; + rt_hw_spin_unlock(&pth_lock); + + if (ptd && ptd->magic == PTHREAD_MAGIC) return ptd; + + return NULL; +} + +pthread_t _pthread_data_get_pth(_pthread_data_t *ptd) +{ + int index; + RT_DECLARE_SPINLOCK(pth_lock); + + rt_hw_spin_lock(&pth_lock); + for (index = 0; index < PTHREAD_NUM_MAX; index ++) + { + if (pth_table[index] == ptd) break; + } + rt_hw_spin_unlock(&pth_lock); + + return index; +} + +pthread_t _pthread_data_create(void) +{ + int index; + _pthread_data_t *ptd = NULL; + RT_DECLARE_SPINLOCK(pth_lock); + + ptd = (_pthread_data_t*)rt_malloc(sizeof(_pthread_data_t)); + if (!ptd) return PTHREAD_NUM_MAX; + + memset(ptd, 0x0, sizeof(_pthread_data_t)); + ptd->canceled = 0; + ptd->cancelstate = PTHREAD_CANCEL_DISABLE; + ptd->canceltype = PTHREAD_CANCEL_DEFERRED; + ptd->magic = PTHREAD_MAGIC; + + rt_hw_spin_lock(&pth_lock); + for (index = 0; index < PTHREAD_NUM_MAX; index ++) + { + if (pth_table[index] == NULL) + { + pth_table[index] = ptd; + break; + } + } + rt_hw_spin_unlock(&pth_lock); + + /* full of pthreads, clean magic and release ptd */ + if (index == PTHREAD_NUM_MAX) + { + ptd->magic = 0x0; + rt_free(ptd); + } + + return index; +} + +void _pthread_data_destroy(pthread_t pth) +{ + RT_DECLARE_SPINLOCK(pth_lock); + + _pthread_data_t *ptd = _pthread_get_data(pth); + if (ptd) + { + /* remove from pthread table */ + rt_hw_spin_lock(&pth_lock); + pth_table[pth] = NULL; + rt_hw_spin_unlock(&pth_lock); + + /* delete joinable semaphore */ + if (ptd->joinable_sem != RT_NULL) + rt_sem_delete(ptd->joinable_sem); + + /* release thread resource */ + if (ptd->attr.stackaddr == RT_NULL && ptd->tid->stack_addr != RT_NULL) + { + /* release thread allocated stack */ + rt_free(ptd->tid->stack_addr); + } + /* clean stack addr pointer */ + ptd->tid->stack_addr = RT_NULL; + + /* + * if this thread create the local thread data, + * delete it + */ + if (ptd->tls != RT_NULL) rt_free(ptd->tls); + rt_free(ptd->tid); + + /* clean magic */ + ptd->magic = 0x0; + + /* free ptd */ + rt_free(ptd); + } +} + int pthread_system_init(void) { /* initialize key area */ @@ -26,10 +138,24 @@ int pthread_system_init(void) } INIT_COMPONENT_EXPORT(pthread_system_init); +static void _pthread_destroy(_pthread_data_t *ptd) +{ + pthread_t pth = _pthread_data_get_pth(ptd); + if (pth != PTHREAD_NUM_MAX) + { + _pthread_data_destroy(pth); + } + + return; +} + static void _pthread_cleanup(rt_thread_t tid) { _pthread_data_t *ptd; - ptd = _pthread_get_data(tid); + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)tid->user_data; + RT_ASSERT(ptd != RT_NULL); /* clear cleanup function */ tid->cleanup = RT_NULL; @@ -40,14 +166,14 @@ static void _pthread_cleanup(rt_thread_t tid) else { /* release pthread resource */ - pthread_detach(tid); + _pthread_destroy(ptd); } } static void pthread_entry_stub(void *parameter) { - _pthread_data_t *ptd; void *value; + _pthread_data_t *ptd; ptd = (_pthread_data_t *)parameter; @@ -57,29 +183,30 @@ static void pthread_entry_stub(void *parameter) ptd->return_value = value; } -int pthread_create(pthread_t *tid, +int pthread_create(pthread_t *pid, const pthread_attr_t *attr, void *(*start)(void *), void *parameter) { - int result; + int ret = 0; void *stack; char name[RT_NAME_MAX]; static rt_uint16_t pthread_number = 0; + + pthread_t pth_id; _pthread_data_t *ptd; - /* tid shall be provided */ - RT_ASSERT(tid != RT_NULL); + /* pid shall be provided */ + RT_ASSERT(pid != RT_NULL); /* allocate posix thread data */ - ptd = (_pthread_data_t *)rt_malloc(sizeof(_pthread_data_t)); - if (ptd == RT_NULL) - return ENOMEM; - /* clean posix thread data memory */ - rt_memset(ptd, 0, sizeof(_pthread_data_t)); - ptd->canceled = 0; - ptd->cancelstate = PTHREAD_CANCEL_DISABLE; - ptd->canceltype = PTHREAD_CANCEL_DEFERRED; - ptd->magic = PTHREAD_MAGIC; + pth_id = _pthread_data_create(); + if (pth_id == PTHREAD_NUM_MAX) + { + ret = ENOMEM; + goto __exit; + } + /* get pthread data */ + ptd = _pthread_get_data(pth_id); if (attr != RT_NULL) { @@ -92,43 +219,23 @@ int pthread_create(pthread_t *tid, } rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++); - if (ptd->attr.stack_base == 0) - { - stack = (void *)rt_malloc(ptd->attr.stack_size); - } - else - { - stack = (void *)(ptd->attr.stack_base); - } - - if (stack == RT_NULL) - { - rt_free(ptd); - - return ENOMEM; - } /* pthread is a static thread object */ ptd->tid = (rt_thread_t) rt_malloc(sizeof(struct rt_thread)); if (ptd->tid == RT_NULL) { - if (ptd->attr.stack_base == 0) - rt_free(stack); - rt_free(ptd); - - return ENOMEM; + ret = ENOMEM; + goto __exit; } + memset(ptd->tid, 0, sizeof(struct rt_thread)); if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE) { ptd->joinable_sem = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO); if (ptd->joinable_sem == RT_NULL) { - if (ptd->attr.stack_base != 0) - rt_free(stack); - rt_free(ptd); - - return ENOMEM; + ret = ENOMEM; + goto __exit; } } else @@ -140,101 +247,109 @@ int pthread_create(pthread_t *tid, ptd->thread_entry = start; ptd->thread_parameter = parameter; + /* stack */ + if (ptd->attr.stackaddr == 0) + { + stack = (void *)rt_malloc(ptd->attr.stacksize); + } + else + { + stack = (void *)(ptd->attr.stackaddr); + } + + if (stack == RT_NULL) + { + ret = ENOMEM; + goto __exit; + } + /* initial this pthread to system */ if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd, - stack, ptd->attr.stack_size, - ptd->attr.priority, 5) != RT_EOK) + stack, ptd->attr.stacksize, + ptd->attr.schedparam.sched_priority, 5) != RT_EOK) { - if (ptd->attr.stack_base == 0) - rt_free(stack); - if (ptd->joinable_sem != RT_NULL) - rt_sem_delete(ptd->joinable_sem); - rt_free(ptd); - - return EINVAL; + ret = EINVAL; + goto __exit; } /* set pthread id */ - *tid = ptd->tid; + *pid = pth_id; /* set pthread cleanup function and ptd data */ - (*tid)->cleanup = _pthread_cleanup; - (*tid)->user_data = (rt_uint32_t)ptd; + ptd->tid->cleanup = _pthread_cleanup; + ptd->tid->user_data = (rt_ubase_t)ptd; /* start thread */ - result = rt_thread_startup(*tid); - if (result == RT_EOK) + if (rt_thread_startup(ptd->tid) == RT_EOK) return 0; /* start thread failed */ rt_thread_detach(ptd->tid); - if (ptd->attr.stack_base == 0) - rt_free(stack); - if (ptd->joinable_sem != RT_NULL) - rt_sem_delete(ptd->joinable_sem); + ret = EINVAL; - rt_free(ptd); - - return EINVAL; +__exit: + if (pth_id != PTHREAD_NUM_MAX) + _pthread_data_destroy(pth_id); + return ret; } RTM_EXPORT(pthread_create); int pthread_detach(pthread_t thread) { - _pthread_data_t *ptd; - - ptd = _pthread_get_data(thread); + int ret = 0; + _pthread_data_t *ptd = _pthread_get_data(thread); + rt_enter_critical(); if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED) { /* The implementation has detected that the value specified by thread does not refer * to a joinable thread. */ - return EINVAL; + ret = EINVAL; + goto __exit; } - if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE) + if ((ptd->tid->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE) { - /* delete joinable semaphore */ - if (ptd->joinable_sem != RT_NULL) - rt_sem_delete(ptd->joinable_sem); - /* detach thread object */ - rt_thread_detach(ptd->tid); - - /* release thread resource */ - if (ptd->attr.stack_base == RT_NULL) + /* this defunct pthread is not handled by idle */ + if (rt_sem_trytake(ptd->joinable_sem) != RT_EOK) { - /* release thread allocated stack */ - rt_free(ptd->tid->stack_addr); + rt_sem_release(ptd->joinable_sem); + + /* change to detach state */ + ptd->attr.detachstate = PTHREAD_CREATE_DETACHED; + + /* detach joinable semaphore */ + if (ptd->joinable_sem) + { + rt_sem_delete(ptd->joinable_sem); + ptd->joinable_sem = RT_NULL; + } } else { - /* clean stack addr pointer */ - ptd->tid->stack_addr = RT_NULL; + /* destroy this pthread */ + _pthread_destroy(ptd); } - /* - * if this thread create the local thread data, - * delete it - */ - if (ptd->tls != RT_NULL) - rt_free(ptd->tls); - rt_free(ptd->tid); - rt_free(ptd); + goto __exit; } else { - rt_enter_critical(); /* change to detach state */ ptd->attr.detachstate = PTHREAD_CREATE_DETACHED; /* detach joinable semaphore */ - rt_sem_delete(ptd->joinable_sem); - ptd->joinable_sem = RT_NULL; - rt_exit_critical(); + if (ptd->joinable_sem) + { + rt_sem_delete(ptd->joinable_sem); + ptd->joinable_sem = RT_NULL; + } } - return 0; +__exit: + rt_exit_critical(); + return ret; } RTM_EXPORT(pthread_detach); @@ -243,13 +358,13 @@ int pthread_join(pthread_t thread, void **value_ptr) _pthread_data_t *ptd; rt_err_t result; - if (thread == rt_thread_self()) + ptd = _pthread_get_data(thread); + if (ptd && ptd->tid == rt_thread_self()) { /* join self */ return EDEADLK; } - ptd = _pthread_get_data(thread); if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED) return EINVAL; /* join on a detached pthread */ @@ -260,8 +375,8 @@ int pthread_join(pthread_t thread, void **value_ptr) if (value_ptr != RT_NULL) *value_ptr = ptd->return_value; - /* release resource */ - pthread_detach(thread); + /* destroy this pthread */ + _pthread_destroy(ptd); } else { @@ -272,13 +387,32 @@ int pthread_join(pthread_t thread, void **value_ptr) } RTM_EXPORT(pthread_join); +pthread_t pthread_self (void) +{ + rt_thread_t tid; + _pthread_data_t *ptd; + + tid = rt_thread_self(); + if (tid == NULL) return PTHREAD_NUM_MAX; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; + RT_ASSERT(ptd != RT_NULL); + + return _pthread_data_get_pth(ptd); +} +RTM_EXPORT(pthread_self); + void pthread_exit(void *value) { _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; extern _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX]; - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; rt_enter_critical(); /* disable cancel */ @@ -319,12 +453,6 @@ void pthread_exit(void *value) ptd->tls = RT_NULL; } - if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE) - { - /* release the joinable pthread */ - rt_sem_release(ptd->joinable_sem); - } - /* detach thread */ rt_thread_detach(ptd->tid); /* reschedule thread */ @@ -361,7 +489,15 @@ RTM_EXPORT(pthread_atfork); int pthread_kill(pthread_t thread, int sig) { #ifdef RT_USING_SIGNALS - return rt_thread_kill(thread, sig); + _pthread_data_t *ptd; + + ptd = _pthread_get_data(thread); + if (ptd) + { + return rt_thread_kill(ptd->tid, sig); + } + + return EINVAL; #else return ENOSYS; #endif @@ -380,8 +516,10 @@ void pthread_cleanup_pop(int execute) _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; - /* get posix thread data */ - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != RT_NULL); if (execute) @@ -407,8 +545,10 @@ void pthread_cleanup_push(void (*routine)(void *), void *arg) _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; - /* get posix thread data */ - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != RT_NULL); cleanup = (_pthread_cleanup_t *)rt_malloc(sizeof(_pthread_cleanup_t)); @@ -457,8 +597,10 @@ int pthread_setcancelstate(int state, int *oldstate) { _pthread_data_t *ptd; - /* get posix thread data */ - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return EINVAL; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != RT_NULL); if ((state == PTHREAD_CANCEL_ENABLE) || (state == PTHREAD_CANCEL_DISABLE)) @@ -478,8 +620,10 @@ int pthread_setcanceltype(int type, int *oldtype) { _pthread_data_t *ptd; - /* get posix thread data */ - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return EINVAL; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != RT_NULL); if ((type != PTHREAD_CANCEL_DEFERRED) && (type != PTHREAD_CANCEL_ASYNCHRONOUS)) @@ -498,8 +642,10 @@ void pthread_testcancel(void) int cancel = 0; _pthread_data_t *ptd; - /* get posix thread data */ - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != RT_NULL); if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE) @@ -513,14 +659,14 @@ int pthread_cancel(pthread_t thread) { _pthread_data_t *ptd; - /* cancel self */ - if (thread == rt_thread_self()) - return 0; - /* get posix thread data */ ptd = _pthread_get_data(thread); RT_ASSERT(ptd != RT_NULL); + /* cancel self */ + if (ptd->tid == rt_thread_self()) + return 0; + /* set canceled */ if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE) { @@ -534,10 +680,11 @@ int pthread_cancel(pthread_t thread) * thread (pthread_cleanup), it will move to defunct * thread list and wait for handling in idle thread. */ - rt_thread_detach(thread); + rt_thread_detach(ptd->tid); } } return 0; } RTM_EXPORT(pthread_cancel); + diff --git a/components/libc/pthreads/pthread.h b/components/libc/pthreads/pthread.h index 6a82375de4..7bb72b726c 100644 --- a/components/libc/pthreads/pthread.h +++ b/components/libc/pthreads/pthread.h @@ -12,6 +12,11 @@ #define __PTHREAD_H__ #include <rtthread.h> + +#ifdef __cplusplus +extern "C" { +#endif + #include <posix_types.h> #include <sched.h> @@ -27,7 +32,7 @@ #define PTHREAD_EXPLICIT_SCHED 0 #define PTHREAD_INHERIT_SCHED 1 -typedef rt_thread_t pthread_t; +typedef long pthread_t; typedef long pthread_condattr_t; typedef long pthread_rwlockattr_t; typedef long pthread_mutexattr_t; @@ -71,15 +76,21 @@ enum #define PTHREAD_SCOPE_PROCESS 0 #define PTHREAD_SCOPE_SYSTEM 1 +struct sched_param +{ + int sched_priority; +}; + struct pthread_attr { - void* stack_base; - rt_uint32_t stack_size; /* stack size of thread */ + void* stackaddr; /* stack address of thread */ + int stacksize; /* stack size of thread */ - rt_uint8_t priority; /* priority of thread */ - rt_uint8_t detachstate; /* detach state */ - rt_uint8_t policy; /* scheduler policy */ - rt_uint8_t inheritsched; /* Inherit parent prio/policy */ + int inheritsched; /* Inherit parent prio/policy */ + int schedpolicy; /* scheduler policy */ + struct sched_param schedparam; /* sched parameter */ + + int detachstate; /* detach state */ }; typedef struct pthread_attr pthread_attr_t; @@ -126,11 +137,6 @@ struct pthread_barrier }; typedef struct pthread_barrier pthread_barrier_t; -struct sched_param -{ - int sched_priority; -}; - /* pthread thread interface */ int pthread_attr_destroy(pthread_attr_t *attr); int pthread_attr_init(pthread_attr_t *attr); @@ -166,10 +172,7 @@ rt_inline int pthread_equal (pthread_t t1, pthread_t t2) return t1 == t2; } -rt_inline pthread_t pthread_self (void) -{ - return rt_thread_self(); -} +pthread_t pthread_self (void); void pthread_exit (void *value_ptr); int pthread_once(pthread_once_t * once_control, void (*init_routine) (void)); @@ -262,4 +265,8 @@ int pthread_barrier_init(pthread_barrier_t *barrier, int pthread_barrier_wait(pthread_barrier_t *barrier); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/libc/pthreads/pthread_attr.c b/components/libc/pthreads/pthread_attr.c index 8eed35932f..2294599bf3 100644 --- a/components/libc/pthreads/pthread_attr.c +++ b/components/libc/pthreads/pthread_attr.c @@ -20,10 +20,13 @@ const pthread_attr_t pthread_default_attr = { 0, /* stack base */ DEFAULT_STACK_SIZE, /* stack size */ - DEFAULT_PRIORITY, /* priority */ - PTHREAD_CREATE_JOINABLE, /* detach state */ + + PTHREAD_INHERIT_SCHED, /* Inherit parent prio/policy */ SCHED_FIFO, /* scheduler policy */ - PTHREAD_INHERIT_SCHED /* Inherit parent prio/policy */ + { + DEFAULT_PRIORITY, /* scheduler priority */ + }, + PTHREAD_CREATE_JOINABLE, /* detach state */ }; int pthread_attr_init(pthread_attr_t *attr) @@ -73,7 +76,7 @@ int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) { RT_ASSERT(attr != RT_NULL); - attr->policy = policy; + attr->schedpolicy = policy; return 0; } @@ -83,7 +86,7 @@ int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy) { RT_ASSERT(attr != RT_NULL); - *policy = (int)attr->policy; + *policy = (int)attr->schedpolicy; return 0; } @@ -95,7 +98,7 @@ int pthread_attr_setschedparam(pthread_attr_t *attr, RT_ASSERT(attr != RT_NULL); RT_ASSERT(param != RT_NULL); - attr->priority = param->sched_priority; + attr->schedparam.sched_priority = param->sched_priority; return 0; } @@ -107,7 +110,7 @@ int pthread_attr_getschedparam(pthread_attr_t const *attr, RT_ASSERT(attr != RT_NULL); RT_ASSERT(param != RT_NULL); - param->sched_priority = attr->priority; + param->sched_priority = attr->schedparam.sched_priority; return 0; } @@ -117,7 +120,7 @@ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size) { RT_ASSERT(attr != RT_NULL); - attr->stack_size = stack_size; + attr->stacksize = stack_size; return 0; } @@ -127,7 +130,7 @@ int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size) { RT_ASSERT(attr != RT_NULL); - *stack_size = attr->stack_size; + *stack_size = attr->stacksize; return 0; } @@ -155,8 +158,8 @@ int pthread_attr_setstack(pthread_attr_t *attr, { RT_ASSERT(attr != RT_NULL); - attr->stack_base = stack_base; - attr->stack_size = RT_ALIGN_DOWN(stack_size, RT_ALIGN_SIZE); + attr->stackaddr = stack_base; + attr->stacksize = RT_ALIGN_DOWN(stack_size, RT_ALIGN_SIZE); return 0; } @@ -168,8 +171,8 @@ int pthread_attr_getstack(pthread_attr_t const *attr, { RT_ASSERT(attr != RT_NULL); - *stack_base = attr->stack_base; - *stack_size = attr->stack_size; + *stack_base = attr->stackaddr; + *stack_size = attr->stacksize; return 0; } diff --git a/components/libc/pthreads/pthread_cond.c b/components/libc/pthreads/pthread_cond.c index d3c4ac7637..38dc697469 100644 --- a/components/libc/pthreads/pthread_cond.c +++ b/components/libc/pthreads/pthread_cond.c @@ -189,7 +189,7 @@ rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_cond_init(cond, RT_NULL); /* The mutex was not owned by the current thread at the time of the call. */ - if (mutex->lock.owner != pthread_self()) + if (mutex->lock.owner != rt_thread_self()) return -RT_ERROR; /* unlock a mutex failed */ if (pthread_mutex_unlock(mutex) != 0) diff --git a/components/libc/pthreads/pthread_internal.h b/components/libc/pthreads/pthread_internal.h index 3e94e867d7..a6706ca091 100644 --- a/components/libc/pthreads/pthread_internal.h +++ b/components/libc/pthreads/pthread_internal.h @@ -30,6 +30,10 @@ struct _pthread_key_data }; typedef struct _pthread_key_data _pthread_key_data_t; +#ifndef PTHREAD_NUM_MAX +#define PTHREAD_NUM_MAX 32 +#endif + #define PTHREAD_MAGIC 0x70746873 struct _pthread_data { @@ -56,17 +60,7 @@ struct _pthread_data }; typedef struct _pthread_data _pthread_data_t; -rt_inline _pthread_data_t *_pthread_get_data(pthread_t thread) -{ - _pthread_data_t *ptd; - RT_ASSERT(thread != RT_NULL); - - ptd = (_pthread_data_t *)thread->user_data; - RT_ASSERT(ptd != RT_NULL); - RT_ASSERT(ptd->magic == PTHREAD_MAGIC); - - return ptd; -} +_pthread_data_t *_pthread_get_data(pthread_t thread); int clock_time_to_tick(const struct timespec *time); diff --git a/components/libc/pthreads/pthread_tls.c b/components/libc/pthreads/pthread_tls.c index c6d0bca155..4b97d796d9 100644 --- a/components/libc/pthreads/pthread_tls.c +++ b/components/libc/pthreads/pthread_tls.c @@ -22,7 +22,10 @@ void *pthread_getspecific(pthread_key_t key) { struct _pthread_data* ptd; - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return NULL; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != NULL); if (ptd->tls == NULL) @@ -39,7 +42,10 @@ int pthread_setspecific(pthread_key_t key, const void *value) { struct _pthread_data* ptd; - ptd = _pthread_get_data(rt_thread_self()); + if (rt_thread_self() == NULL) return EINVAL; + + /* get pthread data from user data of thread */ + ptd = (_pthread_data_t *)rt_thread_self()->user_data; RT_ASSERT(ptd != NULL); /* check tls area */ diff --git a/components/libc/termios/posix_termios.c b/components/libc/termios/posix_termios.c index 75c876dd33..9c736c3184 100644 --- a/components/libc/termios/posix_termios.c +++ b/components/libc/termios/posix_termios.c @@ -5,7 +5,7 @@ * * Change Logs: * Date Author Notes - * 2017/08/30 Bernard The first version + * 2017/08/30 Bernard The first version */ #include <stdlib.h> #include <string.h> @@ -111,13 +111,6 @@ int tcdrain(int fd) return 0; } -int isatty (int fd) -{ - struct termios term; - - return tcgetattr (fd, &term) == 0; -} - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) void cfmakeraw(struct termios *t) { diff --git a/components/libc/termios/posix_termios.h b/components/libc/termios/posix_termios.h index 4f556d79d9..c61191b7dc 100644 --- a/components/libc/termios/posix_termios.h +++ b/components/libc/termios/posix_termios.h @@ -5,12 +5,13 @@ * * Change Logs: * Date Author Notes - * 2017/08/30 Bernard The first version + * 2017/08/30 Bernard The first version */ #ifndef TERMIOS_H__ #define TERMIOS_H__ #include <rtthread.h> +#include <sys/types.h> #ifdef __cplusplus extern "C" { diff --git a/components/libc/time/clock_time.h b/components/libc/time/clock_time.h index 7feb0390a4..16b2306f4b 100644 --- a/components/libc/time/clock_time.h +++ b/components/libc/time/clock_time.h @@ -11,6 +11,10 @@ #ifndef CLOCK_TIME_H__ #define CLOCK_TIME_H__ +#ifdef __cplusplus +extern "C" { +#endif + /* posix clock and timer */ #define MILLISECOND_PER_SECOND 1000UL #define MICROSECOND_PER_SECOND 1000000UL @@ -41,4 +45,8 @@ 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); +#ifdef __cplusplus +} +#endif + #endif |
