mbed library sources. Supersedes mbed-src.
Dependents: LPCXpresso1769_blinky
Fork of mbed-dev 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.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 16:04:26 by 1.7.2