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.
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.h" 00017 #include "FileHandle.h" 00018 #include "FileSystemLike.h" 00019 #include "FilePath.h" 00020 #include "serial_api.h" 00021 #include "toolchain.h" 00022 #include "semihost_api.h" 00023 #include "mbed_interface.h" 00024 #include "SingletonPtr.h" 00025 #include "PlatformMutex.h" 00026 #include "mbed_error.h" 00027 #include "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_CORE_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_CORE_STDIO_BAUD_RATE 00112 serial_baud(&stdio_uart, MBED_CONF_CORE_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" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { 00153 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) 00154 // Before version 5.03, we were using a patched version of microlib with proper names 00155 // This is the workaround that the microlib author suggested us 00156 static int n = 0; 00157 if (!std::strcmp(name, ":tt")) return n++; 00158 00159 #else 00160 /* Use the posix convention that stdin,out,err are filehandles 0,1,2. 00161 */ 00162 if (std::strcmp(name, __stdin_name) == 0) { 00163 init_serial(); 00164 return 0; 00165 } else if (std::strcmp(name, __stdout_name) == 0) { 00166 init_serial(); 00167 return 1; 00168 } else if (std::strcmp(name, __stderr_name) == 0) { 00169 init_serial(); 00170 return 2; 00171 } 00172 #endif 00173 00174 // find the first empty slot in filehandles 00175 filehandle_mutex->lock(); 00176 unsigned int fh_i; 00177 for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { 00178 if (filehandles[fh_i] == NULL) break; 00179 } 00180 if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { 00181 filehandle_mutex->unlock(); 00182 return -1; 00183 } 00184 filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED; 00185 filehandle_mutex->unlock(); 00186 00187 FileHandle *res; 00188 00189 /* FILENAME: ":0x12345678" describes a FileLike* */ 00190 if (name[0] == ':') { 00191 void *p; 00192 sscanf(name, ":%p", &p); 00193 res = (FileHandle*)p; 00194 00195 /* FILENAME: "/file_system/file_name" */ 00196 } else { 00197 FilePath path(name); 00198 00199 if (!path.exists()) { 00200 // Free file handle 00201 filehandles[fh_i] = NULL; 00202 return -1; 00203 } else if (path.isFile()) { 00204 res = path.file(); 00205 } else { 00206 FileSystemLike *fs = path.fileSystem(); 00207 if (fs == NULL) { 00208 // Free file handle 00209 filehandles[fh_i] = NULL; 00210 return -1; 00211 } 00212 int posix_mode = openmode_to_posix(openmode); 00213 res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ 00214 } 00215 } 00216 00217 if (res == NULL) { 00218 // Free file handle 00219 filehandles[fh_i] = NULL; 00220 return -1; 00221 } 00222 filehandles[fh_i] = res; 00223 00224 return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err 00225 } 00226 00227 extern "C" int PREFIX(_close)(FILEHANDLE fh) { 00228 if (fh < 3) return 0; 00229 00230 FileHandle* fhc = filehandles[fh-3]; 00231 filehandles[fh-3] = NULL; 00232 if (fhc == NULL) return -1; 00233 00234 return fhc->close(); 00235 } 00236 00237 #if defined(__ICCARM__) 00238 extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { 00239 #else 00240 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { 00241 #endif 00242 int n; // n is the number of bytes written 00243 if (fh < 3) { 00244 #if DEVICE_SERIAL 00245 if (!stdio_uart_inited) init_serial(); 00246 #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES 00247 for (unsigned int i = 0; i < length; i++) { 00248 if (buffer[i] == '\n' && stdio_out_prev != '\r') { 00249 serial_putc(&stdio_uart, '\r'); 00250 } 00251 serial_putc(&stdio_uart, buffer[i]); 00252 stdio_out_prev = buffer[i]; 00253 } 00254 #else 00255 for (unsigned int i = 0; i < length; i++) { 00256 serial_putc(&stdio_uart, buffer[i]); 00257 } 00258 #endif 00259 #endif 00260 n = length; 00261 } else { 00262 FileHandle* fhc = filehandles[fh-3]; 00263 if (fhc == NULL) return -1; 00264 00265 n = fhc->write(buffer, length); 00266 } 00267 #ifdef __ARMCC_VERSION 00268 return length-n; 00269 #else 00270 return n; 00271 #endif 00272 } 00273 00274 #if defined(__ICCARM__) 00275 extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { 00276 #else 00277 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { 00278 #endif 00279 int n; // n is the number of bytes read 00280 if (fh < 3) { 00281 // only read a character at a time from stdin 00282 #if DEVICE_SERIAL 00283 if (!stdio_uart_inited) init_serial(); 00284 #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES 00285 while (true) { 00286 char c = serial_getc(&stdio_uart); 00287 if ((c == '\r' && stdio_in_prev != '\n') || 00288 (c == '\n' && stdio_in_prev != '\r')) { 00289 stdio_in_prev = c; 00290 *buffer = '\n'; 00291 break; 00292 } else if ((c == '\r' && stdio_in_prev == '\n') || 00293 (c == '\n' && stdio_in_prev == '\r')) { 00294 stdio_in_prev = c; 00295 // onto next character 00296 continue; 00297 } else { 00298 stdio_in_prev = c; 00299 *buffer = c; 00300 break; 00301 } 00302 } 00303 #else 00304 *buffer = serial_getc(&stdio_uart); 00305 #endif 00306 #endif 00307 n = 1; 00308 } else { 00309 FileHandle* fhc = filehandles[fh-3]; 00310 if (fhc == NULL) return -1; 00311 00312 n = fhc->read(buffer, length); 00313 } 00314 #ifdef __ARMCC_VERSION 00315 return length-n; 00316 #else 00317 return n; 00318 #endif 00319 } 00320 00321 #ifdef __ARMCC_VERSION 00322 extern "C" int PREFIX(_istty)(FILEHANDLE fh) 00323 #else 00324 extern "C" int _isatty(FILEHANDLE fh) 00325 #endif 00326 { 00327 /* stdin, stdout and stderr should be tty */ 00328 if (fh < 3) return 1; 00329 00330 FileHandle* fhc = filehandles[fh-3]; 00331 if (fhc == NULL) return -1; 00332 00333 return fhc->isatty(); 00334 } 00335 00336 extern "C" 00337 #if defined(__ARMCC_VERSION) 00338 int _sys_seek(FILEHANDLE fh, long position) 00339 #elif defined(__ICCARM__) 00340 long __lseek(int fh, long offset, int whence) 00341 #else 00342 int _lseek(FILEHANDLE fh, int offset, int whence) 00343 #endif 00344 { 00345 if (fh < 3) return 0; 00346 00347 FileHandle* fhc = filehandles[fh-3]; 00348 if (fhc == NULL) return -1; 00349 00350 #if defined(__ARMCC_VERSION) 00351 return fhc->lseek(position, SEEK_SET); 00352 #else 00353 return fhc->lseek(offset, whence); 00354 #endif 00355 } 00356 00357 #ifdef __ARMCC_VERSION 00358 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { 00359 if (fh < 3) return 0; 00360 00361 FileHandle* fhc = filehandles[fh-3]; 00362 if (fhc == NULL) return -1; 00363 00364 return fhc->fsync(); 00365 } 00366 00367 extern "C" long PREFIX(_flen)(FILEHANDLE fh) { 00368 if (fh < 3) return 0; 00369 00370 FileHandle* fhc = filehandles[fh-3]; 00371 if (fhc == NULL) return -1; 00372 00373 return fhc->flen(); 00374 } 00375 #endif 00376 00377 00378 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) 00379 extern "C" int _fstat(int fd, struct stat *st) { 00380 if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) { 00381 st->st_mode = S_IFCHR; 00382 return 0; 00383 } 00384 00385 errno = EBADF; 00386 return -1; 00387 } 00388 #endif 00389 00390 namespace std { 00391 extern "C" int remove(const char *path) { 00392 FilePath fp(path); 00393 FileSystemLike *fs = fp.fileSystem(); 00394 if (fs == NULL) return -1; 00395 00396 return fs->remove(fp.fileName()); 00397 } 00398 00399 extern "C" int rename(const char *oldname, const char *newname) { 00400 FilePath fpOld(oldname); 00401 FilePath fpNew(newname); 00402 FileSystemLike *fsOld = fpOld.fileSystem(); 00403 FileSystemLike *fsNew = fpNew.fileSystem(); 00404 00405 /* rename only if both files are on the same FS */ 00406 if (fsOld != fsNew || fsOld == NULL) return -1; 00407 00408 return fsOld->rename(fpOld.fileName(), fpNew.fileName()); 00409 } 00410 00411 extern "C" char *tmpnam(char *s) { 00412 return NULL; 00413 } 00414 00415 extern "C" FILE *tmpfile() { 00416 return NULL; 00417 } 00418 } // namespace std 00419 00420 #ifdef __ARMCC_VERSION 00421 extern "C" char *_sys_command_string(char *cmd, int len) { 00422 return NULL; 00423 } 00424 #endif 00425 00426 extern "C" DIR *opendir(const char *path) { 00427 /* root dir is FileSystemLike */ 00428 if (path[0] == '/' && path[1] == 0) { 00429 return FileSystemLike::opendir(); 00430 } 00431 00432 FilePath fp(path); 00433 FileSystemLike* fs = fp.fileSystem(); 00434 if (fs == NULL) return NULL; 00435 00436 return fs->opendir(fp.fileName()); 00437 } 00438 00439 extern "C" struct dirent *readdir(DIR *dir) { 00440 return dir->readdir(); 00441 } 00442 00443 extern "C" int closedir(DIR *dir) { 00444 return dir->closedir(); 00445 } 00446 00447 extern "C" void rewinddir(DIR *dir) { 00448 dir->rewinddir(); 00449 } 00450 00451 extern "C" off_t telldir(DIR *dir) { 00452 return dir->telldir(); 00453 } 00454 00455 extern "C" void seekdir(DIR *dir, off_t off) { 00456 dir->seekdir(off); 00457 } 00458 00459 extern "C" int mkdir(const char *path, mode_t mode) { 00460 FilePath fp(path); 00461 FileSystemLike *fs = fp.fileSystem(); 00462 if (fs == NULL) return -1; 00463 00464 return fs->mkdir(fp.fileName(), mode); 00465 } 00466 00467 #if defined(TOOLCHAIN_GCC) 00468 /* prevents the exception handling name demangling code getting pulled in */ 00469 #include "mbed_error.h" 00470 namespace __gnu_cxx { 00471 void __verbose_terminate_handler() { 00472 error("Exception"); 00473 } 00474 } 00475 extern "C" WEAK void __cxa_pure_virtual(void); 00476 extern "C" WEAK void __cxa_pure_virtual(void) { 00477 exit(1); 00478 } 00479 00480 #endif 00481 00482 #if defined(TOOLCHAIN_GCC) 00483 00484 #ifdef FEATURE_UVISOR 00485 #include "uvisor-lib/uvisor-lib.h" 00486 #endif/* FEATURE_UVISOR */ 00487 00488 00489 extern "C" WEAK void software_init_hook_rtos(void) 00490 { 00491 // Do nothing by default. 00492 } 00493 00494 extern "C" void software_init_hook(void) 00495 { 00496 #ifdef FEATURE_UVISOR 00497 int return_code; 00498 00499 return_code = uvisor_lib_init(); 00500 if (return_code) { 00501 mbed_die(); 00502 } 00503 #endif/* FEATURE_UVISOR */ 00504 00505 software_init_hook_rtos(); 00506 } 00507 #endif 00508 00509 // **************************************************************************** 00510 // mbed_main is a function that is called before main() 00511 // mbed_sdk_init() is also a function that is called before main(), but unlike 00512 // mbed_main(), it is not meant for user code, but for the SDK itself to perform 00513 // initializations before main() is called. 00514 00515 extern "C" WEAK void mbed_main(void); 00516 extern "C" WEAK void mbed_main(void) { 00517 } 00518 00519 extern "C" WEAK void mbed_sdk_init(void); 00520 extern "C" WEAK void mbed_sdk_init(void) { 00521 } 00522 00523 #if defined(TOOLCHAIN_ARM) 00524 extern "C" int $Super$$main(void); 00525 00526 extern "C" int $Sub$$main(void) { 00527 mbed_sdk_init(); 00528 mbed_main(); 00529 return $Super$$main(); 00530 } 00531 #elif defined(TOOLCHAIN_GCC) 00532 extern "C" int __real_main(void); 00533 00534 extern "C" int __wrap_main(void) { 00535 mbed_sdk_init(); 00536 mbed_main(); 00537 return __real_main(); 00538 } 00539 #elif defined(TOOLCHAIN_IAR) 00540 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent 00541 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting 00542 // 'main' to another symbol looses the original 'main' symbol. However, its startup 00543 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined. 00544 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main. 00545 extern "C" void __iar_argc_argv() { 00546 mbed_main(); 00547 } 00548 #endif 00549 00550 // Provide implementation of _sbrk (low-level dynamic memory allocation 00551 // routine) for GCC_ARM which compares new heap pointer with MSP instead of 00552 // SP. This make it compatible with RTX RTOS thread stacks. 00553 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) 00554 // Linker defined symbol used by _sbrk to indicate where heap should start. 00555 extern "C" int __end__; 00556 00557 #if defined(TARGET_CORTEX_A) 00558 extern "C" uint32_t __HeapLimit; 00559 #endif 00560 00561 // Turn off the errno macro and use actual global variable instead. 00562 #undef errno 00563 extern "C" int errno; 00564 00565 // For ARM7 only 00566 register unsigned char * stack_ptr __asm ("sp"); 00567 00568 // Dynamic memory allocation related syscall. 00569 #if defined(TARGET_NUMAKER_PFM_NUC472) 00570 // Overwrite _sbrk() to support two region model. 00571 extern "C" void *__wrap__sbrk(int incr); 00572 extern "C" caddr_t _sbrk(int incr) { 00573 return (caddr_t) __wrap__sbrk(incr); 00574 } 00575 #else 00576 extern "C" caddr_t _sbrk(int incr) { 00577 static unsigned char* heap = (unsigned char*)&__end__; 00578 unsigned char* prev_heap = heap; 00579 unsigned char* new_heap = heap + incr; 00580 00581 #if defined(TARGET_ARM7) 00582 if (new_heap >= stack_ptr) { 00583 #elif defined(TARGET_CORTEX_A) 00584 if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ 00585 #else 00586 if (new_heap >= (unsigned char*)__get_MSP()) { 00587 #endif 00588 errno = ENOMEM; 00589 return (caddr_t)-1; 00590 } 00591 00592 // Additional heap checking if set 00593 if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) { 00594 errno = ENOMEM; 00595 return (caddr_t)-1; 00596 } 00597 00598 heap = new_heap; 00599 return (caddr_t) prev_heap; 00600 } 00601 #endif 00602 #endif 00603 00604 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) 00605 extern "C" void _exit(int return_code) { 00606 #else 00607 namespace std { 00608 extern "C" void exit(int return_code) { 00609 #endif 00610 00611 #if DEVICE_STDIO_MESSAGES 00612 fflush(stdout); 00613 fflush(stderr); 00614 #endif 00615 00616 #if DEVICE_SEMIHOST 00617 if (mbed_interface_connected()) { 00618 semihost_exit(); 00619 } 00620 #endif 00621 if (return_code) { 00622 mbed_die(); 00623 } 00624 00625 while (1); 00626 } 00627 00628 #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR) 00629 } //namespace std 00630 #endif 00631 00632 00633 namespace mbed { 00634 00635 void mbed_set_unbuffered_stream(FILE *_file) { 00636 #if defined (__ICCARM__) 00637 char buf[2]; 00638 std::setvbuf(_file,buf,_IONBF,NULL); 00639 #else 00640 setbuf(_file, NULL); 00641 #endif 00642 } 00643 00644 int mbed_getc(FILE *_file){ 00645 #if defined (__ICCARM__) 00646 /*This is only valid for unbuffered streams*/ 00647 int res = std::fgetc(_file); 00648 if (res>=0){ 00649 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ 00650 _file->_Rend = _file->_Wend; 00651 _file->_Next = _file->_Wend; 00652 } 00653 return res; 00654 #else 00655 return std::fgetc(_file); 00656 #endif 00657 } 00658 00659 char* mbed_gets(char*s, int size, FILE *_file){ 00660 #if defined (__ICCARM__) 00661 /*This is only valid for unbuffered streams*/ 00662 char *str = fgets(s,size,_file); 00663 if (str!=NULL){ 00664 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ 00665 _file->_Rend = _file->_Wend; 00666 _file->_Next = _file->_Wend; 00667 } 00668 return str; 00669 #else 00670 return std::fgets(s,size,_file); 00671 #endif 00672 } 00673 00674 } // namespace mbed 00675 00676 #if defined (__ICCARM__) 00677 // Stub out locks when an rtos is not present 00678 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {} 00679 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {} 00680 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {} 00681 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {} 00682 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {} 00683 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {} 00684 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {} 00685 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {} 00686 #elif defined(__CC_ARM) 00687 // Do nothing 00688 #elif defined (__GNUC__) 00689 struct _reent; 00690 // Stub out locks when an rtos is not present 00691 extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {} 00692 extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {} 00693 extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {} 00694 extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {} 00695 00696 extern "C" void __malloc_lock( struct _reent *_r ) 00697 { 00698 __rtos_malloc_lock(_r); 00699 } 00700 00701 extern "C" void __malloc_unlock( struct _reent *_r ) 00702 { 00703 __rtos_malloc_unlock(_r); 00704 } 00705 00706 extern "C" void __env_lock( struct _reent *_r ) 00707 { 00708 __rtos_env_lock(_r); 00709 } 00710 00711 extern "C" void __env_unlock( struct _reent *_r ) 00712 { 00713 __rtos_env_unlock(_r); 00714 } 00715 00716 #define CXA_GUARD_INIT_DONE (1 << 0) 00717 #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1) 00718 #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS) 00719 00720 extern "C" int __cxa_guard_acquire(int *guard_object_p) 00721 { 00722 uint8_t *guard_object = (uint8_t *)guard_object_p; 00723 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { 00724 return 0; 00725 } 00726 singleton_lock(); 00727 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { 00728 singleton_unlock(); 00729 return 0; 00730 } 00731 MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK)); 00732 *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS; 00733 return 1; 00734 } 00735 00736 extern "C" void __cxa_guard_release(int *guard_object_p) 00737 { 00738 uint8_t *guard_object = (uint8_t *)guard_object_p; 00739 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); 00740 *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE; 00741 singleton_unlock(); 00742 } 00743 00744 extern "C" void __cxa_guard_abort(int *guard_object_p) 00745 { 00746 uint8_t *guard_object = (uint8_t *)guard_object_p; 00747 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); 00748 *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS; 00749 singleton_unlock(); 00750 } 00751 00752 #endif 00753 00754 void *operator new(std::size_t count) 00755 { 00756 void *buffer = malloc(count); 00757 if (NULL == buffer) { 00758 error("Operator new out of memory\r\n"); 00759 } 00760 return buffer; 00761 } 00762 00763 void *operator new[](std::size_t count) 00764 { 00765 void *buffer = malloc(count); 00766 if (NULL == buffer) { 00767 error("Operator new[] out of memory\r\n"); 00768 } 00769 return buffer; 00770 } 00771 00772 void operator delete(void *ptr) 00773 { 00774 if (ptr != NULL) { 00775 free(ptr); 00776 } 00777 } 00778 void operator delete[](void *ptr) 00779 { 00780 if (ptr != NULL) { 00781 free(ptr); 00782 } 00783 }
Generated on Tue Jul 12 2022 22:19:21 by
