syscalls.c 7.2 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 */
9 10 11
#include <reent.h>
#include <sys/errno.h>
#include <sys/time.h>
12 13
#include <stdio.h>

14 15
#include <rtthread.h>

B
Bernard Xiong 已提交
16 17 18 19
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#endif

20
#ifdef RT_USING_PTHREADS
B
Bernard Xiong 已提交
21 22 23
#include <pthread.h>
#endif

24 25 26 27
#ifdef RT_USING_MODULE
#include <dlmodule.h>
#endif

28 29 30 31 32
/* Reentrant versions of system calls.  */

int
_close_r(struct _reent *ptr, int fd)
{
33
#ifndef RT_USING_DFS
B
BernardXiong 已提交
34
    return 0;
35
#else
B
BernardXiong 已提交
36
    return close(fd);
37
#endif
38 39 40 41 42
}

int
_execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env)
{
B
BernardXiong 已提交
43 44 45
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
46 47 48 49 50
}

int
_fcntl_r(struct _reent *ptr, int fd, int cmd, int arg)
{
B
BernardXiong 已提交
51 52 53
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
54 55 56 57 58
}

int
_fork_r(struct _reent *ptr)
{
B
BernardXiong 已提交
59 60 61
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
62 63 64 65 66
}

int
_fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
{
B
BernardXiong 已提交
67 68 69
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
70 71 72 73 74
}

int
_getpid_r(struct _reent *ptr)
{
B
BernardXiong 已提交
75
    return 0;
76 77 78 79 80
}

int
_isatty_r(struct _reent *ptr, int fd)
{
B
BernardXiong 已提交
81
    if (fd >=0 && fd < 3) return 1;
82

B
BernardXiong 已提交
83 84 85
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
86 87 88 89 90
}

int
_kill_r(struct _reent *ptr, int pid, int sig)
{
B
BernardXiong 已提交
91 92 93
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
94 95 96 97 98
}

int
_link_r(struct _reent *ptr, const char *old, const char *new)
{
B
BernardXiong 已提交
99 100 101
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
102 103 104 105 106
}

_off_t
_lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence)
{
107
#ifndef RT_USING_DFS
B
BernardXiong 已提交
108
    return 0;
109
#else
B
BernardXiong 已提交
110
    _off_t rc;
111

B
BernardXiong 已提交
112 113
    rc = lseek(fd, pos, whence);
    return rc;
114
#endif
115 116 117 118 119
}

int
_mkdir_r(struct _reent *ptr, const char *name, int mode)
{
120
#ifndef RT_USING_DFS
B
BernardXiong 已提交
121
    return 0;
122
#else
B
BernardXiong 已提交
123
    int rc;
124

B
BernardXiong 已提交
125 126
    rc = mkdir(name, mode);
    return rc;
127
#endif
128 129 130 131 132
}

int
_open_r(struct _reent *ptr, const char *file, int flags, int mode)
{
133
#ifndef RT_USING_DFS
B
BernardXiong 已提交
134
    return 0;
135
#else
B
BernardXiong 已提交
136
    int rc;
137

B
BernardXiong 已提交
138 139
    rc = open(file, flags, mode);
    return rc;
140
#endif
141 142
}

143
_ssize_t
144 145
_read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
{
146
#ifndef RT_USING_DFS
B
BernardXiong 已提交
147
    return 0;
148
#else
B
BernardXiong 已提交
149
    _ssize_t rc;
150

B
BernardXiong 已提交
151 152
    rc = read(fd, buf, nbytes);
    return rc;
153
#endif
154 155 156 157 158
}

int
_rename_r(struct _reent *ptr, const char *old, const char *new)
{
159
#ifndef RT_USING_DFS
B
BernardXiong 已提交
160
    return 0;
161
#else
B
BernardXiong 已提交
162
    int rc;
163

B
BernardXiong 已提交
164 165
    rc = rename(old, new);
    return rc;
166
#endif
167 168 169 170 171
}

void *
_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
{
B
BernardXiong 已提交
172 173
    /* no use this routine to get memory */
    return RT_NULL;
174 175 176 177 178
}

int
_stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
{
179
#ifndef RT_USING_DFS
B
BernardXiong 已提交
180
    return 0;
181
#else
B
BernardXiong 已提交
182
    int rc;
183

B
BernardXiong 已提交
184 185
    rc = stat(file, pstat);
    return rc;
186
#endif
187 188 189 190 191
}

_CLOCK_T_
_times_r(struct _reent *ptr, struct tms *ptms)
{
B
BernardXiong 已提交
192 193 194
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
195 196 197 198 199
}

int
_unlink_r(struct _reent *ptr, const char *file)
{
200
#ifndef RT_USING_DFS
B
BernardXiong 已提交
201
    return 0;
202
#else
B
BernardXiong 已提交
203
    int rc;
204

B
BernardXiong 已提交
205 206
    rc = unlink(file);
    return rc;
207
#endif
208 209 210 211 212
}

int
_wait_r(struct _reent *ptr, int *status)
{
B
BernardXiong 已提交
213 214 215
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
216 217
}

218
#ifdef RT_USING_DEVICE
219 220 221
_ssize_t
_write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
{
B
bernard 已提交
222
#ifndef RT_USING_DFS
223
    if (fileno(stdout) == fd)
B
BernardXiong 已提交
224 225
    {
        rt_device_t console;
226

B
BernardXiong 已提交
227 228 229
        console = rt_console_get_device();
        if (console) return rt_device_write(console, -1, buf, nbytes);
    }
230

B
bernard 已提交
231 232
    return 0;

233
#else
B
BernardXiong 已提交
234
    _ssize_t rc;
B
bernard 已提交
235

B
BernardXiong 已提交
236 237
    rc = write(fd, buf, nbytes);
    return rc;
238
#endif
239
}
240
#endif
241

