Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TUKS-COURSE-TIMER by
retarget.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "platform/platform.h" 00017 #include "drivers/FileHandle.h" 00018 #include "drivers/FileSystemLike.h" 00019 #include "drivers/FilePath.h" 00020 #include "hal/serial_api.h" 00021 #include "platform/toolchain.h" 00022 #include "platform/semihost_api.h" 00023 #include "platform/mbed_interface.h" 00024 #include "platform/SingletonPtr.h" 00025 #include "platform/PlatformMutex.h" 00026 #include "platform/mbed_error.h" 00027 #include "platform/mbed_stats.h" 00028 #include <stdlib.h> 00029 #include <string.h> 00030 #if DEVICE_STDIO_MESSAGES 00031 #include <stdio.h> 00032 #endif 00033 #include <errno.h> 00034 00035 #if defined(__ARMCC_VERSION) 00036 # include <rt_sys.h> 00037 # define PREFIX(x) _sys##x 00038 # define OPEN_MAX _SYS_OPEN 00039 # ifdef __MICROLIB 00040 # pragma import(__use_full_stdio) 00041 # endif 00042 00043 #elif defined(__ICCARM__) 00044 # include <yfuns.h> 00045 # define PREFIX(x) _##x 00046 # define OPEN_MAX 16 00047 00048 # define STDIN_FILENO 0 00049 # define STDOUT_FILENO 1 00050 # define STDERR_FILENO 2 00051 00052 #else 00053 # include <sys/stat.h> 00054 # include <sys/unistd.h> 00055 # include <sys/syslimits.h> 00056 # define PREFIX(x) x 00057 #endif 00058 00059 #define FILE_HANDLE_RESERVED 0xFFFFFFFF 00060 00061 using namespace mbed; 00062 00063 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) 00064 // Before version 5.03, we were using a patched version of microlib with proper names 00065 extern const char __stdin_name[] = ":tt"; 00066 extern const char __stdout_name[] = ":tt"; 00067 extern const char __stderr_name[] = ":tt"; 00068 00069 #else 00070 extern const char __stdin_name[] = "/stdin"; 00071 extern const char __stdout_name[] = "/stdout"; 00072 extern const char __stderr_name[] = "/stderr"; 00073 #endif 00074 00075 // Heap limits - only used if set 00076 unsigned char *mbed_heap_start = 0; 00077 uint32_t mbed_heap_size = 0; 00078 00079 /* newlib has the filehandle field in the FILE struct as a short, so 00080 * we can't just return a Filehandle* from _open and instead have to 00081 * put it in a filehandles array and return the index into that array 00082 * (or rather index+3, as filehandles 0-2 are stdin/out/err). 00083 */ 00084 static FileHandle *filehandles[OPEN_MAX]; 00085 static SingletonPtr<PlatformMutex> filehandle_mutex; 00086 00087 FileHandle::~FileHandle() { 00088 filehandle_mutex->lock(); 00089 /* Remove all open filehandles for this */ 00090 for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { 00091 if (filehandles[fh_i] == this) { 00092 filehandles[fh_i] = NULL; 00093 } 00094 } 00095 filehandle_mutex->unlock(); 00096 } 00097 00098 #if DEVICE_SERIAL 00099 extern int stdio_uart_inited; 00100 extern serial_t stdio_uart; 00101 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES 00102 static char stdio_in_prev; 00103 static char stdio_out_prev; 00104 #endif 00105 #endif 00106 00107 static void init_serial() { 00108 #if DEVICE_SERIAL 00109 if (stdio_uart_inited) return; 00110 serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX); 00111 #if MBED_CONF_PLATFORM_STDIO_BAUD_RATE 00112 serial_baud(&stdio_uart, MBED_CONF_PLATFORM_STDIO_BAUD_RATE); 00113 #endif 00114 #endif 00115 } 00116 00117 static inline int openmode_to_posix(int openmode) { 00118 int posix = openmode; 00119 #ifdef __ARMCC_VERSION 00120 if (openmode & OPEN_PLUS) { 00121 posix = O_RDWR; 00122 } else if(openmode & OPEN_W) { 00123 posix = O_WRONLY; 00124 } else if(openmode & OPEN_A) { 00125 posix = O_WRONLY|O_APPEND; 00126 } else { 00127 posix = O_RDONLY; 00128 } 00129 /* a, w, a+, w+ all create if file does not already exist */ 00130 if (openmode & (OPEN_A|OPEN_W)) { 00131 posix |= O_CREAT; 00132 } 00133 /* w and w+ truncate */ 00134 if (openmode & OPEN_W) { 00135 posix |= O_TRUNC; 00136 } 00137 #elif defined(__ICCARM__) 00138 switch (openmode & _LLIO_RDWRMASK) { 00139 case _LLIO_RDONLY: posix = O_RDONLY; break; 00140 case _LLIO_WRONLY: posix = O_WRONLY; break; 00141 case _LLIO_RDWR : posix = O_RDWR ; break; 00142 } 00143 if (openmode & _LLIO_CREAT ) posix |= O_CREAT; 00144 if (openmode & _LLIO_APPEND) posix |= O_APPEND; 00145 if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC; 00146 #elif defined(TOOLCHAIN_GCC) 00147 posix &= ~O_BINARY; 00148 #endif 00149 return posix; 00150 } 00151 00152 extern "C" WEAK void mbed_sdk_init(void); 00153 extern "C" WEAK void mbed_sdk_init(void) { 00154 } 00155 00156 extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { 00157 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) 00158 // Before version 5.03, we were using a patched version of microlib with proper names 00159 // This is the workaround that the microlib author suggested us 00160 static int n = 0; 00161 static int mbed_sdk_inited = 0; 00162 if (!mbed_sdk_inited) { 00163 mbed_sdk_inited = 1; 00164 mbed_sdk_init(); 00165 } 00166 if (!std::strcmp(name, ":tt")) return n++; 00167 #else 00168 /* Use the posix convention that stdin,out,err are filehandles 0,1,2. 00169 */ 00170 if (std::strcmp(name, __stdin_name) == 0) { 00171 init_serial(); 00172 return 0; 00173 } else if (std::strcmp(name, __stdout_name) == 0) { 00174 init_serial(); 00175 return 1; 00176 } else if (std::strcmp(name, __stderr_name) == 0) { 00177 init_serial(); 00178 return 2; 00179 } 00180 #endif 00181 00182 // find the first empty slot in filehandles 00183 filehandle_mutex->lock(); 00184 unsigned int fh_i; 00185 for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { 00186 if (filehandles[fh_i] == NULL) break; 00187 } 00188 if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { 00189 filehandle_mutex->unlock(); 00190 return -1; 00191 } 00192 filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED; 00193 filehandle_mutex->unlock(); 00194 00195 FileHandle *res; 00196 00197 /* FILENAME: ":0x12345678" describes a FileLike* */ 00198 if (name[0] == ':') { 00199 void *p; 00200 sscanf(name, ":%p", &p); 00201 res = (FileHandle*)p; 00202 00203 /* FILENAME: "/file_system/file_name" */ 00204 } else { 00205 FilePath path(name); 00206 00207 if (!path.exists()) { 00208 // Free file handle 00209 filehandles[fh_i] = NULL; 00210 return -1; 00211 } else if (path.isFile()) { 00212 res = path.file(); 00213 } else { 00214 FileSystemLike *fs = path.fileSystem(); 00215 if (fs == NULL) { 00216 // Free file handle 00217 filehandles[fh_i] = NULL; 00218 return -1; 00219 } 00220 int posix_mode = openmode_to_posix(openmode); 00221 res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ 00222 } 00223 } 00224 00225 if (res == NULL) { 00226 // Free file handle 00227 filehandles[fh_i] = NULL; 00228 return -1; 00229 } 00230 filehandles[fh_i] = res; 00231 00232 return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err 00233 } 00234 00235 extern "C" int PREFIX(_close)(FILEHANDLE fh) { 00236 if (fh < 3) return 0; 00237 00238 FileHandle* fhc = filehandles[fh-3]; 00239 filehandles[fh-3] = NULL; 00240 if (fhc == NULL) return -1; 00241 00242 return fhc->close(); 00243 } 00244 00245 #if defined(__ICCARM__) 00246 extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { 00247 #else 00248 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { 00249 #endif 00250 int n; // n is the number of bytes written 00251 if (fh < 3) { 00252 #if DEVICE_SERIAL 00253 if (!stdio_uart_inited) init_serial(); 00254 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES 00255 for (unsigned int i = 0; i < length; i++) { 00256 if (buffer[i] == '\n' && stdio_out_prev != '\r') { 00257 serial_putc(&stdio_uart, '\r'); 00258 } 00259 serial_putc(&stdio_uart, buffer[i]); 00260 stdio_out_prev = buffer[i]; 00261 } 00262 #else 00263 for (unsigned int i = 0; i < length; i++) { 00264 serial_putc(&stdio_uart, buffer[i]); 00265 } 00266 #endif 00267 #endif 00268 n = length; 00269 } else { 00270 FileHandle* fhc = filehandles[fh-3]; 00271 if (fhc == NULL) return -1; 00272 00273 n = fhc->write(buffer, length); 00274 } 00275 #ifdef __ARMCC_VERSION 00276 return length-n; 00277 #else 00278 return n; 00279 #endif 00280 } 00281 00282 #if defined(__ICCARM__) 00283 extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { 00284 #else 00285 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { 00286 #endif 00287 int n; // n is the number of bytes read 00288 if (fh < 3) { 00289 // only read a character at a time from stdin 00290 #if DEVICE_SERIAL 00291 if (!stdio_uart_inited) init_serial(); 00292 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES 00293 while (true) { 00294 char c = serial_getc(&stdio_uart); 00295 if ((c == '\r' && stdio_in_prev != '\n') || 00296 (c == '\n' && stdio_in_prev != '\r')) { 00297 stdio_in_prev = c; 00298 *buffer = '\n'; 00299 break; 00300 } else if ((c == '\r' && stdio_in_prev == '\n') || 00301 (c == '\n' && stdio_in_prev == '\r')) { 00302 stdio_in_prev = c; 00303 // onto next character 00304 continue; 00305 } else { 00306 stdio_in_prev = c; 00307 *buffer = c; 00308 break; 00309 } 00310 } 00311 #else 00312 *buffer = serial_getc(&stdio_uart); 00313 #endif 00314 #endif 00315 n = 1; 00316 } else { 00317 FileHandle* fhc = filehandles[fh-3]; 00318 if (fhc == NULL) return -1; 00319 00320 n = fhc->read(buffer, length); 00321 } 00322 #ifdef __ARMCC_VERSION 00323 return length-n; 00324 #else 00325 return n; 00326 #endif 00327 } 00328 00329 #ifdef __ARMCC_VERSION 00330 extern "C" int PREFIX(_istty)(FILEHANDLE fh) 00331 #else 00332 extern "C" int _isatty(FILEHANDLE fh) 00333 #endif 00334 { 00335 /* stdin, stdout and stderr should be tty */ 00336 if (fh < 3) return 1; 00337 00338 FileHandle* fhc = filehandles[fh-3]; 00339 if (fhc == NULL) return -1; 00340 00341 return fhc->isatty(); 00342 } 00343 00344 extern "C" 00345 #if defined(__ARMCC_VERSION) 00346 int _sys_seek(FILEHANDLE fh, long position) 00347 #elif defined(__ICCARM__) 00348 long __lseek(int fh, long offset, int whence) 00349 #else 00350 int _lseek(FILEHANDLE fh, int offset, int whence) 00351 #endif 00352 { 00353 if (fh < 3) return 0; 00354 00355 FileHandle* fhc = filehandles[fh-3]; 00356 if (fhc == NULL) return -1; 00357 00358 #if defined(__ARMCC_VERSION) 00359 return fhc->lseek(position, SEEK_SET); 00360 #else 00361 return fhc->lseek(offset, whence); 00362 #endif 00363 } 00364 00365 #ifdef __ARMCC_VERSION 00366 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { 00367 if (fh < 3) return 0; 00368 00369 FileHandle* fhc = filehandles[fh-3]; 00370 if (fhc == NULL) return -1; 00371 00372 return fhc->fsync(); 00373 } 00374 00375 extern "C" long PREFIX(_flen)(FILEHANDLE fh) { 00376 if (fh < 3) return 0; 00377 00378 FileHandle* fhc = filehandles[fh-3]; 00379 if (fhc == NULL) return -1; 00380 00381 return fhc->flen(); 00382 } 00383 #endif 00384 00385 00386 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) 00387 extern "C" int _fstat(int fd, struct stat *st) { 00388 if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) { 00389 st->st_mode = S_IFCHR; 00390 return 0; 00391 } 00392 00393 errno = EBADF; 00394 return -1; 00395 } 00396 #endif 00397 00398 namespace std { 00399 extern "C" int remove(const char *path) { 00400 FilePath fp(path); 00401 FileSystemLike *fs = fp.fileSystem(); 00402 if (fs == NULL) return -1; 00403 00404 return fs->remove(fp.fileName()); 00405 } 00406 00407 extern "C" int rename(const char *oldname, const char *newname) { 00408 FilePath fpOld(oldname); 00409 FilePath fpNew(newname); 00410 FileSystemLike *fsOld = fpOld.fileSystem(); 00411 FileSystemLike *fsNew = fpNew.fileSystem(); 00412 00413 /* rename only if both files are on the same FS */ 00414 if (fsOld != fsNew || fsOld == NULL) return -1; 00415 00416 return fsOld->rename(fpOld.fileName(), fpNew.fileName()); 00417 } 00418 00419 extern "C" char *tmpnam(char *s) { 00420 return NULL; 00421 } 00422 00423 extern "C" FILE *tmpfile() { 00424 return NULL; 00425 } 00426 } // namespace std 00427 00428 #ifdef __ARMCC_VERSION 00429 extern "C" char *_sys_command_string(char *cmd, int len) { 00430 return NULL; 00431 } 00432 #endif 00433 00434 extern "C" DIR *opendir(const char *path) { 00435 /* root dir is FileSystemLike */ 00436 if (path[0] == '/' && path[1] == 0) { 00437 return FileSystemLike::opendir(); 00438 } 00439 00440 FilePath fp(path); 00441 FileSystemLike* fs = fp.fileSystem(); 00442 if (fs == NULL) return NULL; 00443 00444 return fs->opendir(fp.fileName()); 00445 } 00446 00447 extern "C" struct dirent *readdir(DIR *dir) { 00448 return dir->readdir(); 00449 } 00450 00451 extern "C" int closedir(DIR *dir) { 00452 return dir->closedir(); 00453 } 00454 00455 extern "C" void rewinddir(DIR *dir) { 00456 dir->rewinddir(); 00457 } 00458 00459 extern "C" off_t telldir(DIR *dir) { 00460 return dir->telldir(); 00461 } 00462 00463 extern "C" void seekdir(DIR *dir, off_t off) { 00464 dir->seekdir(off); 00465 } 00466 00467 extern "C" int mkdir(const char *path, mode_t mode) { 00468 FilePath fp(path); 00469 FileSystemLike *fs = fp.fileSystem(); 00470 if (fs == NULL) return -1; 00471 00472 return fs->mkdir(fp.fileName(), mode); 00473 } 00474 00475 #if defined(TOOLCHAIN_GCC) 00476 /* prevents the exception handling name demangling code getting pulled in */ 00477 #include "mbed_error.h" 00478 namespace __gnu_cxx { 00479 void __verbose_terminate_handler() { 00480 error("Exception"); 00481 } 00482 } 00483 extern "C" WEAK void __cxa_pure_virtual(void); 00484 extern "C" WEAK void __cxa_pure_virtual(void) { 00485 exit(1); 00486 } 00487 00488 #endif 00489 00490 #if defined(TOOLCHAIN_GCC) 00491 00492 #ifdef FEATURE_UVISOR 00493 #include "uvisor-lib/uvisor-lib.h" 00494 #endif/* FEATURE_UVISOR */ 00495 00496 00497 extern "C" WEAK void software_init_hook_rtos(void) 00498 { 00499 // Do nothing by default. 00500 } 00501 00502 extern "C" void software_init_hook(void) 00503 { 00504 #ifdef FEATURE_UVISOR 00505 int return_code; 00506 00507 return_code = uvisor_lib_init(); 00508 if (return_code) { 00509 mbed_die(); 00510 } 00511 #endif/* FEATURE_UVISOR */ 00512 mbed_sdk_init(); 00513 software_init_hook_rtos(); 00514 } 00515 #endif 00516 00517 // **************************************************************************** 00518 // mbed_main is a function that is called before main() 00519 // mbed_sdk_init() is also a function that is called before main(), but unlike 00520 // mbed_main(), it is not meant for user code, but for the SDK itself to perform 00521 // initializations before main() is called. 00522 00523 extern "C" WEAK void mbed_main(void); 00524 extern "C" WEAK void mbed_main(void) { 00525 } 00526 00527 #if defined(TOOLCHAIN_ARM) 00528 extern "C" int $Super$$main(void); 00529 00530 extern "C" int $Sub$$main(void) { 00531 mbed_main(); 00532 return $Super$$main(); 00533 } 00534 00535 extern "C" void _platform_post_stackheap_init (void) { 00536 mbed_sdk_init(); 00537 } 00538 00539 #elif defined(TOOLCHAIN_GCC) 00540 extern "C" int __real_main(void); 00541 00542 extern "C" int __wrap_main(void) { 00543 mbed_main(); 00544 return __real_main(); 00545 } 00546 #elif defined(TOOLCHAIN_IAR) 00547 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent 00548 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting 00549 // 'main' to another symbol looses the original 'main' symbol. However, its startup 00550 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined. 00551 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main. 00552 extern "C" void __iar_argc_argv() { 00553 mbed_main(); 00554 } 00555 #endif 00556 00557 // Provide implementation of _sbrk (low-level dynamic memory allocation 00558 // routine) for GCC_ARM which compares new heap pointer with MSP instead of 00559 // SP. This make it compatible with RTX RTOS thread stacks. 00560 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) 00561 // Linker defined symbol used by _sbrk to indicate where heap should start. 00562 extern "C" int __end__; 00563 00564 #if defined(TARGET_CORTEX_A) 00565 extern "C" uint32_t __HeapLimit; 00566 #endif 00567 00568 // Turn off the errno macro and use actual global variable instead. 00569 #undef errno 00570 extern "C" int errno; 00571 00572 // For ARM7 only 00573 register unsigned char * stack_ptr __asm ("sp"); 00574 00575 // Dynamic memory allocation related syscall. 00576 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M453) 00577 // Overwrite _sbrk() to support two region model (heap and stack are two distinct regions). 00578 // __wrap__sbrk() is implemented in: 00579 // TARGET_NUMAKER_PFM_NUC472 hal/targets/cmsis/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/retarget.c 00580 // TARGET_NUMAKER_PFM_M453 hal/targets/cmsis/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/retarget.c 00581 extern "C" void *__wrap__sbrk(int incr); 00582 extern "C" caddr_t _sbrk(int incr) { 00583 return (caddr_t) __wrap__sbrk(incr); 00584 } 00585 #else 00586 extern "C" caddr_t _sbrk(int incr) { 00587 static unsigned char* heap = (unsigned char*)&__end__; 00588 unsigned char* prev_heap = heap; 00589 unsigned char* new_heap = heap + incr; 00590 00591 #if defined(TARGET_ARM7) 00592 if (new_heap >= stack_ptr) { 00593 #elif defined(TARGET_CORTEX_A) 00594 if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ 00595 #else 00596 if (new_heap >= (unsigned char*)__get_MSP()) { 00597 #endif 00598 errno = ENOMEM; 00599 return (caddr_t)-1; 00600 } 00601 00602 // Additional heap checking if set 00603 if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) { 00604 errno = ENOMEM; 00605 return (caddr_t)-1; 00606 } 00607 00608 heap = new_heap; 00609 return (caddr_t) prev_heap; 00610 } 00611 #endif 00612 #endif 00613 00614 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) 00615 extern "C" void _exit(int return_code) { 00616 #else 00617 namespace std { 00618 extern "C" void exit(int return_code) { 00619 #endif 00620 00621 #if DEVICE_STDIO_MESSAGES 00622 #if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT 00623 fflush(stdout); 00624 fflush(stderr); 00625 #endif 00626 #endif 00627 00628 #if DEVICE_SEMIHOST 00629 if (mbed_interface_connected()) { 00630 semihost_exit(); 00631 } 00632 #endif 00633 if (return_code) { 00634 mbed_die(); 00635 } 00636 00637 while (1); 00638 } 00639 00640 #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR) 00641 } //namespace std 00642 #endif 00643 00644 #if defined(TOOLCHAIN_ARM) || defined(TOOLCHAIN_GCC) 00645 00646 // This series of function disable the registration of global destructors 00647 // in a dynamic table which will be called when the application exit. 00648 // In mbed, program never exit properly, it dies. 00649 // More informations about this topic for ARMCC here: 00650 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/6449.html 00651 extern "C" { 00652 int __aeabi_atexit(void *object, void (*dtor)(void* /*this*/), void *handle) { 00653 return 1; 00654 } 00655 00656 int __cxa_atexit(void (*dtor)(void* /*this*/), void *object, void *handle) { 00657 return 1; 00658 } 00659 00660 void __cxa_finalize(void *handle) { 00661 } 00662 00663 } // end of extern "C" 00664 00665 #endif 00666 00667 00668 #if defined(TOOLCHAIN_GCC) 00669 00670 /* 00671 * Depending on how newlib is configured, it is often not enough to define 00672 * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the 00673 * behavior regarding the registration of handlers with atexit. 00674 * 00675 * To overcome this limitation, exit and atexit are overriden here. 00676 */ 00677 extern "C"{ 00678 00679 /** 00680 * @brief Retarget of exit for GCC. 00681 * @details Unlike the standard version, this function doesn't call any function 00682 * registered with atexit before calling _exit. 00683 */ 00684 void __wrap_exit(int return_code) { 00685 _exit(return_code); 00686 } 00687 00688 /** 00689 * @brief Retarget atexit from GCC. 00690 * @details This function will always fail and never register any handler to be 00691 * called at exit. 00692 */ 00693 int __wrap_atexit(void (*func)()) { 00694 return 1; 00695 } 00696 00697 } 00698 00699 #endif 00700 00701 00702 00703 namespace mbed { 00704 00705 void mbed_set_unbuffered_stream(FILE *_file) { 00706 #if defined (__ICCARM__) 00707 char buf[2]; 00708 std::setvbuf(_file,buf,_IONBF,NULL); 00709 #else 00710 setbuf(_file, NULL); 00711 #endif 00712 } 00713 00714 int mbed_getc(FILE *_file){ 00715 #if defined (__ICCARM__) 00716 /*This is only valid for unbuffered streams*/ 00717 int res = std::fgetc(_file); 00718 if (res>=0){ 00719 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ 00720 _file->_Rend = _file->_Wend; 00721 _file->_Next = _file->_Wend; 00722 } 00723 return res; 00724 #else 00725 return std::fgetc(_file); 00726 #endif 00727 } 00728 00729 char* mbed_gets(char*s, int size, FILE *_file){ 00730 #if defined (__ICCARM__) 00731 /*This is only valid for unbuffered streams*/ 00732 char *str = fgets(s,size,_file); 00733 if (str!=NULL){ 00734 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ 00735 _file->_Rend = _file->_Wend; 00736 _file->_Next = _file->_Wend; 00737 } 00738 return str; 00739 #else 00740 return std::fgets(s,size,_file); 00741 #endif 00742 } 00743 00744 } // namespace mbed 00745 00746 #if defined (__ICCARM__) 00747 // Stub out locks when an rtos is not present 00748 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {} 00749 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {} 00750 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {} 00751 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {} 00752 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {} 00753 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {} 00754 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {} 00755 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {} 00756 #elif defined(__CC_ARM) 00757 // Do nothing 00758 #elif defined (__GNUC__) 00759 struct _reent; 00760 // Stub out locks when an rtos is not present 00761 extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {} 00762 extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {} 00763 extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {} 00764 extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {} 00765 00766 extern "C" void __malloc_lock( struct _reent *_r ) 00767 { 00768 __rtos_malloc_lock(_r); 00769 } 00770 00771 extern "C" void __malloc_unlock( struct _reent *_r ) 00772 { 00773 __rtos_malloc_unlock(_r); 00774 } 00775 00776 extern "C" void __env_lock( struct _reent *_r ) 00777 { 00778 __rtos_env_lock(_r); 00779 } 00780 00781 extern "C" void __env_unlock( struct _reent *_r ) 00782 { 00783 __rtos_env_unlock(_r); 00784 } 00785 00786 #define CXA_GUARD_INIT_DONE (1 << 0) 00787 #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1) 00788 #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS) 00789 00790 extern "C" int __cxa_guard_acquire(int *guard_object_p) 00791 { 00792 uint8_t *guard_object = (uint8_t *)guard_object_p; 00793 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { 00794 return 0; 00795 } 00796 singleton_lock(); 00797 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { 00798 singleton_unlock(); 00799 return 0; 00800 } 00801 MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK)); 00802 *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS; 00803 return 1; 00804 } 00805 00806 extern "C" void __cxa_guard_release(int *guard_object_p) 00807 { 00808 uint8_t *guard_object = (uint8_t *)guard_object_p; 00809 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); 00810 *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE; 00811 singleton_unlock(); 00812 } 00813 00814 extern "C" void __cxa_guard_abort(int *guard_object_p) 00815 { 00816 uint8_t *guard_object = (uint8_t *)guard_object_p; 00817 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); 00818 *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS; 00819 singleton_unlock(); 00820 } 00821 00822 #endif 00823 00824 void *operator new(std::size_t count) 00825 { 00826 void *buffer = malloc(count); 00827 if (NULL == buffer) { 00828 error("Operator new out of memory\r\n"); 00829 } 00830 return buffer; 00831 } 00832 00833 void *operator new[](std::size_t count) 00834 { 00835 void *buffer = malloc(count); 00836 if (NULL == buffer) { 00837 error("Operator new[] out of memory\r\n"); 00838 } 00839 return buffer; 00840 } 00841 00842 void operator delete(void *ptr) 00843 { 00844 if (ptr != NULL) { 00845 free(ptr); 00846 } 00847 } 00848 void operator delete[](void *ptr) 00849 { 00850 if (ptr != NULL) { 00851 free(ptr); 00852 } 00853 }
Generated on Tue Jul 12 2022 17:38:48 by
