Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_retarget.cpp Source File

mbed_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/FilePath.h"
00018 #include "hal/serial_api.h"
00019 #include "platform/mbed_toolchain.h"
00020 #include "platform/mbed_semihost_api.h"
00021 #include "platform/mbed_interface.h"
00022 #include "platform/SingletonPtr.h"
00023 #include "platform/PlatformMutex.h"
00024 #include "platform/mbed_error.h"
00025 #include "platform/mbed_stats.h"
00026 #if MBED_CONF_FILESYSTEM_PRESENT
00027 #include "filesystem/FileSystem.h"
00028 #include "filesystem/File.h"
00029 #include "filesystem/Dir.h"
00030 #endif
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #if DEVICE_STDIO_MESSAGES
00034 #include <stdio.h>
00035 #endif
00036 #include <errno.h>
00037 #include "platform/mbed_retarget.h"
00038 
00039 
00040 #if defined(__ARMCC_VERSION)
00041 #   include <rt_sys.h>
00042 #   define PREFIX(x)    _sys##x
00043 #   define OPEN_MAX     _SYS_OPEN
00044 #   ifdef __MICROLIB
00045 #       pragma import(__use_full_stdio)
00046 #   endif
00047 
00048 #elif defined(__ICCARM__)
00049 #   include <yfuns.h>
00050 #   define PREFIX(x)        _##x
00051 #   define OPEN_MAX         16
00052 
00053 #   define STDIN_FILENO     0
00054 #   define STDOUT_FILENO    1
00055 #   define STDERR_FILENO    2
00056 
00057 #else
00058 #   include <sys/stat.h>
00059 #   include <sys/syslimits.h>
00060 #   define PREFIX(x)    x
00061 #endif
00062 
00063 #define FILE_HANDLE_RESERVED    0xFFFFFFFF
00064 
00065 using namespace mbed;
00066 
00067 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
00068 // Before version 5.03, we were using a patched version of microlib with proper names
00069 extern const char __stdin_name[]  = ":tt";
00070 extern const char __stdout_name[] = ":tt";
00071 extern const char __stderr_name[] = ":tt";
00072 
00073 #else
00074 extern const char __stdin_name[]  = "/stdin";
00075 extern const char __stdout_name[] = "/stdout";
00076 extern const char __stderr_name[] = "/stderr";
00077 #endif
00078 
00079 // Heap limits - only used if set
00080 unsigned char *mbed_heap_start = 0;
00081 uint32_t mbed_heap_size = 0;
00082 
00083 /* newlib has the filehandle field in the FILE struct as a short, so
00084  * we can't just return a Filehandle* from _open and instead have to
00085  * put it in a filehandles array and return the index into that array
00086  * (or rather index+3, as filehandles 0-2 are stdin/out/err).
00087  */
00088 static FileLike *filehandles[OPEN_MAX];
00089 static SingletonPtr<PlatformMutex>  filehandle_mutex;
00090 
00091 namespace mbed {
00092 void remove_filehandle(FileLike *file) {
00093     filehandle_mutex->lock();
00094     /* Remove all open filehandles for this */
00095     for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
00096         if (filehandles[fh_i] == file) {
00097             filehandles[fh_i] = NULL;
00098         }
00099     }
00100     filehandle_mutex->unlock();
00101 }
00102 }
00103 
00104 #if DEVICE_SERIAL
00105 extern int stdio_uart_inited;
00106 extern serial_t stdio_uart;
00107 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
00108 static char stdio_in_prev;
00109 static char stdio_out_prev;
00110 #endif
00111 #endif
00112 
00113 static void init_serial() {
00114 #if DEVICE_SERIAL
00115     if (stdio_uart_inited) return;
00116     serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
00117 #if MBED_CONF_PLATFORM_STDIO_BAUD_RATE
00118     serial_baud(&stdio_uart, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
00119 #endif
00120 #endif
00121 }
00122 
00123 #if MBED_CONF_FILESYSTEM_PRESENT
00124 static inline int openmode_to_posix(int openmode) {
00125     int posix = openmode;
00126 #ifdef __ARMCC_VERSION
00127     if (openmode & OPEN_PLUS) {
00128         posix = O_RDWR;
00129     } else if(openmode & OPEN_W) {
00130         posix = O_WRONLY;
00131     } else if(openmode & OPEN_A) {
00132         posix = O_WRONLY|O_APPEND;
00133     } else {
00134         posix = O_RDONLY;
00135     }
00136     /* a, w, a+, w+ all create if file does not already exist */
00137     if (openmode & (OPEN_A|OPEN_W)) {
00138         posix |= O_CREAT;
00139     }
00140     /* w and w+ truncate */
00141     if (openmode & OPEN_W) {
00142         posix |= O_TRUNC;
00143     }
00144 #elif defined(__ICCARM__)
00145     switch (openmode & _LLIO_RDWRMASK) {
00146         case _LLIO_RDONLY: posix = O_RDONLY; break;
00147         case _LLIO_WRONLY: posix = O_WRONLY; break;
00148         case _LLIO_RDWR  : posix = O_RDWR  ; break;
00149     }
00150     if (openmode & _LLIO_CREAT ) posix |= O_CREAT;
00151     if (openmode & _LLIO_APPEND) posix |= O_APPEND;
00152     if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC;
00153 #elif defined(TOOLCHAIN_GCC)
00154     posix &= ~O_BINARY;
00155 #endif
00156     return posix;
00157 }
00158 #endif
00159 
00160 extern "C" WEAK void mbed_sdk_init(void);
00161 extern "C" WEAK void mbed_sdk_init(void) {
00162 }
00163 
00164 #if MBED_CONF_FILESYSTEM_PRESENT
00165 // Internally used file objects with managed memory on close
00166 class ManagedFile : public File {
00167 public:
00168     virtual int close() {
00169         int err = File::close();
00170         delete this;
00171         return err;
00172     }
00173 };
00174 
00175 class ManagedDir : public Dir {
00176 public:
00177      virtual int close() {
00178         int err = Dir::close();
00179         delete this;
00180         return err;
00181     }
00182 };
00183 #endif
00184 
00185 /* @brief   standard c library fopen() retargeting function.
00186  *
00187  * This function is invoked by the standard c library retargeting to handle fopen()
00188  *
00189  * @return
00190  *  On success, a valid FILEHANDLE is returned.
00191  *  On failure, -1 is returned and errno is set to an appropriate value e.g.
00192  *   EBADF      a bad file descriptor was found (default errno setting)
00193  *   EMFILE     the maximum number of open files was exceeded.
00194  *
00195  * */
00196 extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
00197     #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
00198     // Before version 5.03, we were using a patched version of microlib with proper names
00199     // This is the workaround that the microlib author suggested us
00200     static int n = 0;
00201     static int mbed_sdk_inited = 0;
00202     if (!mbed_sdk_inited) {
00203         mbed_sdk_inited = 1;
00204         mbed_sdk_init();
00205     }
00206     if (!std::strcmp(name, ":tt")) return n++;
00207     #else
00208     /* Use the posix convention that stdin,out,err are filehandles 0,1,2.
00209      */
00210     if (std::strcmp(name, __stdin_name) == 0) {
00211         init_serial();
00212         return 0;
00213     } else if (std::strcmp(name, __stdout_name) == 0) {
00214         init_serial();
00215         return 1;
00216     } else if (std::strcmp(name, __stderr_name) == 0) {
00217         init_serial();
00218         return 2;
00219     }
00220     #endif
00221 
00222     /* if something goes wrong and errno is not explicly set, errno will be set to EBADF */
00223     errno = EBADF;
00224 
00225     // find the first empty slot in filehandles
00226     filehandle_mutex->lock();
00227     unsigned int fh_i;
00228     for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
00229         /* Take a next free filehandle slot available. */
00230         if (filehandles[fh_i] == NULL) break;
00231     }
00232     if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) {
00233         /* Too many file handles have been opened */
00234         errno = EMFILE;
00235         filehandle_mutex->unlock();
00236         return -1;
00237     }
00238     filehandles[fh_i] = (FileLike*)FILE_HANDLE_RESERVED;
00239     filehandle_mutex->unlock();
00240 
00241     FileLike *res = NULL;
00242 
00243     /* FILENAME: ":0x12345678" describes a FileLike* */
00244     if (name[0] == ':') {
00245         void *p;
00246         sscanf(name, ":%p", &p);
00247         res = (FileLike*)p;
00248 
00249     /* FILENAME: "/file_system/file_name" */
00250     } else {
00251         FilePath path(name);
00252 
00253         if (!path.exists()) {
00254             /* The first part of the filename (between first 2 '/') is not a
00255              * registered mount point in the namespace.
00256              * Free file handle.
00257              */
00258             filehandles[fh_i] = NULL;
00259             errno = ENOENT;
00260             return -1;
00261         } else if (path.isFile()) {
00262             res = path.file();
00263 #if MBED_CONF_FILESYSTEM_PRESENT
00264         } else {
00265             FileSystem *fs = path.fileSystem();
00266             if (fs == NULL) {
00267                 /* The filesystem instance managing the namespace under the mount point
00268                  * has not been found. Free file handle */
00269                 errno = ENOENT;
00270                 filehandles[fh_i] = NULL;
00271                 return -1;
00272             }
00273             int posix_mode = openmode_to_posix(openmode);
00274             File *file = new ManagedFile;
00275             int err = file->open(fs, path.fileName(), posix_mode);
00276             if (err < 0) {
00277                 errno = -err;
00278                 delete file;
00279             } else {
00280                 res = file;
00281             }
00282 #endif
00283         }
00284     }
00285 
00286     if (res == NULL) {
00287         // Free file handle
00288         filehandles[fh_i] = NULL;
00289         return -1;
00290     }
00291     filehandles[fh_i] = res;
00292 
00293     return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err
00294 }
00295 
00296 extern "C" int PREFIX(_close)(FILEHANDLE fh) {
00297     if (fh < 3) return 0;
00298 
00299     errno = EBADF;
00300     FileLike* fhc = filehandles[fh-3];
00301     filehandles[fh-3] = NULL;
00302     if (fhc == NULL) return -1;
00303 
00304     int err = fhc->close();
00305     if (err < 0) {
00306         errno = -err;
00307         return -1;
00308     } else {
00309         return 0;
00310     }
00311 }
00312 
00313 #if defined(__ICCARM__)
00314 extern "C" size_t    __write (int        fh, const unsigned char *buffer, size_t length) {
00315 #else
00316 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) {
00317 #endif
00318     int n; // n is the number of bytes written
00319 
00320     errno = EBADF;
00321     if (fh < 3) {
00322 #if DEVICE_SERIAL
00323         if (!stdio_uart_inited) init_serial();
00324 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
00325         for (unsigned int i = 0; i < length; i++) {
00326             if (buffer[i] == '\n' && stdio_out_prev != '\r') {
00327                  serial_putc(&stdio_uart, '\r');
00328             }
00329             serial_putc(&stdio_uart, buffer[i]);
00330             stdio_out_prev = buffer[i];
00331         }
00332 #else
00333         for (unsigned int i = 0; i < length; i++) {
00334             serial_putc(&stdio_uart, buffer[i]);
00335         }
00336 #endif
00337 #endif
00338         n = length;
00339     } else {
00340         FileLike* fhc = filehandles[fh-3];
00341         if (fhc == NULL) return -1;
00342 
00343         n = fhc->write(buffer, length);
00344         if (n < 0) {
00345             errno = -n;
00346         }
00347     }
00348 #ifdef __ARMCC_VERSION
00349     return length-n;
00350 #else
00351     return n;
00352 #endif
00353 }
00354 
00355 #if defined(__ICCARM__)
00356 extern "C" size_t    __read (int        fh, unsigned char *buffer, size_t       length) {
00357 #else
00358 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) {
00359 #endif
00360     int n; // n is the number of bytes read
00361 
00362     errno = EBADF;
00363     if (fh < 3) {
00364         // only read a character at a time from stdin
00365 #if DEVICE_SERIAL
00366         if (!stdio_uart_inited) init_serial();
00367 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
00368         while (true) {
00369             char c = serial_getc(&stdio_uart);
00370             if ((c == '\r' && stdio_in_prev != '\n') ||
00371                 (c == '\n' && stdio_in_prev != '\r')) {
00372                 stdio_in_prev = c;
00373                 *buffer = '\n';
00374                 break;
00375             } else if ((c == '\r' && stdio_in_prev == '\n') ||
00376                        (c == '\n' && stdio_in_prev == '\r')) {
00377                 stdio_in_prev = c;
00378                 // onto next character
00379                 continue;
00380             } else {
00381                 stdio_in_prev = c;
00382                 *buffer = c;
00383                 break;
00384             }
00385         }
00386 #else
00387         *buffer = serial_getc(&stdio_uart);
00388 #endif
00389 #endif
00390         n = 1;
00391     } else {
00392         FileLike* fhc = filehandles[fh-3];
00393         if (fhc == NULL) return -1;
00394 
00395         n = fhc->read(buffer, length);
00396         if (n < 0) {
00397             errno = -n;
00398         }
00399     }
00400 #ifdef __ARMCC_VERSION
00401     return length-n;
00402 #else
00403     return n;
00404 #endif
00405 }
00406 
00407 #ifdef __ARMCC_VERSION
00408 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
00409 #else
00410 extern "C" int _isatty(FILEHANDLE fh)
00411 #endif
00412 {
00413     errno = EBADF;
00414     /* stdin, stdout and stderr should be tty */
00415     if (fh < 3) return 1;
00416 
00417     FileLike* fhc = filehandles[fh-3];
00418     if (fhc == NULL) return -1;
00419 
00420     int err = fhc->isatty();
00421     if (err < 0) {
00422         errno = -err;
00423         return -1;
00424     } else {
00425         return 0;
00426     }
00427 }
00428 
00429 extern "C"
00430 #if defined(__ARMCC_VERSION)
00431 int _sys_seek(FILEHANDLE fh, long position)
00432 #elif defined(__ICCARM__)
00433 long __lseek(int fh, long offset, int whence)
00434 #else
00435 int _lseek(FILEHANDLE fh, int offset, int whence)
00436 #endif
00437 {
00438     errno = EBADF;
00439     if (fh < 3) return 0;
00440 
00441     FileLike* fhc = filehandles[fh-3];
00442     if (fhc == NULL) return -1;
00443 
00444 #if defined(__ARMCC_VERSION)
00445     return fhc->seek(position, SEEK_SET);
00446 #else
00447     return fhc->seek(offset, whence);
00448 #endif
00449 }
00450 
00451 #ifdef __ARMCC_VERSION
00452 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
00453     errno = EBADF;
00454     if (fh < 3) return 0;
00455 
00456     FileLike* fhc = filehandles[fh-3];
00457     if (fhc == NULL) return -1;
00458 
00459     int err = fhc->sync();
00460     if (err < 0) {
00461         errno = -err;
00462         return -1;
00463     } else {
00464         return 0;
00465     }
00466 }
00467 
00468 extern "C" long PREFIX(_flen)(FILEHANDLE fh) {
00469     errno = EBADF;
00470     if (fh < 3) return 0;
00471 
00472     FileLike* fhc = filehandles[fh-3];
00473     if (fhc == NULL) return -1;
00474 
00475     return fhc->size();
00476 }
00477 #endif
00478 
00479 
00480 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
00481 extern "C" int _fstat(int fd, struct stat *st) {
00482     if (fd < 3) {
00483         st->st_mode = S_IFCHR;
00484         return  0;
00485     }
00486     errno = EBADF;
00487     return -1;
00488 }
00489 #endif
00490 
00491 namespace std {
00492 extern "C" int remove(const char *path) {
00493 #if MBED_CONF_FILESYSTEM_PRESENT
00494     errno = EBADF;
00495     FilePath fp(path);
00496     FileSystem *fs = fp.fileSystem();
00497     if (fs == NULL) return -1;
00498 
00499     int err = fs->remove(fp.fileName());
00500     if (err < 0) {
00501         errno = -err;
00502         return -1;
00503     } else {
00504         return 0;
00505     }
00506 #else
00507     errno = ENOSYS;
00508     return -1;
00509 #endif
00510 }
00511 
00512 extern "C" int rename(const char *oldname, const char *newname) {
00513 #if MBED_CONF_FILESYSTEM_PRESENT
00514     errno = EBADF;
00515     FilePath fpOld(oldname);
00516     FilePath fpNew(newname);
00517     FileSystem *fsOld = fpOld.fileSystem();
00518     FileSystem *fsNew = fpNew.fileSystem();
00519 
00520     /* rename only if both files are on the same FS */
00521     if (fsOld != fsNew || fsOld == NULL) return -1;
00522 
00523     int err = fsOld->rename(fpOld.fileName(), fpNew.fileName());
00524     if (err < 0) {
00525         errno = -err;
00526         return -1;
00527     } else {
00528         return 0;
00529     }
00530 #else
00531     errno = ENOSYS;
00532     return -1;
00533 #endif
00534 }
00535 
00536 extern "C" char *tmpnam(char *s) {
00537     errno = EBADF;
00538     return NULL;
00539 }
00540 
00541 extern "C" FILE *tmpfile() {
00542     errno = EBADF;
00543     return NULL;
00544 }
00545 } // namespace std
00546 
00547 #ifdef __ARMCC_VERSION
00548 extern "C" char *_sys_command_string(char *cmd, int len) {
00549     return NULL;
00550 }
00551 #endif
00552 
00553 extern "C" DIR *opendir(const char *path) {
00554 #if MBED_CONF_FILESYSTEM_PRESENT
00555     errno = EBADF;
00556 
00557     FilePath fp(path);
00558     FileSystem* fs = fp.fileSystem();
00559     if (fs == NULL) return NULL;
00560 
00561     Dir *dir = new ManagedDir;
00562     int err = dir->open(fs, fp.fileName());
00563     if (err < 0) {
00564         errno = -err;
00565         delete dir;
00566         dir = NULL;
00567     }
00568 
00569     return dir;
00570 #else
00571     errno = ENOSYS;
00572     return 0;
00573 #endif
00574 }
00575 
00576 extern "C" struct dirent *readdir(DIR *dir) {
00577 #if MBED_CONF_FILESYSTEM_PRESENT
00578     static struct dirent ent;
00579     int err = dir->read(&ent);
00580     if (err < 1) {
00581         if (err < 0) {
00582             errno = -err;
00583         }
00584         return NULL;
00585     }
00586 
00587     return &ent;
00588 #else
00589     errno = ENOSYS;
00590     return 0;
00591 #endif
00592 }
00593 
00594 extern "C" int closedir(DIR *dir) {
00595 #if MBED_CONF_FILESYSTEM_PRESENT
00596     int err = dir->close();
00597     if (err < 0) {
00598         errno = -err;
00599         return -1;
00600     } else {
00601         return 0;
00602     }
00603 #else
00604     errno = ENOSYS;
00605     return -1;
00606 #endif
00607 }
00608 
00609 extern "C" void rewinddir(DIR *dir) {
00610 #if MBED_CONF_FILESYSTEM_PRESENT
00611     dir->rewind();
00612 #else
00613     errno = ENOSYS;
00614 #endif
00615 }
00616 
00617 extern "C" off_t telldir(DIR *dir) {
00618 #if MBED_CONF_FILESYSTEM_PRESENT
00619     return dir->tell();
00620 #else
00621     errno = ENOSYS;
00622     return 0;
00623 #endif
00624 }
00625 
00626 extern "C" void seekdir(DIR *dir, off_t off) {
00627 #if MBED_CONF_FILESYSTEM_PRESENT
00628     dir->seek(off);
00629 #else
00630     errno = ENOSYS;
00631 #endif
00632 }
00633 
00634 extern "C" int mkdir(const char *path, mode_t mode) {
00635 #if MBED_CONF_FILESYSTEM_PRESENT
00636     FilePath fp(path);
00637     FileSystem *fs = fp.fileSystem();
00638     if (fs == NULL) return -1;
00639 
00640     int err = fs->mkdir(fp.fileName(), mode);
00641     if (err < 0) {
00642         errno = -err;
00643         return -1;
00644     } else {
00645         return 0;
00646     }
00647 #else
00648     errno = ENOSYS;
00649     return -1;
00650 #endif
00651 }
00652 
00653 extern "C" int stat(const char *path, struct stat *st) {
00654 #if MBED_CONF_FILESYSTEM_PRESENT
00655     FilePath fp(path);
00656     FileSystem *fs = fp.fileSystem();
00657     if (fs == NULL) return -1;
00658 
00659     int err = fs->stat(fp.fileName(), st);
00660     if (err < 0) {
00661         errno = -err;
00662         return -1;
00663     } else {
00664         return 0;
00665     }
00666 #else
00667     errno = ENOSYS;
00668     return -1;
00669 #endif
00670 }
00671 
00672 #if defined(TOOLCHAIN_GCC)
00673 /* prevents the exception handling name demangling code getting pulled in */
00674 #include "mbed_error.h"
00675 namespace __gnu_cxx {
00676     void __verbose_terminate_handler() {
00677         error("Exception");
00678     }
00679 }
00680 extern "C" WEAK void __cxa_pure_virtual(void);
00681 extern "C" WEAK void __cxa_pure_virtual(void) {
00682     exit(1);
00683 }
00684 
00685 #endif
00686 
00687 #if defined(TOOLCHAIN_GCC)
00688 
00689 #ifdef  FEATURE_UVISOR
00690 #include "uvisor-lib/uvisor-lib.h"
00691 #endif/* FEATURE_UVISOR */
00692 
00693 
00694 extern "C" WEAK void software_init_hook_rtos(void)
00695 {
00696     // Do nothing by default.
00697 }
00698 
00699 extern "C" void software_init_hook(void)
00700 {
00701 #ifdef   FEATURE_UVISOR
00702     int return_code;
00703 
00704     return_code = uvisor_lib_init();
00705     if (return_code) {
00706         mbed_die();
00707     }
00708 #endif/* FEATURE_UVISOR */
00709     mbed_sdk_init();
00710     software_init_hook_rtos();
00711 }
00712 #endif
00713 
00714 // ****************************************************************************
00715 // mbed_main is a function that is called before main()
00716 // mbed_sdk_init() is also a function that is called before main(), but unlike
00717 // mbed_main(), it is not meant for user code, but for the SDK itself to perform
00718 // initializations before main() is called.
00719 
00720 extern "C" WEAK void mbed_main(void);
00721 extern "C" WEAK void mbed_main(void) {
00722 }
00723 
00724 #if defined(TOOLCHAIN_ARM)
00725 extern "C" int $Super$$main(void);
00726 
00727 extern "C" int $Sub$$main(void) {
00728     mbed_main();
00729     return $Super$$main();
00730 }
00731 
00732 extern "C" void _platform_post_stackheap_init (void) {
00733     mbed_sdk_init();
00734 }
00735 
00736 #elif defined(TOOLCHAIN_GCC)
00737 extern "C" int __real_main(void);
00738 
00739 extern "C" int __wrap_main(void) {
00740     mbed_main();
00741     return __real_main();
00742 }
00743 #elif defined(TOOLCHAIN_IAR)
00744 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
00745 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
00746 // 'main' to another symbol looses the original 'main' symbol. However, its startup
00747 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
00748 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
00749 extern "C" void __iar_argc_argv() {
00750     mbed_main();
00751 }
00752 #endif
00753 
00754 // Provide implementation of _sbrk (low-level dynamic memory allocation
00755 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
00756 // SP.  This make it compatible with RTX RTOS thread stacks.
00757 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
00758 // Linker defined symbol used by _sbrk to indicate where heap should start.
00759 extern "C" int __end__;
00760 
00761 #if defined(TARGET_CORTEX_A)
00762 extern "C" uint32_t  __HeapLimit;
00763 #endif
00764 
00765 // Turn off the errno macro and use actual global variable instead.
00766 #undef errno
00767 extern "C" int errno;
00768 
00769 // For ARM7 only
00770 register unsigned char * stack_ptr __asm ("sp");
00771 
00772 // Dynamic memory allocation related syscall.
00773 #if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M453)
00774 // Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
00775 // __wrap__sbrk() is implemented in:
00776 // TARGET_NUMAKER_PFM_NUC472    hal/targets/cmsis/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/retarget.c
00777 // TARGET_NUMAKER_PFM_M453      hal/targets/cmsis/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/retarget.c
00778 extern "C" void *__wrap__sbrk(int incr);
00779 extern "C" caddr_t _sbrk(int incr) {
00780     return (caddr_t) __wrap__sbrk(incr);
00781 }
00782 #else
00783 extern "C" caddr_t _sbrk(int incr) {
00784     static unsigned char* heap = (unsigned char*)&__end__;
00785     unsigned char*        prev_heap = heap;
00786     unsigned char*        new_heap = heap + incr;
00787 
00788 #if defined(TARGET_ARM7)
00789     if (new_heap >= stack_ptr) {
00790 #elif defined(TARGET_CORTEX_A)
00791     if (new_heap >= (unsigned char*)&__HeapLimit) {     /* __HeapLimit is end of heap section */
00792 #else
00793     if (new_heap >= (unsigned char*)__get_MSP()) {
00794 #endif
00795         errno = ENOMEM;
00796         return (caddr_t)-1;
00797     }
00798 
00799     // Additional heap checking if set
00800     if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) {
00801         errno = ENOMEM;
00802         return (caddr_t)-1;
00803     }
00804 
00805     heap = new_heap;
00806     return (caddr_t) prev_heap;
00807 }
00808 #endif
00809 #endif
00810 
00811 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
00812 extern "C" void _exit(int return_code) {
00813 #else
00814 namespace std {
00815 extern "C" void exit(int return_code) {
00816 #endif
00817 
00818 #if DEVICE_STDIO_MESSAGES
00819 #if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
00820     fflush(stdout);
00821     fflush(stderr);
00822 #endif
00823 #endif
00824 
00825 #if DEVICE_SEMIHOST
00826     if (mbed_interface_connected()) {
00827         semihost_exit();
00828     }
00829 #endif
00830     if (return_code) {
00831         mbed_die();
00832     }
00833 
00834     while (1);
00835 }
00836 
00837 #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR)
00838 } //namespace std
00839 #endif
00840 
00841 #if defined(TOOLCHAIN_ARM) || defined(TOOLCHAIN_GCC)
00842 
00843 // This series of function disable the registration of global destructors
00844 // in a dynamic table which will be called when the application exit.
00845 // In mbed, program never exit properly, it dies.
00846 // More informations about this topic for ARMCC here:
00847 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/6449.html
00848 extern "C" {
00849 int __aeabi_atexit(void *object, void (*dtor)(void* /*this*/), void *handle) {
00850     return 1;
00851 }
00852 
00853 int __cxa_atexit(void (*dtor)(void* /*this*/), void *object, void *handle) {
00854     return 1;
00855 }
00856 
00857 void __cxa_finalize(void *handle) {
00858 }
00859 
00860 } // end of extern "C"
00861 
00862 #endif
00863 
00864 
00865 #if defined(TOOLCHAIN_GCC)
00866 
00867 /*
00868  * Depending on how newlib is  configured, it is often not enough to define
00869  * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the
00870  * behavior regarding the registration of handlers with atexit.
00871  *
00872  * To overcome this limitation, exit and atexit are overriden here.
00873  */
00874 extern "C"{
00875 
00876 /**
00877  * @brief Retarget of exit for GCC.
00878  * @details Unlike the standard version, this function doesn't call any function
00879  * registered with atexit before calling _exit.
00880  */
00881 void __wrap_exit(int return_code) {
00882     _exit(return_code);
00883 }
00884 
00885 /**
00886  * @brief Retarget atexit from GCC.
00887  * @details This function will always fail and never register any handler to be
00888  * called at exit.
00889  */
00890 int __wrap_atexit(void (*func)()) {
00891     return 1;
00892 }
00893 
00894 }
00895 
00896 #endif
00897 
00898 
00899 
00900 namespace mbed {
00901 
00902 void mbed_set_unbuffered_stream(FILE *_file) {
00903 #if defined (__ICCARM__)
00904     char buf[2];
00905     std::setvbuf(_file,buf,_IONBF,NULL);    
00906 #else
00907     setbuf(_file, NULL);
00908 #endif
00909 }
00910 
00911 int mbed_getc(FILE *_file){
00912 #if defined (__ICCARM__)
00913     /*This is only valid for unbuffered streams*/
00914     int res = std::fgetc(_file);
00915     if (res>=0){
00916         _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
00917         _file->_Rend = _file->_Wend;
00918         _file->_Next = _file->_Wend;
00919     }    
00920     return res;
00921 #else    
00922     return std::fgetc(_file);
00923 #endif   
00924 }
00925 
00926 char* mbed_gets(char*s, int size, FILE *_file){
00927 #if defined (__ICCARM__)
00928     /*This is only valid for unbuffered streams*/
00929     char *str = fgets(s,size,_file);
00930     if (str!=NULL){
00931         _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
00932         _file->_Rend = _file->_Wend;
00933         _file->_Next = _file->_Wend;
00934     }
00935     return str;
00936 #else    
00937     return std::fgets(s,size,_file);
00938 #endif
00939 }
00940 
00941 } // namespace mbed
00942 
00943 #if defined (__ICCARM__)
00944 // Stub out locks when an rtos is not present
00945 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {}
00946 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {}
00947 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {}
00948 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {}
00949 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {}
00950 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {}
00951 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {}
00952 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {}
00953 #elif defined(__CC_ARM)
00954 // Do nothing
00955 #elif defined (__GNUC__)
00956 struct _reent;
00957 // Stub out locks when an rtos is not present
00958 extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {}
00959 extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {}
00960 extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {}
00961 extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {}
00962 
00963 extern "C" void __malloc_lock( struct _reent *_r )
00964 {
00965     __rtos_malloc_lock(_r);
00966 }
00967 
00968 extern "C" void __malloc_unlock( struct _reent *_r )
00969 {
00970     __rtos_malloc_unlock(_r);
00971 }
00972 
00973 extern "C" void __env_lock( struct _reent *_r )
00974 {
00975     __rtos_env_lock(_r);
00976 }
00977 
00978 extern "C" void __env_unlock( struct _reent *_r )
00979 {
00980     __rtos_env_unlock(_r);
00981 }
00982 
00983 #define CXA_GUARD_INIT_DONE             (1 << 0)
00984 #define CXA_GUARD_INIT_IN_PROGRESS      (1 << 1)
00985 #define CXA_GUARD_MASK                  (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS)
00986 
00987 extern "C" int __cxa_guard_acquire(int *guard_object_p)
00988 {
00989     uint8_t *guard_object = (uint8_t *)guard_object_p;
00990     if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
00991         return 0;
00992     }
00993     singleton_lock();
00994     if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
00995         singleton_unlock();
00996         return 0;
00997     }
00998     MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK));
00999     *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS;
01000     return 1;
01001 }
01002 
01003 extern "C" void __cxa_guard_release(int *guard_object_p)
01004 {
01005     uint8_t *guard_object = (uint8_t *)guard_object_p;
01006     MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
01007     *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE;
01008     singleton_unlock();
01009 }
01010 
01011 extern "C" void __cxa_guard_abort(int *guard_object_p)
01012 {
01013     uint8_t *guard_object = (uint8_t *)guard_object_p;
01014     MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
01015     *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS;
01016     singleton_unlock();
01017 }
01018 
01019 #endif
01020 
01021 void *operator new(std::size_t count)
01022 {
01023     void *buffer = malloc(count);
01024     if (NULL == buffer) {
01025         error("Operator new out of memory\r\n");
01026     }
01027     return buffer;
01028 }
01029 
01030 void *operator new[](std::size_t count)
01031 {
01032     void *buffer = malloc(count);
01033     if (NULL == buffer) {
01034         error("Operator new[] out of memory\r\n");
01035     }
01036     return buffer;
01037 }
01038 
01039 void operator delete(void *ptr)
01040 {
01041     if (ptr != NULL) {
01042         free(ptr);
01043     }
01044 }
01045 void operator delete[](void *ptr)
01046 {
01047     if (ptr != NULL) {
01048         free(ptr);
01049     }
01050 }