diff options
| author | bernard <[email protected]> | 2017-10-10 17:12:03 +0800 |
|---|---|---|
| committer | bernard <[email protected]> | 2017-10-10 17:12:03 +0800 |
| commit | db88c0b6a23fa6d56094b6d6f5e9c3e577e9a88d (patch) | |
| tree | 2573ed87aa2c25f9bf8149d981b57e9be27a9050 /components/libc/compilers | |
| parent | 5c6a6e5db825905befa9ca903aa557ea3577b7af (diff) | |
[libc] Change libc stubs to compiler folder.
Diffstat (limited to 'components/libc/compilers')
58 files changed, 3612 insertions, 0 deletions
diff --git a/components/libc/compilers/armlibc/SConscript b/components/libc/compilers/armlibc/SConscript new file mode 100644 index 0000000000..29f342a1c1 --- /dev/null +++ b/components/libc/compilers/armlibc/SConscript @@ -0,0 +1,12 @@ +from building import * + +src = Glob('*.c') +cwd = GetCurrentDir() + +CPPPATH = [cwd] +CPPDEFINES = ['RT_USING_ARM_LIBC'] + +group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], + CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/components/libc/compilers/armlibc/fcntl.h b/components/libc/compilers/armlibc/fcntl.h new file mode 100644 index 0000000000..324b73f218 --- /dev/null +++ b/components/libc/compilers/armlibc/fcntl.h @@ -0,0 +1,8 @@ +#ifndef FCNTL_H__ +#define FCNTL_H__ + +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif + +#endif diff --git a/components/libc/compilers/armlibc/libc_syms.c b/components/libc/compilers/armlibc/libc_syms.c new file mode 100644 index 0000000000..fc84aec77a --- /dev/null +++ b/components/libc/compilers/armlibc/libc_syms.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> + +#include <rtm.h> + +/* some export routines for module */ + +RTM_EXPORT(strstr); +RTM_EXPORT(strlen); +RTM_EXPORT(strchr); +RTM_EXPORT(strcpy); +RTM_EXPORT(strncpy); +RTM_EXPORT(strcmp); +RTM_EXPORT(strncmp); +RTM_EXPORT(strcat); +RTM_EXPORT(strtol); + +RTM_EXPORT(memcpy); +RTM_EXPORT(memcmp); +RTM_EXPORT(memmove); +RTM_EXPORT(memset); +RTM_EXPORT(memchr); + +RTM_EXPORT(toupper); +RTM_EXPORT(atoi); + +#ifdef RT_USING_RTC +RTM_EXPORT(localtime); +RTM_EXPORT(time); +#endif + +/* import the full stdio for printf */ +#if defined(RT_USING_MODULE) && defined(__MICROLIB) +#error "[RT_USING_LIBC] Please use standard libc but not microlib." +#endif + +RTM_EXPORT(puts); +RTM_EXPORT(printf); diff --git a/components/libc/compilers/armlibc/mem_std.c b/components/libc/compilers/armlibc/mem_std.c new file mode 100644 index 0000000000..56aa525df2 --- /dev/null +++ b/components/libc/compilers/armlibc/mem_std.c @@ -0,0 +1,43 @@ +/* + * File : mem_std.c + * Brief : implement standard memory routins. + * + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2014, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * 2014-08-03 bernard Add file header. + */ + +#include "rtthread.h" + +/* avoid the heap and heap-using library functions supplied by arm */ +#pragma import(__use_no_heap) + +void *malloc(int n) +{ + return rt_malloc(n); +} +RTM_EXPORT(malloc); + +void *realloc(void *rmem, rt_size_t newsize) +{ + return rt_realloc(rmem, newsize); +} +RTM_EXPORT(realloc); + +void *calloc(rt_size_t nelem, rt_size_t elsize) +{ + return rt_calloc(nelem, elsize); +} +RTM_EXPORT(calloc); + +void free(void *rmem) +{ + rt_free(rmem); +} +RTM_EXPORT(free); diff --git a/components/libc/compilers/armlibc/stubs.c b/components/libc/compilers/armlibc/stubs.c new file mode 100644 index 0000000000..395e51ecda --- /dev/null +++ b/components/libc/compilers/armlibc/stubs.c @@ -0,0 +1,291 @@ +/* + * File : stubs.c + * Brief : reimplement some basic functions of arm standard c library + * + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2012-11-23 Yihui The first version + * 2013-11-24 aozima fixed _sys_read()/_sys_write() issues. + * 2014-08-03 bernard If using msh, use system() implementation + * in msh. + */ + +#include <string.h> +#include <rt_sys.h> + +#include "rtthread.h" + +#ifdef RT_USING_DFS +#include "dfs_posix.h" +#endif + +#pragma import(__use_no_semihosting_swi) + +/* TODO: Standard IO device handles. */ +#define STDIN 1 +#define STDOUT 2 +#define STDERR 3 + +/* Standard IO device name defines. */ +const char __stdin_name[] = "STDIN"; +const char __stdout_name[] = "STDOUT"; +const char __stderr_name[] = "STDERR"; + +/** + * required by fopen() and freopen(). + * + * @param name - file name with path. + * @param openmode - a bitmap hose bits mostly correspond directly to + * the ISO mode specification. + * @return -1 if an error occurs. + */ +FILEHANDLE _sys_open(const char *name, int openmode) +{ +#ifdef RT_USING_DFS + int fd; + int mode = O_RDONLY; +#endif + + /* Register standard Input Output devices. */ + if (strcmp(name, __stdin_name) == 0) + return (STDIN); + if (strcmp(name, __stdout_name) == 0) + return (STDOUT); + if (strcmp(name, __stderr_name) == 0) + return (STDERR); + +#ifndef RT_USING_DFS + return -1; +#else + /* Correct openmode from fopen to open */ + if (openmode & OPEN_PLUS) + { + if (openmode & OPEN_W) + { + mode |= (O_RDWR | O_TRUNC | O_CREAT); + } + else if (openmode & OPEN_A) + { + mode |= (O_RDWR | O_APPEND | O_CREAT); + } + else + mode |= O_RDWR; + } + else + { + if (openmode & OPEN_W) + { + mode |= (O_WRONLY | O_TRUNC | O_CREAT); + } + else if (openmode & OPEN_A) + { + mode |= (O_WRONLY | O_APPEND | O_CREAT); + } + } + + fd = open(name, mode, 0); + if (fd < 0) + return -1; + else + return fd + STDERR + 1; +#endif +} + +int _sys_close(FILEHANDLE fh) +{ +#ifndef RT_USING_DFS + return 0; +#else + if (fh < STDERR) + return 0; + + return close(fh - STDERR - 1); +#endif +} + +/** + * read data + * + * @param fh - file handle + * @param buf - buffer to save read data + * @param len - max length of data buffer + * @param mode - useless, for historical reasons + * @return The number of bytes not read. + */ +int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode) +{ +#ifdef RT_USING_DFS + int size; +#endif + + if (fh == STDIN) + { + /* TODO */ + return 0; + } + + if ((fh == STDOUT) || (fh == STDERR)) + return -1; + +#ifndef RT_USING_DFS + return 0; +#else + size = read(fh - STDERR - 1, buf, len); + if (size >= 0) + return len - size; + else + return -1; +#endif +} + +/** + * write data + * + * @param fh - file handle + * @param buf - data buffer + * @param len - buffer length + * @param mode - useless, for historical reasons + * @return a positive number representing the number of characters not written. + */ +int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode) +{ +#ifdef RT_USING_DFS + int size; +#endif + + if ((fh == STDOUT) || (fh == STDERR)) + { +#ifndef RT_USING_CONSOLE + return 0; +#else + rt_device_t console_device; + + console_device = rt_console_get_device(); + if (console_device != 0) rt_device_write(console_device, 0, buf, len); + + return 0; +#endif + } + + if (fh == STDIN) + return -1; + +#ifndef RT_USING_DFS + return 0; +#else + size = write(fh - STDERR - 1, buf, len); + if (size >= 0) + return len - size; + else + return -1; +#endif +} + +/** + * put he file pointer at offset pos from the beginning of the file. + * + * @param pos - offset + * @return the current file position, or -1 on failed + */ +int _sys_seek(FILEHANDLE fh, long pos) +{ + if (fh < STDERR) + return -1; + +#ifndef RT_USING_DFS + return -1; +#else + + /* position is relative to the start of file fh */ + return lseek(fh - STDERR - 1, pos, 0); +#endif +} + +/** + * used by tmpnam() or tmpfile() + */ +int _sys_tmpnam(char *name, int fileno, unsigned maxlength) +{ + return -1; +} + +char *_sys_command_string(char *cmd, int len) +{ + /* no support */ + return cmd; +} + +/* This function writes a character to the console. */ +void _ttywrch(int ch) +{ +#ifdef RT_USING_CONSOLE + char c; + + c = (char)ch; + rt_kprintf(&c); +#endif +} + +void _sys_exit(int return_code) +{ + /* TODO: perhaps exit the thread which is invoking this function */ + while (1); +} + +/** + * return current length of file. + * + * @param fh - file handle + * @return file length, or -1 on failed + */ +long _sys_flen(FILEHANDLE fh) +{ + return -1; +} + +int _sys_istty(FILEHANDLE fh) +{ + return 0; +} + +int remove(const char *filename) +{ +#ifndef RT_USING_DFS + return -1; +#else + return unlink(filename); +#endif +} + +#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) && defined(RT_USING_MODULE) && defined(RT_USING_DFS) +/* use system(const char *string) implementation in the msh */ +#else +int system(const char *string) +{ + RT_ASSERT(0); + for (;;); +} +#endif + +#ifdef __MICROLIB +#include <stdio.h> + +int fputc(int c, FILE *f) +{ + char ch = c; + + rt_kprintf(&ch); + return 1; +} + +int fgetc(FILE *f) { + return -1; +} +#endif diff --git a/components/libc/compilers/armlibc/sys/README.md b/components/libc/compilers/armlibc/sys/README.md new file mode 100644 index 0000000000..7ad10a7d43 --- /dev/null +++ b/components/libc/compilers/armlibc/sys/README.md @@ -0,0 +1 @@ +Because Keil MDK leaks some system header file, we put them in here.
\ No newline at end of file diff --git a/components/libc/compilers/armlibc/sys/errno.h b/components/libc/compilers/armlibc/sys/errno.h new file mode 100644 index 0000000000..0aba5f5e19 --- /dev/null +++ b/components/libc/compilers/armlibc/sys/errno.h @@ -0,0 +1,80 @@ +#ifndef SYS_ERRNO_H__ +#define SYS_ERRNO_H__ + +#ifdef RT_USING_DFS + +#include <dfs_def.h> + +/* using device error codes */ +#define ENOENT DFS_STATUS_ENOENT +#define EIO DFS_STATUS_EIO +#define ENXIO DFS_STATUS_ENXIO +#define EBADF DFS_STATUS_EBADF +#define EAGAIN DFS_STATUS_EAGAIN +#define ENOMEM DFS_STATUS_ENOMEM +#define EBUSY DFS_STATUS_EBUSY +#define EEXIST DFS_STATUS_EEXIST +#define EXDEV DFS_STATUS_EXDEV +#define ENODEV DFS_STATUS_ENODEV +#define ENOTDIR DFS_STATUS_ENOTDIR +#define EISDIR DFS_STATUS_EISDIR +#define EINVAL DFS_STATUS_EINVAL +#define ENOSPC DFS_STATUS_ENOSPC +#define EROFS DFS_STATUS_EROFS +#define ENOSYS DFS_STATUS_ENOSYS +#define ENOTEMPTY DFS_STATUS_ENOTEMPTY + +#else + +/* error codes */ +#define ENOENT 2 /* No such file or directory */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define EBADF 9 /* Bad file number */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* no memory */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENOSPC 28 /* No space left on device */ +#define EROFS 30 /* Read-only file system */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ + +#endif + +#define EPERM 1 /* Not super-user */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENFILE 23 /* Too many open files in system */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 45 /* Deadlock condition */ +#define EBADMSG 77 /* Trying to read unreadable message */ +#define EMSGSIZE 90 /* Message too long */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ETIMEDOUT 116 /* Connection timed out */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define ENOTSUP 134 /* Not supported */ +#define ENSRNOTFOUND 163 /* Domain name not found */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ + +#endif diff --git a/components/libc/compilers/armlibc/sys/stat.h b/components/libc/compilers/armlibc/sys/stat.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/components/libc/compilers/armlibc/sys/stat.h diff --git a/components/libc/compilers/armlibc/sys/time.h b/components/libc/compilers/armlibc/sys/time.h new file mode 100644 index 0000000000..2d60b37317 --- /dev/null +++ b/components/libc/compilers/armlibc/sys/time.h @@ -0,0 +1,45 @@ +#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); + +#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 new file mode 100644 index 0000000000..3074bd69d0 --- /dev/null +++ b/components/libc/compilers/armlibc/sys/types.h @@ -0,0 +1,14 @@ +#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 int mode_t; + +#endif diff --git a/components/libc/compilers/armlibc/sys/unistd.h b/components/libc/compilers/armlibc/sys/unistd.h new file mode 100644 index 0000000000..e1e0dc904c --- /dev/null +++ b/components/libc/compilers/armlibc/sys/unistd.h @@ -0,0 +1,36 @@ +#ifndef _SYS_UNISTD_H +#define _SYS_UNISTD_H + +#include <rtthread.h> + +#ifdef RT_USING_DFS +#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 */ + +#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 + +#endif /* _SYS_UNISTD_H */ diff --git a/components/libc/compilers/armlibc/unistd.h b/components/libc/compilers/armlibc/unistd.h new file mode 100644 index 0000000000..3de0eaf398 --- /dev/null +++ b/components/libc/compilers/armlibc/unistd.h @@ -0,0 +1 @@ +#include "sys/unistd.h" diff --git a/components/libc/compilers/dlib/README.md b/components/libc/compilers/dlib/README.md new file mode 100644 index 0000000000..846eb3f5c0 --- /dev/null +++ b/components/libc/compilers/dlib/README.md @@ -0,0 +1,4 @@ +Dlib(IAR) porting for RT-Thread. + +Please define RT_USING_LIBC and compile RT-Thread with IAR compiler. + diff --git a/components/libc/compilers/dlib/SConscript b/components/libc/compilers/dlib/SConscript new file mode 100644 index 0000000000..44be106e03 --- /dev/null +++ b/components/libc/compilers/dlib/SConscript @@ -0,0 +1,19 @@ +from building import * +import rtconfig + +src = Glob('*.c') +cwd = GetCurrentDir() +group = [] + +CPPPATH = [cwd] +CPPDEFINES = ['RT_USING_DLIBC'] + +if rtconfig.PLATFORM == 'iar': + + if GetDepend('RT_USING_DFS'): + CPPDEFINES = CPPDEFINES + ['_DLIB_FILE_DESCRIPTOR', '_DLIB_THREAD_SUPPORT'] + + group = DefineGroup('dlib', src, depend = ['RT_USING_LIBC'], + CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/components/libc/compilers/dlib/environ.c b/components/libc/compilers/dlib/environ.c new file mode 100644 index 0000000000..1e44eb1627 --- /dev/null +++ b/components/libc/compilers/dlib/environ.c @@ -0,0 +1,25 @@ +/* File: environ.c + * this file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ + +const char *__environ = "OS=RT-Thread"; + diff --git a/components/libc/compilers/dlib/rmtx.c b/components/libc/compilers/dlib/rmtx.c new file mode 100644 index 0000000000..4bf7140271 --- /dev/null +++ b/components/libc/compilers/dlib/rmtx.c @@ -0,0 +1,74 @@ +/* + * File : rmtx.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ +#include <rtthread.h> +#include <yfuns.h> + +/* + * for IAR compiler, we recommand to define _DLIB_THREAD_SUPPORT + * as 2 for dlib multi-thread support. + */ + +#if _DLIB_THREAD_SUPPORT +typedef void* _Rmtx; +void _Mtxinit(_Rmtx *m) +{ + rt_mutex_t mutex; + + RT_ASSERT(m != RT_NULL); + + mutex = (rt_mutex_t)m; + rt_mutex_init(mutex, "iarMtx", RT_IPC_FLAG_FIFO); +} + +void _Mtxdst(_Rmtx *m) +{ + rt_mutex_t mutex; + + RT_ASSERT(m != RT_NULL); + + mutex = (rt_mutex_t)m; + rt_mutex_detach(mutex); +} + +void _Mtxlock(_Rmtx *m) +{ + rt_mutex_t mutex; + + RT_ASSERT(m != RT_NULL); + + mutex = (rt_mutex_t)m; + rt_mutex_take(mutex, RT_WAITING_FOREVER); +} + +void _Mtxunlock(_Rmtx *m) +{ + rt_mutex_t mutex; + + RT_ASSERT(m != RT_NULL); + + mutex = (rt_mutex_t)m; + rt_mutex_release(mutex); +} +#endif + diff --git a/components/libc/compilers/dlib/sys/README.md b/components/libc/compilers/dlib/sys/README.md new file mode 100644 index 0000000000..4f0d203180 --- /dev/null +++ b/components/libc/compilers/dlib/sys/README.md @@ -0,0 +1 @@ +Because IAR leaks some system header file, we put them in here.
\ No newline at end of file diff --git a/components/libc/compilers/dlib/sys/errno.h b/components/libc/compilers/dlib/sys/errno.h new file mode 100644 index 0000000000..a8e09ffd24 --- /dev/null +++ b/components/libc/compilers/dlib/sys/errno.h @@ -0,0 +1,80 @@ +#ifndef SYS_ERRNO_H__ +#define SYS_ERRNO_H__ + +#ifdef RT_USING_DFS + +#include <dfs_def.h> + +/* using device error codes */ +#define ENOENT DFS_STATUS_ENOENT +#define EIO DFS_STATUS_EIO +#define ENXIO DFS_STATUS_ENXIO +#define EBADF DFS_STATUS_EBADF +#define EAGAIN DFS_STATUS_EAGAIN +#define ENOMEM DFS_STATUS_ENOMEM +#define EBUSY DFS_STATUS_EBUSY +#define EEXIST DFS_STATUS_EEXIST +#define EXDEV DFS_STATUS_EXDEV +#define ENODEV DFS_STATUS_ENODEV +#define ENOTDIR DFS_STATUS_ENOTDIR +#define EISDIR DFS_STATUS_EISDIR +#define EINVAL DFS_STATUS_EINVAL +#define ENOSPC DFS_STATUS_ENOSPC +#define EROFS DFS_STATUS_EROFS +#define ENOSYS DFS_STATUS_ENOSYS +#define ENOTEMPTY DFS_STATUS_ENOTEMPTY + +#else + +/* error codes */ +#define ENOENT 2 /* No such file or directory */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define EBADF 9 /* Bad file number */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* no memory */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENOSPC 28 /* No space left on device */ +#define EROFS 30 /* Read-only file system */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ + +#endif + +#define EPERM 1 /* Not super-user */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENFILE 23 /* Too many open files in system */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 45 /* Deadlock condition */ +#define EBADMSG 77 /* Trying to read unreadable message */ +#define EMSGSIZE 90 /* Message too long */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ETIMEDOUT 116 /* Connection timed out */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define ENOTSUP 134 /* Not supported */ +#define ENSRNOTFOUND 163 /* Domain name not found */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ + +#endif diff --git a/components/libc/compilers/dlib/sys/time.h b/components/libc/compilers/dlib/sys/time.h new file mode 100644 index 0000000000..2d60b37317 --- /dev/null +++ b/components/libc/compilers/dlib/sys/time.h @@ -0,0 +1,45 @@ +#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); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_TIME_H_ */ diff --git a/components/libc/compilers/dlib/sys/types.h b/components/libc/compilers/dlib/sys/types.h new file mode 100644 index 0000000000..3074bd69d0 --- /dev/null +++ b/components/libc/compilers/dlib/sys/types.h @@ -0,0 +1,14 @@ +#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 int mode_t; + +#endif diff --git a/components/libc/compilers/dlib/sys/unistd.h b/components/libc/compilers/dlib/sys/unistd.h new file mode 100644 index 0000000000..06a46746c0 --- /dev/null +++ b/components/libc/compilers/dlib/sys/unistd.h @@ -0,0 +1,34 @@ +#ifndef _SYS_UNISTD_H +#define _SYS_UNISTD_H + +#ifdef RT_USING_DFS +#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 */ + +#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 + +#endif /* _SYS_UNISTD_H */ diff --git a/components/libc/compilers/dlib/syscall_close.c b/components/libc/compilers/dlib/syscall_close.c new file mode 100644 index 0000000000..c2bb0b63d6 --- /dev/null +++ b/components/libc/compilers/dlib/syscall_close.c @@ -0,0 +1,43 @@ +/* + * File : syscall_close.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ +#include <rtthread.h> +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif +#include <yfuns.h> + +#pragma module_name = "?__close" +int __close(int handle) +{ + if (handle == _LLIO_STDOUT || + handle == _LLIO_STDERR || + handle == _LLIO_STDIN) + return _LLIO_ERROR; + +#ifdef RT_USING_DFS + return close(handle - _LLIO_STDERR - 1); +#else + return 0; +#endif +} diff --git a/components/libc/compilers/dlib/syscall_lseek.c b/components/libc/compilers/dlib/syscall_lseek.c new file mode 100644 index 0000000000..23d509817e --- /dev/null +++ b/components/libc/compilers/dlib/syscall_lseek.c @@ -0,0 +1,43 @@ +/* + * File : syscall_lseek.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ +#include <rtthread.h> +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif +#include <yfuns.h> + +#pragma module_name = "?__lseek" +long __lseek(int handle, long offset, int whence) +{ + if (handle == _LLIO_STDOUT || + handle == _LLIO_STDERR || + handle == _LLIO_STDIN) + return _LLIO_ERROR; + +#ifdef RT_USING_DFS + return lseek(handle - _LLIO_STDERR - 1, offset, whence); +#else + return _LLIO_ERROR; +#endif +} diff --git a/components/libc/compilers/dlib/syscall_mem.c b/components/libc/compilers/dlib/syscall_mem.c new file mode 100644 index 0000000000..10eb298b9c --- /dev/null +++ b/components/libc/compilers/dlib/syscall_mem.c @@ -0,0 +1,44 @@ +/* + * File : syscall_mem.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ +#include <rtthread.h> + +void *malloc(rt_size_t n) +{ + return rt_malloc(n); +} + +void *realloc(void *rmem, rt_size_t newsize) +{ + return rt_realloc(rmem, newsize); +} + +void *calloc(rt_size_t nelem, rt_size_t elsize) +{ + return rt_calloc(nelem, elsize); +} + +void free(void *rmem) +{ + rt_free(rmem); +} diff --git a/components/libc/compilers/dlib/syscall_open.c b/components/libc/compilers/dlib/syscall_open.c new file mode 100644 index 0000000000..95fa43b9c6 --- /dev/null +++ b/components/libc/compilers/dlib/syscall_open.c @@ -0,0 +1,88 @@ +/* +* File : syscall_open.c +* This file is part of RT-Thread RTOS +* COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Change Logs: +* Date Author Notes +* 2015-01-28 Bernard first version +*/ + +#include <rtthread.h> +#include <yfuns.h> +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif + +#pragma module_name = "?__open" + +int __open(const char *filename, int mode) +{ +#ifndef RT_USING_DFS + return -1; +#else + int handle; + int open_mode = O_RDONLY; + + if (mode & _LLIO_CREAT) + { + open_mode |= O_CREAT; + + /* Check what we should do with it if it exists. */ + if (mode & _LLIO_APPEND) + { + /* Append to the existing file. */ + open_mode |= O_APPEND; + } + + if (mode & _LLIO_TRUNC) + { + /* Truncate the existsing file. */ + open_mode |= O_TRUNC; + } + } + + if (mode & _LLIO_TEXT) + { + /* we didn't support text mode */ + } + + switch (mode & _LLIO_RDWRMASK) + { + case _LLIO_RDONLY: + break; + + case _LLIO_WRONLY: + open_mode |= O_WRONLY; + break; + + case _LLIO_RDWR: + /* The file should be opened for both reads and writes. */ + open_mode |= O_RDWR; + break; + + default: + return -1; + } + + handle = open(filename, open_mode, 0); + if (handle < 0) + return -1; + + return handle + _LLIO_STDERR + 1; +#endif +} diff --git a/components/libc/compilers/dlib/syscall_read.c b/components/libc/compilers/dlib/syscall_read.c new file mode 100644 index 0000000000..aa13654189 --- /dev/null +++ b/components/libc/compilers/dlib/syscall_read.c @@ -0,0 +1,53 @@ +/* + * File : syscall_read.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ + +#include <rtthread.h> +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif +#include <yfuns.h> + +#pragma module_name = "?__read" +size_t __read(int handle, unsigned char *buf, size_t len) +{ +#ifdef RT_USING_DFS + int size; +#endif + + if (handle == _LLIO_STDIN) + { + /* TODO */ + return 0; + } + + if ((handle == _LLIO_STDOUT) || (handle == _LLIO_STDERR)) + return _LLIO_ERROR; + +#ifndef RT_USING_DFS + return _LLIO_ERROR; +#else + size = read(handle - _LLIO_STDERR - 1, buf, len); + return size; +#endif +} diff --git a/components/libc/compilers/dlib/syscall_remove.c b/components/libc/compilers/dlib/syscall_remove.c new file mode 100644 index 0000000000..b7dd9477b7 --- /dev/null +++ b/components/libc/compilers/dlib/syscall_remove.c @@ -0,0 +1,38 @@ +/* + * File : syscall_remove.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ +#include <rtthread.h> +#ifdef RT_USING_DFS +#include <dfs_file.h> +#endif +#include <yfuns.h> + +#pragma module_name = "?remove" +int remove(const char *val) +{ +#ifdef RT_USING_DFS + dfs_file_unlink(val); +#endif + + return 0; +} diff --git a/components/libc/compilers/dlib/syscall_write.c b/components/libc/compilers/dlib/syscall_write.c new file mode 100644 index 0000000000..a7140b9818 --- /dev/null +++ b/components/libc/compilers/dlib/syscall_write.c @@ -0,0 +1,62 @@ +/* + * File : syscall_write.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ + +#include <rtthread.h> +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif +#include <yfuns.h> + +#pragma module_name = "?__write" + +size_t __write(int handle, const unsigned char *buf, size_t len) +{ +#ifdef RT_USING_DFS + int size; +#endif + + if ((handle == _LLIO_STDOUT) || (handle == _LLIO_STDERR)) + { +#ifndef RT_USING_CONSOLE + return _LLIO_ERROR; +#else + rt_device_t console_device; + + console_device = rt_console_get_device(); + if (console_device != 0) rt_device_write(console_device, 0, buf, len); + + return len; +#endif + } + + if (handle == _LLIO_STDIN) return -1; + +#ifndef RT_USING_DFS + return _LLIO_ERROR; +#else + size = write(handle - _LLIO_STDERR - 1, buf, len); + return size; +#endif +} + diff --git a/components/libc/compilers/dlib/syscalls.h b/components/libc/compilers/dlib/syscalls.h new file mode 100644 index 0000000000..2c38854f72 --- /dev/null +++ b/components/libc/compilers/dlib/syscalls.h @@ -0,0 +1,23 @@ +/* File: syscalls.h + * this file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2015-01-28 Bernard first version + */ + diff --git a/components/libc/compilers/minilibc/SConscript b/components/libc/compilers/minilibc/SConscript new file mode 100644 index 0000000000..b0c82a7125 --- /dev/null +++ b/components/libc/compilers/minilibc/SConscript @@ -0,0 +1,13 @@ +Import('RTT_ROOT') +from building import * + +src = Glob('*.c') +cwd = GetCurrentDir() + +CPPPATH = [cwd] +CPPDEFINES = ['RT_USING_MINILIBC'] + +group = DefineGroup('libc', src, depend = ['RT_USING_MINILIBC'], + CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/components/libc/compilers/minilibc/ctype.c b/components/libc/compilers/minilibc/ctype.c new file mode 100644 index 0000000000..fed8f583a6 --- /dev/null +++ b/components/libc/compilers/minilibc/ctype.c @@ -0,0 +1,53 @@ +/* + * File : ctype.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-08-14 Bernard the first version + */ + +#include <rtthread.h> +#include <sys/types.h> + +#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) +#include "ctype.h" + +int isprint (int ch) +{ + ch&=0x7f; + return (ch>=32 && ch<127); +} + +int isalpha(int ch) +{ + return (unsigned int)((ch | 0x20) - 'a') < 26u; +} + +int isdigit (int ch) +{ + return (unsigned int)(ch - '0') < 10u; +} + +int isspace(int ch) +{ + switch(ch) + { + case ' ': + case '\n': + case '\f': + case '\r': + case '\t': + case '\v': + return 1; + default: + return 0; + } +} + +#endif diff --git a/components/libc/compilers/minilibc/ctype.h b/components/libc/compilers/minilibc/ctype.h new file mode 100644 index 0000000000..6b93490d36 --- /dev/null +++ b/components/libc/compilers/minilibc/ctype.h @@ -0,0 +1,22 @@ +/* + * File : ctype.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-08-14 Bernard the first version + */ +#ifndef __CTYPE_H__ +#define __CTYPE_H__ + +int isprint(int c) __attribute__ ((__const__)); +int isalpha (int c) __attribute__ ((__const__)); +int isdigit (int ch) __attribute__ ((__const__)); +int isspace(int ch) __attribute__ ((__const__)); + +#endif diff --git a/components/libc/compilers/minilibc/errno.h b/components/libc/compilers/minilibc/errno.h new file mode 100644 index 0000000000..74b8296241 --- /dev/null +++ b/components/libc/compilers/minilibc/errno.h @@ -0,0 +1,77 @@ +#ifndef __ERRNO_H__ +#define __ERRNO_H__ + +#ifdef RT_USING_DFS + +#include <dfs_def.h> + +/* using device error codes */ +#define ENOENT DFS_STATUS_ENOENT +#define EIO DFS_STATUS_EIO +#define ENXIO DFS_STATUS_ENXIO +#define EBADF DFS_STATUS_EBADF +#define EAGAIN DFS_STATUS_EAGAIN +#define ENOMEM DFS_STATUS_ENOMEM +#define EBUSY DFS_STATUS_EBUSY +#define EEXIST DFS_STATUS_EEXIST +#define EXDEV DFS_STATUS_EXDEV +#define ENODEV DFS_STATUS_ENODEV +#define ENOTDIR DFS_STATUS_ENOTDIR +#define EISDIR DFS_STATUS_EISDIR +#define EINVAL DFS_STATUS_EINVAL +#define ENOSPC DFS_STATUS_ENOSPC +#define EROFS DFS_STATUS_EROFS +#define ENOSYS DFS_STATUS_ENOSYS +#define ENOTEMPTY DFS_STATUS_ENOTEMPTY + +#else + +/* error codes */ +#define ENOENT 2 /* No such file or directory */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define EBADF 9 /* Bad file number */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* no memory */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENOSPC 28 /* No space left on device */ +#define EROFS 30 /* Read-only file system */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ + +#endif + +#define EPERM 1 /* Not super-user */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EFAULT 14 /* Bad address */ +#define ENFILE 23 /* Too many open files in system */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 45 /* Deadlock condition */ +#define EBADMSG 77 /* Trying to read unreadable message */ +#define EMSGSIZE 90 /* Message too long */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ETIMEDOUT 116 /* Connection timed out */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define ENOTSUP 134 /* Not supported */ +#define ENSRNOTFOUND 163 /* Domain name not found */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ + +#endif diff --git a/components/libc/compilers/minilibc/inttypes.h b/components/libc/compilers/minilibc/inttypes.h new file mode 100644 index 0000000000..84e036a043 --- /dev/null +++ b/components/libc/compilers/minilibc/inttypes.h @@ -0,0 +1,6 @@ +#ifndef __INTTYPES_H__ +#define __INTTYPES_H__ + +#include "stdint.h" + +#endif diff --git a/components/libc/compilers/minilibc/math.c b/components/libc/compilers/minilibc/math.c new file mode 100644 index 0000000000..27315a428c --- /dev/null +++ b/components/libc/compilers/minilibc/math.c @@ -0,0 +1,168 @@ +#include <math.h> + +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CRT + * FILE: lib/crt/math/cos.c + * PURPOSE: Generic C Implementation of cos + * PROGRAMMER: Timo Kreuzer ([email protected]) + */ + +#define PRECISION 9 + +static double cos_off_tbl[] = {0.0, -M_PI/2., 0, -M_PI/2.}; +static double cos_sign_tbl[] = {1,-1,-1,1}; + +static double sin_off_tbl[] = {0.0, -M_PI/2., 0, -M_PI/2.}; +static double sin_sign_tbl[] = {1,-1,-1,1}; + +double sin(double x) +{ + int quadrant; + double x2, result; + + /* Calculate the quadrant */ + quadrant = x * (2./M_PI); + + /* Get offset inside quadrant */ + x = x - quadrant * (M_PI/2.); + + /* Normalize quadrant to [0..3] */ + quadrant = (quadrant - 1) & 0x3; + + /* Fixup value for the generic function */ + x += sin_off_tbl[quadrant]; + + /* Calculate the negative of the square of x */ + x2 = - (x * x); + + /* This is an unrolled taylor series using <PRECISION> iterations + * Example with 4 iterations: + * result = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! + * To save multiplications and to keep the precision high, it's performed + * like this: + * result = 1 - x^2 * (1/2! - x^2 * (1/4! - x^2 * (1/6! - x^2 * (1/8!)))) + */ + + /* Start with 0, compiler will optimize this away */ + result = 0; + +#if (PRECISION >= 10) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20); + result *= x2; +#endif +#if (PRECISION >= 9) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18); + result *= x2; +#endif +#if (PRECISION >= 8) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16); + result *= x2; +#endif +#if (PRECISION >= 7) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14); + result *= x2; +#endif +#if (PRECISION >= 6) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12); + result *= x2; +#endif +#if (PRECISION >= 5) + result += 1./(1.*2*3*4*5*6*7*8*9*10); + result *= x2; +#endif + result += 1./(1.*2*3*4*5*6*7*8); + result *= x2; + + result += 1./(1.*2*3*4*5*6); + result *= x2; + + result += 1./(1.*2*3*4); + result *= x2; + + result += 1./(1.*2); + result *= x2; + + result += 1; + + /* Apply correct sign */ + result *= sin_sign_tbl[quadrant]; + + return result; +} + +double cos(double x) +{ + int quadrant; + double x2, result; + + /* Calculate the quadrant */ + quadrant = x * (2./M_PI); + + /* Get offset inside quadrant */ + x = x - quadrant * (M_PI/2.); + + /* Normalize quadrant to [0..3] */ + quadrant = quadrant & 0x3; + + /* Fixup value for the generic function */ + x += cos_off_tbl[quadrant]; + + /* Calculate the negative of the square of x */ + x2 = - (x * x); + + /* This is an unrolled taylor series using <PRECISION> iterations + * Example with 4 iterations: + * result = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! + * To save multiplications and to keep the precision high, it's performed + * like this: + * result = 1 - x^2 * (1/2! - x^2 * (1/4! - x^2 * (1/6! - x^2 * (1/8!)))) + */ + + /* Start with 0, compiler will optimize this away */ + result = 0; + +#if (PRECISION >= 10) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20); + result *= x2; +#endif +#if (PRECISION >= 9) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18); + result *= x2; +#endif +#if (PRECISION >= 8) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16); + result *= x2; +#endif +#if (PRECISION >= 7) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14); + result *= x2; +#endif +#if (PRECISION >= 6) + result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12); + result *= x2; +#endif +#if (PRECISION >= 5) + result += 1./(1.*2*3*4*5*6*7*8*9*10); + result *= x2; +#endif + result += 1./(1.*2*3*4*5*6*7*8); + result *= x2; + + result += 1./(1.*2*3*4*5*6); + result *= x2; + + result += 1./(1.*2*3*4); + result *= x2; + + result += 1./(1.*2); + result *= x2; + + result += 1; + + /* Apply correct sign */ + result *= cos_sign_tbl[quadrant]; + + return result; +} + diff --git a/components/libc/compilers/minilibc/math.h b/components/libc/compilers/minilibc/math.h new file mode 100644 index 0000000000..b436eb08b5 --- /dev/null +++ b/components/libc/compilers/minilibc/math.h @@ -0,0 +1,9 @@ +#ifndef __MATH_H__ +#define __MATH_H__ + +#define M_PI 3.141592653589793238462643 + +double sin(double x); +double cos(double x); + +#endif diff --git a/components/libc/compilers/minilibc/qsort.c b/components/libc/compilers/minilibc/qsort.c new file mode 100644 index 0000000000..f412986e1d --- /dev/null +++ b/components/libc/compilers/minilibc/qsort.c @@ -0,0 +1,44 @@ +#include <sys/types.h> +#include <stdlib.h> + +static void exch(char* base,size_t size,size_t a,size_t b) { + char* x=base+a*size; + char* y=base+b*size; + while (size) { + char z=*x; + *x=*y; + *y=z; + --size; ++x; ++y; + } +} + +/* Quicksort with 3-way partitioning, ala Sedgewick */ +/* Blame him for the scary variable names */ +/* http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf */ +static void quicksort(char* base,size_t size,ssize_t l,ssize_t r, + int (*compar)(const void*,const void*)) { + ssize_t i=l-1, j=r, p=l-1, q=r, k; + char* v=base+r*size; + if (r<=l) return; + for (;;) { + while (++i != r && compar(base+i*size,v)<0) ; + while (compar(v,base+(--j)*size)<0) if (j == l) break; + if (i >= j) break; + exch(base,size,i,j); + if (compar(base+i*size,v)==0) exch(base,size,++p,i); + if (compar(v,base+j*size)==0) exch(base,size,j,--q); + } + exch(base,size,i,r); j = i-1; ++i; + for (k=l; k<p; k++, j--) exch(base,size,k,j); + for (k=r-1; k>q; k--, i++) exch(base,size,i,k); + quicksort(base,size,l,j,compar); + quicksort(base,size,i,r,compar); +} + +void qsort(void* base,size_t nmemb,size_t size,int (*compar)(const void*,const void*)) { + /* check for integer overflows */ + if (nmemb >= (((size_t)-1)>>1) || + size >= (((size_t)-1)>>1)) return; + if (nmemb>1) + quicksort(base,size,0,nmemb-1,compar); +} diff --git a/components/libc/compilers/minilibc/rand.c b/components/libc/compilers/minilibc/rand.c new file mode 100644 index 0000000000..387d605d4c --- /dev/null +++ b/components/libc/compilers/minilibc/rand.c @@ -0,0 +1,35 @@ +#include <stdlib.h> +#include <stdint.h> +#include <sys/types.h> + +static unsigned int _seed=1; + +/* Knuth's TAOCP section 3.6 */ +#define M ((1U<<31) -1) +#define A 48271 +#define Q 44488 // M/A +#define R 3399 // M%A; R < Q !!! + +int rand_r(unsigned int* seed) +{ int32_t X; + + X = *seed; + X = A*(X%Q) - R * (int32_t) (X/Q); + if (X < 0) + X += M; + + *seed = X; + return X; +} + +int rand(void) { + return rand_r(&_seed); +} + +void srand(unsigned int i) +{ + _seed=i; +} + +int random(void) __attribute__((alias("rand"))); +void srandom(unsigned int i) __attribute__((alias("srand"))); diff --git a/components/libc/compilers/minilibc/stddef.h b/components/libc/compilers/minilibc/stddef.h new file mode 100644 index 0000000000..8068277117 --- /dev/null +++ b/components/libc/compilers/minilibc/stddef.h @@ -0,0 +1,7 @@ +#ifndef __STDDEF_H__ +#define __STDDEF_H__ + +#include <sys/types.h> +typedef signed long ptrdiff_t; + +#endif diff --git a/components/libc/compilers/minilibc/stdint.h b/components/libc/compilers/minilibc/stdint.h new file mode 100644 index 0000000000..f397b57bc5 --- /dev/null +++ b/components/libc/compilers/minilibc/stdint.h @@ -0,0 +1,48 @@ +#ifndef __STDINT_H__ +#define __STDINT_H__ + +#include <rtthread.h> + +typedef rt_int8_t int8_t; +typedef rt_uint8_t uint8_t; +typedef rt_int16_t int16_t; +typedef rt_uint16_t uint16_t; +typedef rt_int32_t int32_t; +typedef rt_uint32_t uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; + +/* + * 7.18.2 Limits of specified-width integer types. + * + * The following object-like macros specify the minimum and maximum limits + * of integer types corresponding to the typedef names defined above. + */ + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MIN (-0x7f - 1) +#define INT16_MIN (-0x7fff - 1) +#define INT32_MIN (-0x7fffffff - 1) + +#define INT8_MAX 0x7f +#define INT16_MAX 0x7fff +#define INT32_MAX 0x7fffffff + +#define UINT8_MAX 0xff +#define UINT16_MAX 0xffff +#define UINT32_MAX 0xffffffffU + +#ifndef __INT_MAX__ +#define __INT_MAX__ 2147483647 +#endif +#define INT_MIN (-1 - INT_MAX) +#define INT_MAX (__INT_MAX__) +#define UINT_MAX (INT_MAX * 2U + 1U) + +#define LONG_MAX ((long)(~0UL>>1)) +#define LONG_MIN (-LONG_MAX - 1) +#define ULONG_MAX (~0UL) + +#define SIZE_MAX ULONG_MAX + +#endif diff --git a/components/libc/compilers/minilibc/stdio.h b/components/libc/compilers/minilibc/stdio.h new file mode 100644 index 0000000000..160b4d2c78 --- /dev/null +++ b/components/libc/compilers/minilibc/stdio.h @@ -0,0 +1,8 @@ +#ifndef __STDIO_H__ +#define __STDIO_H__ + +#define BUFSIZ 128 +#define EOF (-1) + +#endif + diff --git a/components/libc/compilers/minilibc/stdlib.c b/components/libc/compilers/minilibc/stdlib.c new file mode 100644 index 0000000000..e29ae9bc2e --- /dev/null +++ b/components/libc/compilers/minilibc/stdlib.c @@ -0,0 +1,79 @@ +/* + * File : stdlib.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-08-14 Bernard the first version + */ + +#include <rtthread.h> + +#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) +#include "stdlib.h" + +int atoi(const char* s) +{ + long int v=0; + int sign=1; + while ( *s == ' ' || (unsigned int)(*s - 9) < 5u) s++; + switch (*s) + { + case '-': + sign=-1; + case '+': + ++s; + } + while ((unsigned int) (*s - '0') < 10u) + { + v=v*10+*s-'0'; + ++s; + } + return sign==-1?-v:v; +} + +long int atol(const char* s) +{ + long int v=0; + int sign=0; + while ( *s == ' ' || (unsigned int)(*s - 9) < 5u) ++s; + switch (*s) + { + case '-': sign=-1; + case '+': ++s; + } + while ((unsigned int) (*s - '0') < 10u) + { + v=v*10+*s-'0'; ++s; + } + return sign?-v:v; +} + +#ifdef RT_USING_HEAP +void *malloc(size_t size) +{ + return rt_malloc(size); +} + +void free(void *ptr) +{ + rt_free(ptr); +} + +void *realloc(void *ptr, size_t size) +{ + return rt_realloc(ptr, size); +} + +void *calloc(size_t nelem, size_t elsize) +{ + return rt_calloc(nelem, elsize); +} +#endif + +#endif diff --git a/components/libc/compilers/minilibc/stdlib.h b/components/libc/compilers/minilibc/stdlib.h new file mode 100644 index 0000000000..4e87537d3f --- /dev/null +++ b/components/libc/compilers/minilibc/stdlib.h @@ -0,0 +1,37 @@ +/* + * File : stdlib.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-08-14 Bernard the first version + */ + +#ifndef __STDLIB_H__ +#define __STDLIB_H__ + +#include <sys/types.h> + +#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) +int atoi(const char *nptr); +long int atol(const char *nptr); + +int rand(void); +int rand_r(unsigned int *seed); +void srand(unsigned int seed); + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); + +void *malloc(size_t size); +void free(void *ptr); +void *realloc(void *ptr, size_t size); +void *calloc(size_t nelem, size_t elsize); +void abort(void); +#endif + +#endif diff --git a/components/libc/compilers/minilibc/string.c b/components/libc/compilers/minilibc/string.c new file mode 100644 index 0000000000..4e90da1554 --- /dev/null +++ b/components/libc/compilers/minilibc/string.c @@ -0,0 +1,634 @@ +/* + * File : string.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-08-14 Bernard the first version + * 2010-02-15 Gary Lee add strlcpy + * 2010-03-17 Bernard add strlcpy implementation to this file. + * fix strlcpy declaration + * 2010-03-24 Bernard add strchr and strtok implementation. + */ + +#include <rtthread.h> +#include <stdint.h> + +#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) +#include "string.h" + +/* there is no strcpy and strcmp implementation in RT-Thread */ +char *strcpy(char *dest, const char *src) +{ + return (char *)rt_strncpy(dest, src, rt_strlen(src) + 1); +} + +char *strncpy(char *dest, const char *src, size_t siz) +{ + return (char *)rt_strncpy(dest, src, siz); +} + +size_t strlcpy(char *dst, const char *src, size_t siz) +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) + { + do + { + if ((*d++ = *s++) == 0) break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) *d = '\0'; /* NUL-terminate dst */ + while (*s++) ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +int strcmp (const char *s1, const char *s2) +{ + while (*s1 && *s1 == *s2) + s1++, s2++; + return (*s1 - *s2); +} + +/** + * strncmp - Compare two length-limited strings + * @cs: One string + * @ct: Another string + * @count: The maximum number of bytes to compare + */ +int strncmp(const char *cs,const char *ct, size_t count) +{ + register signed char __res = 0; + + while (count) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + + return __res; +} + +char *strcat(char * dest, const char * src) +{ + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++) != '\0') + ; + + return tmp; +} + +char *strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest = '\0'; + break; + } + } + } + + return tmp; +} + +char *strrchr(const char *t, int c) +{ + register char ch; + register const char *l=0; + + ch = c; + for (;;) + { + if (*t == ch) l=t; + if (!*t) return (char*)l; + ++t; + } + + return (char*)l; +} + + +int strncasecmp ( const char* s1, const char* s2, size_t len ) +{ + register unsigned int x2; + register unsigned int x1; + register const char* end = s1 + len; + + while (1) + { + if ((s1 >= end) ) + return 0; + + x2 = *s2 - 'A'; if ((x2 < 26u)) x2 += 32; + x1 = *s1 - 'A'; if ((x1 < 26u)) x1 += 32; + s1++; s2++; + + if (x2 != x1) + break; + + if (x1 == (unsigned int)-'A') + break; + } + + return x1 - x2; +} + +/* private function */ +#define isdigit(c) ((unsigned)((c) - '0') < 10) + +rt_inline int divide(int *n, int base) +{ + rt_int32_t res; + + /* optimized for processor which does not support divide instructions. */ + if (base == 10) + { + res = ((int)*n) % 10U; + *n = ((int)*n) / 10U; + } + else + { + res = ((int)*n) % 16U; + *n = ((int)*n) / 16U; + } + + return res; +} + +rt_inline int skip_atoi(const char **s) +{ + register int i=0; + while (isdigit(**s)) i = i*10 + *((*s)++) - '0'; + + return i; +} + +unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) +{ + if (isupper(c)) + c -= 'A'-'a'; + return c; +} + +static inline unsigned char __toupper(unsigned char c) +{ + if (islower(c)) + c -= 'a'-'A'; + return c; +} + +int tolower(int c) +{ + return __tolower(c); +} + +int toupper(int c) +{ + return __toupper(c); +} + +/** + * simple_strtoul - convert a string to an unsigned long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) +{ + unsigned long result = 0,value; + + if (!base) { + base = 10; + if (*cp == '0') { + base = 8; + cp++; + if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { + cp++; + base = 16; + } + } + } else if (base == 16) { + if (cp[0] == '0' && toupper(cp[1]) == 'X') + cp += 2; + } + while (isxdigit(*cp) && + (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { + result = result*base + value; + cp++; + } + if (endp) + *endp = (char *)cp; + return result; +} + +/** + * simple_strtol - convert a string to a signed long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +long simple_strtol(const char *cp,char **endp,unsigned int base) +{ + if(*cp=='-') + return -simple_strtoul(cp+1,endp,base); + return simple_strtoul(cp,endp,base); +} + +/** + * simple_strtoull - convert a string to an unsigned long long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) +{ + unsigned long long result = 0, value; + + if (*cp == '0') { + cp++; + if ((toupper(*cp) == 'X') && isxdigit (cp[1])) { + base = 16; + cp++; + } + if (!base) { + base = 8; + } + } + if (!base) { + base = 10; + } + while (isxdigit (*cp) && (value = isdigit (*cp) + ? *cp - '0' + : (islower (*cp) ? toupper (*cp) : *cp) - 'A' + 10) < base) { + result = result * base + value; + cp++; + } + if (endp) + *endp = (char *) cp; + return result; +} + +/** + * simple_strtoll - convert a string to a signed long long + * @cp: The start of the string + * @endp: A pointer to the end of the parsed string will be placed here + * @base: The number base to use + */ +long long simple_strtoll(const char *cp,char **endp,unsigned int base) +{ + if(*cp=='-') + return -simple_strtoull(cp+1,endp,base); + return simple_strtoull(cp,endp,base); +} + +/** + * vsscanf - Unformat a buffer into a list of arguments + * @buf: input buffer + * @fmt: format of buffer + * @args: arguments + */ +int vsscanf(const char * buf, const char * fmt, va_list args) +{ + const char *str = buf; + char *next; + int num = 0; + int qualifier; + int base; + int field_width = -1; + int is_sign = 0; + + while(*fmt && *str) { + /* skip any white space in format */ + /* white space in format matchs any amount of + * white space, including none, in the input. + */ + if (isspace(*fmt)) { + while (isspace(*fmt)) + ++fmt; + while (isspace(*str)) + ++str; + } + + /* anything that is not a conversion must match exactly */ + if (*fmt != '%' && *fmt) { + if (*fmt++ != *str++) + break; + continue; + } + + if (!*fmt) + break; + ++fmt; + + /* skip this conversion. + * advance both strings to next white space + */ + if (*fmt == '*') { + while (!isspace(*fmt) && *fmt) + fmt++; + while (!isspace(*str) && *str) + str++; + continue; + } + + /* get field width */ + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + + /* get conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') { + qualifier = *fmt; + fmt++; + } + base = 10; + is_sign = 0; + + if (!*fmt || !*str) + break; + + switch(*fmt++) { + case 'c': + { + char *s = (char *) va_arg(args,char*); + if (field_width == -1) + field_width = 1; + do { + *s++ = *str++; + } while(field_width-- > 0 && *str); + num++; + } + continue; + case 's': + { + char *s = (char *) va_arg(args, char *); + if(field_width == -1) + field_width = INT_MAX; + /* first, skip leading white space in buffer */ + while (isspace(*str)) + str++; + + /* now copy until next white space */ + while (*str && !isspace(*str) && field_width--) { + *s++ = *str++; + } + *s = '\0'; + num++; + } + continue; + case 'n': + /* return number of characters read so far */ + { + int *i = (int *)va_arg(args,int*); + *i = str - buf; + } + continue; + case 'o': + base = 8; + break; + case 'x': + case 'X': + base = 16; + break; + case 'd': + case 'i': + is_sign = 1; + case 'u': + break; + case '%': + /* looking for '%' in str */ + if (*str++ != '%') + return num; + continue; + default: + /* invalid format; stop here */ + return num; + } + + /* have some sort of integer conversion. + * first, skip white space in buffer. + */ + while (isspace(*str)) + str++; + + if (!*str || !isdigit(*str)) + break; + + switch(qualifier) { + case 'h': + if (is_sign) { + short *s = (short *) va_arg(args,short *); + *s = (short) simple_strtol(str,&next,base); + } else { + unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); + *s = (unsigned short) simple_strtoul(str, &next, base); + } + break; + case 'l': + if (is_sign) { + long *l = (long *) va_arg(args,long *); + *l = simple_strtol(str,&next,base); + } else { + unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); + *l = simple_strtoul(str,&next,base); + } + break; + case 'L': + if (is_sign) { + long long *l = (long long*) va_arg(args,long long *); + *l = simple_strtoll(str,&next,base); + } else { + unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); + *l = simple_strtoull(str,&next,base); + } + break; + case 'Z': + { + unsigned long *s = (unsigned long*) va_arg(args,unsigned long*); + *s = (unsigned long) simple_strtoul(str,&next,base); + } + break; + default: + if (is_sign) { + int *i = (int *) va_arg(args, int*); + *i = (int) simple_strtol(str,&next,base); + } else { + unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); + *i = (unsigned int) simple_strtoul(str,&next,base); + } + break; + } + num++; + + if (!next) + break; + str = next; + } + return num; +} + +/** + * sscanf - Unformat a buffer into a list of arguments + * @buf: input buffer + * @fmt: formatting of buffer + * @...: resulting arguments + */ +int sscanf(const char * buf, const char * fmt, ...) +{ + va_list args; + int i; + + va_start(args,fmt); + i = vsscanf(buf,fmt,args); + va_end(args); + + return i; +} + +size_t strspn(const char *s, const char *accept) +{ + size_t l=0; + int a=1,i, al=strlen(accept); + + while((a)&&(*s)) + { + for(a=i=0;(!a)&&(i<al);i++) + if (*s==accept[i]) a=1; + if (a) l++; + s++; + } + return l; +} + +size_t strcspn(const char *s, const char *reject) +{ + size_t l=0; + int a=1,i,al=strlen(reject); + + while((a)&&(*s)) + { + for(i=0;(a)&&(i<al);i++) + if (*s==reject[i]) a=0; + if (a) l++; + s++; + } + return l; +} + +char*strtok_r(char*s,const char*delim,char**ptrptr) +{ + char*tmp=0; + + if (s==0) s=*ptrptr; + s += strspn(s,delim); /* overread leading delimiter */ + if (*s) + { + tmp=s; + s+=strcspn(s,delim); + + if (*s) *s++=0; /* not the end ? => terminate it */ + } + *ptrptr=s; + return tmp; +} + +char *strtok(char *s, const char *delim) +{ + static char *strtok_pos; + return strtok_r(s,delim,&strtok_pos); +} + +char *strchr(const char *s1, int i) +{ + const unsigned char *s = (const unsigned char *)s1; + unsigned char c = (unsigned int)i; + + while (*s && *s != c) + { + s++; + } + + if (*s != c) + { + s = NULL; + } + + return (char *) s; +} + +long strtol(const char *str, char **endptr, int base) +{ + return simple_strtol(str, endptr, base); +} + +long long strtoll(const char *str, char **endptr, int base) +{ + return simple_strtoll(str, endptr, base); +} + +#endif diff --git a/components/libc/compilers/minilibc/string.h b/components/libc/compilers/minilibc/string.h new file mode 100644 index 0000000000..089903e993 --- /dev/null +++ b/components/libc/compilers/minilibc/string.h @@ -0,0 +1,73 @@ +/* + * File : string.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-08-14 Bernard the first version + */ +#ifndef __STRING_H__ +#define __STRING_H__ + +#include <rtthread.h> +#include <sys/types.h> + +/* replace for standard string library */ +#if !defined (RT_USING_NEWLIB) && defined (RT_USING_MINILIBC) + +#define ZEROPAD (1 << 0) /* pad with zero */ +#define SIGN (1 << 1) /* unsigned/signed long */ +#define PLUS (1 << 2) /* show plus */ +#define SPACE (1 << 3) /* space if plus */ +#define LEFT (1 << 4) /* left justified */ +#define SPECIAL (1 << 5) /* 0x */ +#define LARGE (1 << 6) /* use 'ABCDEF' instead of 'abcdef' */ + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +void* memset(void *s, int c, size_t n); +void* memcpy(void *dest, const void *src, size_t n); +void* memmove(void *dest, const void *src, size_t n); +int memcmp(const void *s1, const void *s2, size_t n); + +int tolower(int c); +int toupper(int c); + +int strcmp (const char *s1, const char *s2); +int strncmp(const char *cs,const char *ct, size_t count); +int strcasecmp(const char *a, const char *b); +int strncasecmp(const char *cs, const char *ct, size_t count); +int sscanf(const char * buf, const char * fmt, ...); +size_t strlen(const char *s); +char *strstr(const char * s1,const char * s2); +char *strcpy(char *dest, const char *src); +char *strncpy(char *dest, const char *src, size_t n); +size_t strlcpy(char *dst, const char *src, size_t siz); +char *strncat(char *dest, const char *src, size_t count); +char *strcat(char * dest, const char * src); +char *strchr(const char *s1, int i); +char *strrchr(const char *t, int c); +char *strdup(const char *s); +char *strtok(char *s, const char *delim); +char*strtok_r(char*s, const char*delim, char**ptrptr); + +size_t strcspn(const char *s, const char *reject); +size_t strspn (const char *s, const char *accept); + +long strtol(const char *str, char **endptr, int base); +long long strtoll(const char *str, char **endptr, int base); +#endif + +#endif diff --git a/components/libc/compilers/minilibc/sys/stat.h b/components/libc/compilers/minilibc/sys/stat.h new file mode 100644 index 0000000000..7826cba945 --- /dev/null +++ b/components/libc/compilers/minilibc/sys/stat.h @@ -0,0 +1,36 @@ +#ifndef __STAT_H__ +#define __STAT_H__ + +#include <rtthread.h> + +#ifdef RT_USING_DFS +#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 */ + +#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 + +#endif diff --git a/components/libc/compilers/minilibc/sys/time.h b/components/libc/compilers/minilibc/sys/time.h new file mode 100644 index 0000000000..ada613251b --- /dev/null +++ b/components/libc/compilers/minilibc/sys/time.h @@ -0,0 +1,45 @@ +#ifndef _SYS_TIME_H_ +#define _SYS_TIME_H_ + +#include <sys/types.h> + +/* + * Structure returned by gettimeofday(2) system call, + * and used in other calls. + */ +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +/* + * Structure defined by POSIX.1b to be like a timeval. + */ +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; + +struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +struct tm { + int tm_sec; /* Seconds. [0-60] (1 leap second) */ + int tm_min; /* Minutes. [0-59] */ + int tm_hour; /* Hours. [0-23] */ + int tm_mday; /* Day. [1-31] */ + int tm_mon; /* Month. [0-11] */ + int tm_year; /* Year - 1900. */ + int tm_wday; /* Day of week. [0-6] */ + int tm_yday; /* Days in year.[0-365] */ + int tm_isdst; /* DST. [-1/0/1]*/ + + long int tm_gmtoff; /* Seconds east of UTC. */ + const char *tm_zone; /* Timezone abbreviation. */ +}; + +int gettimeofday(struct timeval *tp, void *ignore); + +#endif diff --git a/components/libc/compilers/minilibc/sys/types.h b/components/libc/compilers/minilibc/sys/types.h new file mode 100644 index 0000000000..a6860f2aee --- /dev/null +++ b/components/libc/compilers/minilibc/sys/types.h @@ -0,0 +1,27 @@ +#ifndef __TYPES_H__ +#define __TYPES_H__ + +#include <rtthread.h> + +typedef long off_t; +typedef __SIZE_TYPE__ size_t; +typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */ + +typedef rt_uint8_t u_char; +typedef rt_uint16_t u_short; +typedef rt_ubase_t u_int; +typedef rt_uint32_t u_long; + +typedef rt_time_t time_t; +typedef int mode_t; + +typedef unsigned long clockid_t; +typedef int pid_t; + +#ifndef NULL +#define NULL RT_NULL +#endif + +#define __u_char_defined + +#endif diff --git a/components/libc/compilers/minilibc/time.c b/components/libc/compilers/minilibc/time.c new file mode 100644 index 0000000000..efd6be8754 --- /dev/null +++ b/components/libc/compilers/minilibc/time.c @@ -0,0 +1,229 @@ +#include <time.h> + +/* 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 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 "; + +/* 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* 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); +} + +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)); +} + +#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 + +#ifndef _gettimeofday +/* Dummy function when hardware do not have RTC */ +int _gettimeofday( struct timeval *tv, void *ignore) +{ + tv->tv_sec = 0; // convert to seconds + tv->tv_usec = 0; // get remaining microseconds + return 0; // return non-zero for error +} +#endif diff --git a/components/libc/compilers/minilibc/time.h b/components/libc/compilers/minilibc/time.h new file mode 100644 index 0000000000..2f8ad23c71 --- /dev/null +++ b/components/libc/compilers/minilibc/time.h @@ -0,0 +1,6 @@ +#ifndef __TIME_H__ +#define __TIME_H__ + +#include <sys/time.h> + +#endif diff --git a/components/libc/compilers/newlib/SConscript b/components/libc/compilers/newlib/SConscript new file mode 100644 index 0000000000..574c2a8d1f --- /dev/null +++ b/components/libc/compilers/newlib/SConscript @@ -0,0 +1,18 @@ +from building import * + +src = Glob('*.c') +cwd = GetCurrentDir() + +CPPPATH = [cwd] +CPPDEFINES = ['RT_USING_NEWLIB'] + +# link with libc and libm: +# libm is a frequently used lib. Newlib is compiled with -ffunction-sections in +# recent GCC tool chains. The linker would just link in the functions that have +# been referenced. So setting this won't result in bigger text size. +LIBS = ['c', 'm'] + +group = DefineGroup('newlib', src, depend = ['RT_USING_LIBC'], + CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES, LIBS = LIBS) + +Return('group') diff --git a/components/libc/compilers/newlib/libc.c b/components/libc/compilers/newlib/libc.c new file mode 100644 index 0000000000..8f97e1c8b4 --- /dev/null +++ b/components/libc/compilers/newlib/libc.c @@ -0,0 +1,56 @@ +#include <rtthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/time.h> +#include "libc.h" + +#ifdef RT_USING_PTHREADS +#include <pthread.h> +#endif + +#ifdef RT_USING_DFS +#include <dfs_posix.h> + +#ifdef RT_USING_DFS_DEVFS +#include <devfs.h> +#endif + +#endif + +int libc_system_init(void) +{ +#ifdef RT_USING_DFS + int fd; + struct rt_device *console_dev; + +#ifndef RT_USING_DFS_DEVFS +#error Please enable devfs by defining RT_USING_DFS_DEVFS in rtconfig.h +#endif + + console_dev = rt_console_get_device(); + if (console_dev) + { + /* initialize console device */ + rt_console_init(console_dev->parent.name); + + /* open console as stdin/stdout/stderr */ + fd = open("/dev/console", O_RDONLY, 0); /* for stdin */ + fd = open("/dev/console", O_WRONLY, 0); /* for stdout */ + fd = open("/dev/console", O_WRONLY, 0); /* for stderr */ + + /* skip warning */ + fd = fd; + } +#endif + + /* set PATH and HOME */ + putenv("PATH=/bin"); + putenv("HOME=/home"); +#if defined RT_USING_PTHREADS && !defined RT_USING_COMPONENTS_INIT + pthread_system_init(); +#endif + + return 0; +} +INIT_COMPONENT_EXPORT(libc_system_init); diff --git a/components/libc/compilers/newlib/libc.h b/components/libc/compilers/newlib/libc.h new file mode 100644 index 0000000000..a4f342df33 --- /dev/null +++ b/components/libc/compilers/newlib/libc.h @@ -0,0 +1,21 @@ +#ifndef __RTT_LIBC_H__ +#define __RTT_LIBC_H__ + +#include <sys/time.h> + +#define MILLISECOND_PER_SECOND 1000UL +#define MICROSECOND_PER_SECOND 1000000UL +#define NANOSECOND_PER_SECOND 1000000000UL + +#define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) + +int libc_system_init(void); + +/* some time related function */ +int libc_set_time(const struct timespec *time); +int libc_get_time(struct timespec *time); +int libc_time_to_tick(const struct timespec *time); + +#endif diff --git a/components/libc/compilers/newlib/libc_sym.c b/components/libc/compilers/newlib/libc_sym.c new file mode 100644 index 0000000000..48e488f5d8 --- /dev/null +++ b/components/libc/compilers/newlib/libc_sym.c @@ -0,0 +1,47 @@ +#include <rtthread.h> +#include <rtm.h> + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +RTM_EXPORT(strcpy); +RTM_EXPORT(strncpy); +RTM_EXPORT(strlen); +RTM_EXPORT(strcat); +RTM_EXPORT(strstr); +RTM_EXPORT(strchr); +RTM_EXPORT(strcmp); +RTM_EXPORT(strtol); +RTM_EXPORT(strtoul); +RTM_EXPORT(strncmp); + +RTM_EXPORT(memcpy); +RTM_EXPORT(memcmp); +RTM_EXPORT(memmove); +RTM_EXPORT(memset); +RTM_EXPORT(memchr); + +RTM_EXPORT(putchar); +RTM_EXPORT(puts); +RTM_EXPORT(printf); +RTM_EXPORT(sprintf); +RTM_EXPORT(snprintf); + +RTM_EXPORT(fwrite); + +#include <time.h> +RTM_EXPORT(localtime); +RTM_EXPORT(time); + +#include <setjmp.h> +RTM_EXPORT(longjmp); +RTM_EXPORT(setjmp); + +RTM_EXPORT(exit); +RTM_EXPORT(abort); + +RTM_EXPORT(rand); + +#include <assert.h> +RTM_EXPORT(__assert_func); diff --git a/components/libc/compilers/newlib/sys/dirent.h b/components/libc/compilers/newlib/sys/dirent.h new file mode 100644 index 0000000000..2efc683579 --- /dev/null +++ b/components/libc/compilers/newlib/sys/dirent.h @@ -0,0 +1,57 @@ +#ifndef __RTT_DIRENT_H__ +#define __RTT_DIRENT_H__ + +#include <rtthread.h> + +/* +* dirent.h - format of directory entries + * Ref: http://www.opengroup.org/onlinepubs/009695399/basedefs/dirent.h.html + */ + +/* File types */ +#define FT_REGULAR 0 /* regular file */ +#define FT_SOCKET 1 /* socket file */ +#define FT_DIRECTORY 2 /* directory */ +#define FT_USER 3 /* user defined */ + +#define DT_UNKNOWN 0x00 +#define DT_REG 0x01 +#define DT_DIR 0x02 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_DIR_STRUCTURE +typedef struct +{ + int fd; /* directory file */ + char buf[512]; + int num; + int cur; +} DIR; +#endif + +#ifndef HAVE_DIRENT_STRUCTURE +struct dirent +{ + rt_uint8_t d_type; /* The type of the file */ + rt_uint8_t d_namlen; /* The length of the not including the terminating null file name */ + rt_uint16_t d_reclen; /* length of this record */ + char d_name[256]; /* The null-terminated file name */ +}; +#endif + +int closedir(DIR *); +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +int readdir_r(DIR *, struct dirent *, struct dirent **); +void rewinddir(DIR *); +void seekdir(DIR *, long int); +long telldir(DIR *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/libc/compilers/newlib/sys/fcntl.h b/components/libc/compilers/newlib/sys/fcntl.h new file mode 100644 index 0000000000..a53ca808b2 --- /dev/null +++ b/components/libc/compilers/newlib/sys/fcntl.h @@ -0,0 +1,18 @@ +#ifndef __RTT_FCNTL_H__ +#define __RTT_FCNTL_H__ + +/* Operation flags */ +#define O_RDONLY 0x0000000 +#define O_WRONLY 0x0000001 +#define O_RDWR 0x0000002 +#define O_ACCMODE 0x0000003 +#define O_CREAT 0x0000100 +#define O_EXCL 0x0000200 +#define O_TRUNC 0x0001000 +#define O_APPEND 0x0002000 +#define O_DIRECTORY 0x0200000 +#define O_BINARY 0x0008000 + +#include <unistd.h> + +#endif diff --git a/components/libc/compilers/newlib/sys/statfs.h b/components/libc/compilers/newlib/sys/statfs.h new file mode 100644 index 0000000000..95772b5ead --- /dev/null +++ b/components/libc/compilers/newlib/sys/statfs.h @@ -0,0 +1,13 @@ +#ifndef __RTT_STATFS_H__ +#define __RTT_STATFS_H__ + +#include <rtthread.h> + +struct statfs +{ + rt_size_t f_bsize; /* block size */ + rt_size_t f_blocks; /* total data blocks in file system */ + rt_size_t f_bfree; /* free blocks in file system */ +}; + +#endif diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c new file mode 100644 index 0000000000..ff09a4fe80 --- /dev/null +++ b/components/libc/compilers/newlib/syscalls.c @@ -0,0 +1,464 @@ +#include <reent.h> +#include <sys/errno.h> +#include <sys/time.h> +#include <rtthread.h> + +#ifdef RT_USING_DFS +#include <dfs_posix.h> +#endif + +#ifdef RT_USING_PTHREADS +#include <pthread.h> +#endif + +/* Reentrant versions of system calls. */ + +int +_close_r(struct _reent *ptr, int fd) +{ +#ifndef RT_USING_DFS + return 0; +#else + return close(fd); +#endif +} + +int +_execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_fcntl_r(struct _reent *ptr, int fd, int cmd, int arg) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_fork_r(struct _reent *ptr) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_fstat_r(struct _reent *ptr, int fd, struct stat *pstat) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_getpid_r(struct _reent *ptr) +{ + return 0; +} + +int +_isatty_r(struct _reent *ptr, int fd) +{ + if (fd >=0 && fd < 3) return 1; + + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_kill_r(struct _reent *ptr, int pid, int sig) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_link_r(struct _reent *ptr, const char *old, const char *new) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +_off_t +_lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence) +{ +#ifndef RT_USING_DFS + return 0; +#else + _off_t rc; + + rc = lseek(fd, pos, whence); + return rc; +#endif +} + +int +_mkdir_r(struct _reent *ptr, const char *name, int mode) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = mkdir(name, mode); + return rc; +#endif +} + +int +_open_r(struct _reent *ptr, const char *file, int flags, int mode) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = open(file, flags, mode); + return rc; +#endif +} + +_ssize_t +_read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) +{ +#ifndef RT_USING_DFS + return 0; +#else + _ssize_t rc; + + rc = read(fd, buf, nbytes); + return rc; +#endif +} + +int +_rename_r(struct _reent *ptr, const char *old, const char *new) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = rename(old, new); + return rc; +#endif +} + +void * +_sbrk_r(struct _reent *ptr, ptrdiff_t incr) +{ + /* no use this routine to get memory */ + return RT_NULL; +} + +int +_stat_r(struct _reent *ptr, const char *file, struct stat *pstat) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = stat(file, pstat); + return rc; +#endif +} + +_CLOCK_T_ +_times_r(struct _reent *ptr, struct tms *ptms) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +int +_unlink_r(struct _reent *ptr, const char *file) +{ +#ifndef RT_USING_DFS + return 0; +#else + int rc; + + rc = unlink(file); + return rc; +#endif +} + +int +_wait_r(struct _reent *ptr, int *status) +{ + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} + +#ifdef RT_USING_DEVICE +_ssize_t +_write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) +{ + if (fd < 3) + { +#ifdef RT_USING_CONSOLE + rt_device_t console_device; + extern rt_device_t rt_console_get_device(void); + + console_device = rt_console_get_device(); + if (console_device != 0) rt_device_write(console_device, 0, buf, nbytes); + return nbytes; +#else + return 0; +#endif + } + else + { +#ifdef RT_USING_DFS + _ssize_t rc; + + rc = write(fd, buf, nbytes); + return rc; +#else + return 0; +#endif + } +} +#endif + +#ifndef RT_USING_PTHREADS + +#ifndef MILLISECOND_PER_SECOND +#define MILLISECOND_PER_SECOND 1000UL +#endif + +#ifndef MICROSECOND_PER_SECOND +#define MICROSECOND_PER_SECOND 1000000UL +#endif + +#ifndef NANOSECOND_PER_SECOND +#define NANOSECOND_PER_SECOND 1000000000UL +#endif + +#define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) + + +struct timeval _timevalue = {0}; +#ifdef RT_USING_DEVICE +static void libc_system_time_init(void) +{ + time_t time; + rt_tick_t tick; + rt_device_t device; + + time = 0; + device = rt_device_find("rtc"); + if (device != RT_NULL) + { + /* get realtime seconds */ + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + } + + /* get tick */ + tick = rt_tick_get(); + + _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; + _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; +} +#endif + +int libc_get_time(struct timespec *time) +{ + rt_tick_t tick; + static rt_bool_t inited = 0; + + RT_ASSERT(time != RT_NULL); + + /* initialize system time */ + if (inited == 0) + { + libc_system_time_init(); + inited = 1; + } + + /* get tick */ + tick = rt_tick_get(); + + time->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND; + time->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000; + + return 0; +} + +int +_gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp) +{ + struct timespec tp; + + if (libc_get_time(&tp) == 0) + { + if (__tp != RT_NULL) + { + __tp->tv_sec = tp.tv_sec; + __tp->tv_usec = tp.tv_nsec / 1000UL; + } + + return tp.tv_sec; + } + + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} +#else +/* POSIX thread provides clock_gettime function */ +#include <time.h> +int +_gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp) +{ + struct timespec tp; + + if (clock_gettime(CLOCK_REALTIME, &tp) == 0) + { + if (__tp != RT_NULL) + { + __tp->tv_sec = tp.tv_sec; + __tp->tv_usec = tp.tv_nsec / 1000UL; + } + + return tp.tv_sec; + } + + /* return "not supported" */ + ptr->_errno = ENOTSUP; + return -1; +} +#endif + +/* Memory routine */ +void * +_malloc_r (struct _reent *ptr, size_t size) +{ + void* result; + + result = (void*)rt_malloc (size); + if (result == RT_NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void * +_realloc_r (struct _reent *ptr, void *old, size_t newlen) +{ + void* result; + + result = (void*)rt_realloc (old, newlen); + if (result == RT_NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void *_calloc_r (struct _reent *ptr, size_t size, size_t len) +{ + void* result; + + result = (void*)rt_calloc (size, len); + if (result == RT_NULL) + { + ptr->_errno = ENOMEM; + } + + return result; +} + +void +_free_r (struct _reent *ptr, void *addr) +{ + rt_free (addr); +} + +void +_exit (int status) +{ +#ifdef RT_USING_MODULE + rt_module_t module; + + module = rt_module_self(); + if (module != RT_NULL) + { + struct rt_list_node *list; + struct rt_object *object; + + rt_enter_critical(); + + /* delete all threads in the module */ + list = &module->module_object[RT_Object_Class_Thread].object_list; + while (list->next != list) + { + object = rt_list_entry(list->next, struct rt_object, list); + if (rt_object_is_systemobject(object) == RT_TRUE) + { + /* detach static object */ + rt_thread_detach((rt_thread_t)object); + } + else + { + /* delete dynamic object */ + rt_thread_delete((rt_thread_t)object); + } + } + /* delete main thread */ + rt_thread_delete(module->module_thread); + rt_exit_critical(); + + /* re-schedule */ + rt_schedule(); + } +#endif + + rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status); + RT_ASSERT(0); + + while (1); +} + +void +_system(const char *s) +{ + /* not support this call */ + return; +} + +void __libc_init_array(void) +{ + /* we not use __libc init_aray to initialize C++ objects */ +} + +void abort(void) +{ + if (rt_thread_self()) + { + rt_thread_t self = rt_thread_self(); + + rt_kprintf("thread:%-8.*s abort!\n", RT_NAME_MAX, self->name); + rt_thread_suspend(self); + + rt_schedule(); + } + + while (1); +} |
