This fork captures the mbed lib v125 for ease of integration into older projects.
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