1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 */ 9 #include <reent.h> 10 #include <sys/errno.h> 11 #include <sys/time.h> 12 #include <stdio.h> 13 14 #include <rtthread.h> 15 16 #ifdef RT_USING_DFS 17 #include <dfs_posix.h> 18 #endif 19 20 #ifdef RT_USING_PTHREADS 21 #include <pthread.h> 22 #endif 23 24 #ifdef RT_USING_MODULE 25 #include <dlmodule.h> 26 #endif 27 28 /* Reentrant versions of system calls. */ 29 30 int 31 _close_r(struct _reent *ptr, int fd) 32 { 33 #ifndef RT_USING_DFS 34 return 0; 35 #else 36 return close(fd); 37 #endif 38 } 39 40 int 41 _execve_r(struct _reent *ptr, const char * name, char *const *argv, char *const *env) 42 { 43 /* return "not supported" */ 44 ptr->_errno = ENOTSUP; 45 return -1; 46 } 47 48 int 49 _fcntl_r(struct _reent *ptr, int fd, int cmd, int arg) 50 { 51 /* return "not supported" */ 52 ptr->_errno = ENOTSUP; 53 return -1; 54 } 55 56 int 57 _fork_r(struct _reent *ptr) 58 { 59 /* return "not supported" */ 60 ptr->_errno = ENOTSUP; 61 return -1; 62 } 63 64 int 65 _fstat_r(struct _reent *ptr, int fd, struct stat *pstat) 66 { 67 /* return "not supported" */ 68 ptr->_errno = ENOTSUP; 69 return -1; 70 } 71 72 int 73 _getpid_r(struct _reent *ptr) 74 { 75 return 0; 76 } 77 78 int 79 _isatty_r(struct _reent *ptr, int fd) 80 { 81 if (fd >=0 && fd < 3) return 1; 82 83 /* return "not supported" */ 84 ptr->_errno = ENOTSUP; 85 return -1; 86 } 87 88 int 89 _kill_r(struct _reent *ptr, int pid, int sig) 90 { 91 /* return "not supported" */ 92 ptr->_errno = ENOTSUP; 93 return -1; 94 } 95 96 int 97 _link_r(struct _reent *ptr, const char *old, const char *new) 98 { 99 /* return "not supported" */ 100 ptr->_errno = ENOTSUP; 101 return -1; 102 } 103 104 _off_t 105 _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence) 106 { 107 #ifndef RT_USING_DFS 108 return 0; 109 #else 110 _off_t rc; 111 112 rc = lseek(fd, pos, whence); 113 return rc; 114 #endif 115 } 116 117 int 118 _mkdir_r(struct _reent *ptr, const char *name, int mode) 119 { 120 #ifndef RT_USING_DFS 121 return 0; 122 #else 123 int rc; 124 125 rc = mkdir(name, mode); 126 return rc; 127 #endif 128 } 129 130 int 131 _open_r(struct _reent *ptr, const char *file, int flags, int mode) 132 { 133 #ifndef RT_USING_DFS 134 return 0; 135 #else 136 int rc; 137 138 rc = open(file, flags, mode); 139 return rc; 140 #endif 141 } 142 143 _ssize_t 144 _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes) 145 { 146 #ifndef RT_USING_DFS 147 return 0; 148 #else 149 _ssize_t rc; 150 151 rc = read(fd, buf, nbytes); 152 return rc; 153 #endif 154 } 155 156 int 157 _rename_r(struct _reent *ptr, const char *old, const char *new) 158 { 159 #ifndef RT_USING_DFS 160 return 0; 161 #else 162 int rc; 163 164 rc = rename(old, new); 165 return rc; 166 #endif 167 } 168 169 void * 170 _sbrk_r(struct _reent *ptr, ptrdiff_t incr) 171 { 172 /* no use this routine to get memory */ 173 return RT_NULL; 174 } 175 176 int 177 _stat_r(struct _reent *ptr, const char *file, struct stat *pstat) 178 { 179 #ifndef RT_USING_DFS 180 return 0; 181 #else 182 int rc; 183 184 rc = stat(file, pstat); 185 return rc; 186 #endif 187 } 188 189 _CLOCK_T_ 190 _times_r(struct _reent *ptr, struct tms *ptms) 191 { 192 /* return "not supported" */ 193 ptr->_errno = ENOTSUP; 194 return -1; 195 } 196 197 int 198 _unlink_r(struct _reent *ptr, const char *file) 199 { 200 #ifndef RT_USING_DFS 201 return 0; 202 #else 203 int rc; 204 205 rc = unlink(file); 206 return rc; 207 #endif 208 } 209 210 int 211 _wait_r(struct _reent *ptr, int *status) 212 { 213 /* return "not supported" */ 214 ptr->_errno = ENOTSUP; 215 return -1; 216 } 217 218 #ifdef RT_USING_DEVICE 219 _ssize_t 220 _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes) 221 { 222 #ifndef RT_USING_DFS 223 if (fileno(stdout) == fd) 224 { 225 rt_device_t console; 226 227 console = rt_console_get_device(); 228 if (console) return rt_device_write(console, -1, buf, nbytes); 229 } 230 231 return 0; 232 233 #else 234 _ssize_t rc; 235 236 rc = write(fd, buf, nbytes); 237 return rc; 238 #endif 239 } 240 #endif 241 242 #ifdef RT_USING_PTHREADS 243 244 #include <clock_time.h> 245 /* POSIX timer provides clock_gettime function */ 246 #include <time.h> 247 int 248 _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp) 249 { 250 struct timespec tp; 251 252 if (clock_gettime(CLOCK_REALTIME, &tp) == 0) 253 { 254 if (__tp != RT_NULL) 255 { 256 __tp->tv_sec = tp.tv_sec; 257 __tp->tv_usec = tp.tv_nsec / 1000UL; 258 } 259 260 return tp.tv_sec; 261 } 262 263 /* return "not supported" */ 264 ptr->_errno = ENOTSUP; 265 return -1; 266 } 267 268 #else 269 270 #define MILLISECOND_PER_SECOND 1000UL 271 #define MICROSECOND_PER_SECOND 1000000UL 272 #define NANOSECOND_PER_SECOND 1000000000UL 273 274 #define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND) 275 #define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) 276 #define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) 277 278 struct timeval _timevalue = {0}; 279 #ifdef RT_USING_DEVICE 280 static void libc_system_time_init(void) 281 { 282 time_t time; 283 rt_tick_t tick; 284 rt_device_t device; 285 286 time = 0; 287 device = rt_device_find("rtc"); 288 if (device != RT_NULL) 289 { 290 /* get realtime seconds */ 291 rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); 292 } 293 294 /* get tick */ 295 tick = rt_tick_get(); 296 297 _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; 298 _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; 299 } 300 #endif 301 302 int libc_get_time(struct timespec *time) 303 { 304 rt_tick_t tick; 305 static rt_bool_t inited = 0; 306 307 RT_ASSERT(time != RT_NULL); 308 309 /* initialize system time */ 310 if (inited == 0) 311 { 312 libc_system_time_init(); 313 inited = 1; 314 } 315 316 /* get tick */ 317 tick = rt_tick_get(); 318 319 time->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND; 320 time->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000; 321 322 return 0; 323 } 324 325 int 326 _gettimeofday_r(struct _reent *ptr, struct timeval *__tp, void *__tzp) 327 { 328 struct timespec tp; 329 330 if (libc_get_time(&tp) == 0) 331 { 332 if (__tp != RT_NULL) 333 { 334 __tp->tv_sec = tp.tv_sec; 335 __tp->tv_usec = tp.tv_nsec / 1000UL; 336 } 337 338 return tp.tv_sec; 339 } 340 341 /* return "not supported" */ 342 ptr->_errno = ENOTSUP; 343 return -1; 344 } 345 #endif 346 347 /* Memory routine */ 348 void * 349 _malloc_r (struct _reent *ptr, size_t size) 350 { 351 void* result; 352 353 result = (void*)rt_malloc (size); 354 if (result == RT_NULL) 355 { 356 ptr->_errno = ENOMEM; 357 } 358 359 return result; 360 } 361 362 void * 363 _realloc_r (struct _reent *ptr, void *old, size_t newlen) 364 { 365 void* result; 366 367 result = (void*)rt_realloc (old, newlen); 368 if (result == RT_NULL) 369 { 370 ptr->_errno = ENOMEM; 371 } 372 373 return result; 374 } 375 376 void *_calloc_r (struct _reent *ptr, size_t size, size_t len) 377 { 378 void* result; 379 380 result = (void*)rt_calloc (size, len); 381 if (result == RT_NULL) 382 { 383 ptr->_errno = ENOMEM; 384 } 385 386 return result; 387 } 388 389 void 390 _free_r (struct _reent *ptr, void *addr) 391 { 392 rt_free (addr); 393 } 394 395 void 396 exit (int status) 397 { 398 #ifdef RT_USING_MODULE 399 if (dlmodule_self()) 400 { 401 dlmodule_exit(status); 402 } 403 #endif 404 405 rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status); 406 RT_ASSERT(0); 407 408 while (1); 409 } 410 411 void 412 _system(const char *s) 413 { 414 /* not support this call */ 415 return; 416 } 417 418 void __libc_init_array(void) 419 { 420 /* we not use __libc init_aray to initialize C++ objects */ 421 } 422 423 void abort(void) 424 { 425 if (rt_thread_self()) 426 { 427 rt_thread_t self = rt_thread_self(); 428 429 rt_kprintf("thread:%-8.*s abort!\n", RT_NAME_MAX, self->name); 430 rt_thread_suspend(self); 431 432 rt_schedule(); 433 } 434 435 while (1); 436 } 437