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