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