B
BernardXiong 已提交
242
#ifdef RT_USING_PTHREADS
243

B
BernardXiong 已提交
244 245 246 247 248 249 250
#include <clock_time.h>
/* POSIX timer provides clock_gettime function */
#include <time.h>
int
_gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp)
{
    struct timespec tp;
251

B
BernardXiong 已提交
252 253 254 255 256 257 258
    if (clock_gettime(CLOCK_REALTIME, &tp) == 0)
    {
        if (__tp != RT_NULL)
        {
            __tp->tv_sec  = tp.tv_sec;
            __tp->tv_usec = tp.tv_nsec / 1000UL;
        }
259

B
BernardXiong 已提交
260 261 262 263 264 265 266
        return tp.tv_sec;
    }

    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
}
267

B
BernardXiong 已提交
268 269 270 271 272
#else

#define MILLISECOND_PER_SECOND  1000UL
#define MICROSECOND_PER_SECOND  1000000UL
#define NANOSECOND_PER_SECOND   1000000000UL
273

B
BernardXiong 已提交
274 275 276
#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)
277 278

struct timeval _timevalue = {0};
279 280
#ifdef RT_USING_DEVICE
static void libc_system_time_init(void)
281
{
B
BernardXiong 已提交
282 283 284
    time_t time;
    rt_tick_t tick;
    rt_device_t device;
285

B
BernardXiong 已提交
286 287 288 289 290 291 292
    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);
    }
293

B
BernardXiong 已提交
294 295
    /* get tick */
    tick = rt_tick_get();
296

B
BernardXiong 已提交
297 298
    _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
    _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
299
}
300
#endif
301 302 303

int libc_get_time(struct timespec *time)
{
B
BernardXiong 已提交
304 305
    rt_tick_t tick;
    static rt_bool_t inited = 0;
306

B
BernardXiong 已提交
307
    RT_ASSERT(time != RT_NULL);
308

B
BernardXiong 已提交
309 310 311 312 313 314
    /* initialize system time */
    if (inited == 0)
    {
        libc_system_time_init();
        inited = 1;
    }
315

B
BernardXiong 已提交
316 317
    /* get tick */
    tick = rt_tick_get();
318

B
BernardXiong 已提交
319 320
    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;
321

B
BernardXiong 已提交
322
    return 0;
323 324 325 326 327
}

int
_gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp)
{
B
BernardXiong 已提交
328
    struct timespec tp;
329

B
BernardXiong 已提交
330 331 332 333 334 335 336
    if (libc_get_time(&tp) == 0)
    {
        if (__tp != RT_NULL)
        {
            __tp->tv_sec  = tp.tv_sec;
            __tp->tv_usec = tp.tv_nsec / 1000UL;
        }
337

B
BernardXiong 已提交
338 339
        return tp.tv_sec;
    }
340

B
BernardXiong 已提交
341 342 343
    /* return "not supported" */
    ptr->_errno = ENOTSUP;
    return -1;
344 345 346 347 348 349 350
}
#endif

/* Memory routine */
void *
_malloc_r (struct _reent *ptr, size_t size)
{
B
BernardXiong 已提交
351
    void* result;
352

B
BernardXiong 已提交
353 354 355 356 357
    result = (void*)rt_malloc (size);
    if (result == RT_NULL)
    {
        ptr->_errno = ENOMEM;
    }
358

B
BernardXiong 已提交
359
    return result;
360 361 362 363 364
}

void *
_realloc_r (struct _reent *ptr, void *old, size_t newlen)
{
B
BernardXiong 已提交
365
    void* result;
366

B
BernardXiong 已提交
367 368 369 370 371
    result = (void*)rt_realloc (old, newlen);
    if (result == RT_NULL)
    {
        ptr->_errno = ENOMEM;
    }
372

B
BernardXiong 已提交
373
    return result;
374 375 376 377
}

void *_calloc_r (struct _reent *ptr, size_t size, size_t len)
{
B
BernardXiong 已提交
378
    void* result;
379

B
BernardXiong 已提交
380 381 382 383 384
    result = (void*)rt_calloc (size, len);
    if (result == RT_NULL)
    {
        ptr->_errno = ENOMEM;
    }
385

B
BernardXiong 已提交
386
    return result;
387 388
}

389
void
390 391
_free_r (struct _reent *ptr, void *addr)
{
B
BernardXiong 已提交
392
    rt_free (addr);
393 394 395
}

void
396
exit (int status)
397
{
398
#ifdef RT_USING_MODULE
399
    if (dlmodule_self())
B
BernardXiong 已提交
400
    {
401
        dlmodule_exit(status);
B
BernardXiong 已提交
402
    }
403
#endif
404

B
BernardXiong 已提交
405 406
    rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status);
    RT_ASSERT(0);
407

B
BernardXiong 已提交
408
    while (1);
409
}
410

411
void
412 413 414 415 416
_system(const char *s)
{
    /* not support this call */
    return;
}
417 418 419

void __libc_init_array(void)
{
B
BernardXiong 已提交
420
    /* we not use __libc init_aray to initialize C++ objects */
421
}
422 423 424

void abort(void)
{
425 426 427 428 429 430 431 432 433 434
    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();
    }

B
BernardXiong 已提交
435
    while (1);
436
}