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.
Dependents: HelloWorld_CCA01M1 HelloWorld_CCA02M1 CI-data-logger-server HelloWorld_CCA02M1 ... more
This is a fork of the events subdirectory of https://github.com/ARMmbed/mbed-os.
Note, you must import this library with import name: events!!!
hal/common/retarget.cpp@7987:0474ba76d193, 2016-09-19 (annotated)
- Committer:
- Vincent Coubard
- Date:
- Mon Sep 19 15:17:39 2016 +0100
- Revision:
- 7987:0474ba76d193
- Parent:
- 7985:90dbfa1a67e6
- Child:
- 8147:c2e43990f039
Override exit and atexit functions from newlib.
This change simplify the exit and initialization process.
It also reduce the number of hidden memory allocation made by atexit.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Mihail Stoyanov |
6088:e1cf77a573c5 | 1 | /* mbed Microcontroller Library |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 2 | * Copyright (c) 2006-2015 ARM Limited |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 3 | * |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 5 | * you may not use this file except in compliance with the License. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 6 | * You may obtain a copy of the License at |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 7 | * |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 9 | * |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 10 | * Unless required by applicable law or agreed to in writing, software |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 13 | * See the License for the specific language governing permissions and |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 14 | * limitations under the License. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 15 | */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 16 | #include "platform.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 17 | #include "FileHandle.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 18 | #include "FileSystemLike.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 19 | #include "FilePath.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 20 | #include "serial_api.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 21 | #include "toolchain.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 22 | #include "semihost_api.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 23 | #include "mbed_interface.h" |
| Russ Butler |
6984:94fc5d678e5f | 24 | #include "SingletonPtr.h" |
| Russ Butler |
7262:f469aee29594 | 25 | #include "PlatformMutex.h" |
| Russ Butler |
7397:7448008aec84 | 26 | #include "mbed_error.h" |
| Russ Butler |
7514:a0c71f3f3d2f | 27 | #include "mbed_stats.h" |
| Russ Butler |
7397:7448008aec84 | 28 | #include <stdlib.h> |
| Russ Butler |
7514:a0c71f3f3d2f | 29 | #include <string.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 30 | #if DEVICE_STDIO_MESSAGES |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 31 | #include <stdio.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 32 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 33 | #include <errno.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 34 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 35 | #if defined(__ARMCC_VERSION) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 36 | # include <rt_sys.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 37 | # define PREFIX(x) _sys##x |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 38 | # define OPEN_MAX _SYS_OPEN |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 39 | # ifdef __MICROLIB |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 40 | # pragma import(__use_full_stdio) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 41 | # endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 42 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 43 | #elif defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 44 | # include <yfuns.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 45 | # define PREFIX(x) _##x |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 46 | # define OPEN_MAX 16 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 47 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 48 | # define STDIN_FILENO 0 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 49 | # define STDOUT_FILENO 1 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 50 | # define STDERR_FILENO 2 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 51 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 52 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 53 | # include <sys/stat.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 54 | # include <sys/unistd.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 55 | # include <sys/syslimits.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 56 | # define PREFIX(x) x |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 57 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 58 | |
| Russ Butler |
6361:7b5bd40de905 | 59 | #define FILE_HANDLE_RESERVED 0xFFFFFFFF |
| Russ Butler |
6361:7b5bd40de905 | 60 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 61 | using namespace mbed; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 62 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 63 | #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 64 | // Before version 5.03, we were using a patched version of microlib with proper names |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 65 | extern const char __stdin_name[] = ":tt"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 66 | extern const char __stdout_name[] = ":tt"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 67 | extern const char __stderr_name[] = ":tt"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 68 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 69 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 70 | extern const char __stdin_name[] = "/stdin"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 71 | extern const char __stdout_name[] = "/stdout"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 72 | extern const char __stderr_name[] = "/stderr"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 73 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 74 | |
| Russ Butler |
7395:79e8c79e165c | 75 | // Heap limits - only used if set |
| Russ Butler |
7395:79e8c79e165c | 76 | unsigned char *mbed_heap_start = 0; |
| Russ Butler |
7395:79e8c79e165c | 77 | uint32_t mbed_heap_size = 0; |
| Russ Butler |
7395:79e8c79e165c | 78 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 79 | /* newlib has the filehandle field in the FILE struct as a short, so |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 80 | * we can't just return a Filehandle* from _open and instead have to |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 81 | * put it in a filehandles array and return the index into that array |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 82 | * (or rather index+3, as filehandles 0-2 are stdin/out/err). |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 83 | */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 84 | static FileHandle *filehandles[OPEN_MAX]; |
| Russ Butler |
6984:94fc5d678e5f | 85 | static SingletonPtr<PlatformMutex> filehandle_mutex; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 86 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 87 | FileHandle::~FileHandle() { |
| Russ Butler |
6984:94fc5d678e5f | 88 | filehandle_mutex->lock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 89 | /* Remove all open filehandles for this */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 90 | for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 91 | if (filehandles[fh_i] == this) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 92 | filehandles[fh_i] = NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 93 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 94 | } |
| Russ Butler |
6984:94fc5d678e5f | 95 | filehandle_mutex->unlock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 96 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 97 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 98 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 99 | extern int stdio_uart_inited; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 100 | extern serial_t stdio_uart; |
| Christopher Haster |
6549:723eda4f0297 | 101 | #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES |
| Christopher Haster |
6547:5f2779e36035 | 102 | static char stdio_in_prev; |
| Christopher Haster |
6547:5f2779e36035 | 103 | static char stdio_out_prev; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 104 | #endif |
| Christopher Haster |
6548:c08cb6087b0a | 105 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 106 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 107 | static void init_serial() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 108 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 109 | if (stdio_uart_inited) return; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 110 | serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX); |
| Christopher Haster |
6892:5bf317924ef4 | 111 | #if MBED_CONF_CORE_STDIO_BAUD_RATE |
| Christopher Haster |
6892:5bf317924ef4 | 112 | serial_baud(&stdio_uart, MBED_CONF_CORE_STDIO_BAUD_RATE); |
| Christopher Haster |
6892:5bf317924ef4 | 113 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 114 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 115 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 116 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 117 | static inline int openmode_to_posix(int openmode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 118 | int posix = openmode; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 119 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 120 | if (openmode & OPEN_PLUS) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 121 | posix = O_RDWR; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 122 | } else if(openmode & OPEN_W) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 123 | posix = O_WRONLY; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 124 | } else if(openmode & OPEN_A) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 125 | posix = O_WRONLY|O_APPEND; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 126 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 127 | posix = O_RDONLY; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 128 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 129 | /* a, w, a+, w+ all create if file does not already exist */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 130 | if (openmode & (OPEN_A|OPEN_W)) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 131 | posix |= O_CREAT; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 132 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 133 | /* w and w+ truncate */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 134 | if (openmode & OPEN_W) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 135 | posix |= O_TRUNC; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 136 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 137 | #elif defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 138 | switch (openmode & _LLIO_RDWRMASK) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 139 | case _LLIO_RDONLY: posix = O_RDONLY; break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 140 | case _LLIO_WRONLY: posix = O_WRONLY; break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 141 | case _LLIO_RDWR : posix = O_RDWR ; break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 142 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 143 | if (openmode & _LLIO_CREAT ) posix |= O_CREAT; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 144 | if (openmode & _LLIO_APPEND) posix |= O_APPEND; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 145 | if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 146 | #elif defined(TOOLCHAIN_GCC) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 147 | posix &= ~O_BINARY; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 148 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 149 | return posix; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 150 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 151 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 152 | extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 153 | #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 154 | // Before version 5.03, we were using a patched version of microlib with proper names |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 155 | // This is the workaround that the microlib author suggested us |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 156 | static int n = 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 157 | if (!std::strcmp(name, ":tt")) return n++; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 158 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 159 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 160 | /* Use the posix convention that stdin,out,err are filehandles 0,1,2. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 161 | */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 162 | if (std::strcmp(name, __stdin_name) == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 163 | init_serial(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 164 | return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 165 | } else if (std::strcmp(name, __stdout_name) == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 166 | init_serial(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 167 | return 1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 168 | } else if (std::strcmp(name, __stderr_name) == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 169 | init_serial(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 170 | return 2; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 171 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 172 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 173 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 174 | // find the first empty slot in filehandles |
| Russ Butler |
6984:94fc5d678e5f | 175 | filehandle_mutex->lock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 176 | unsigned int fh_i; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 177 | for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 178 | if (filehandles[fh_i] == NULL) break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 179 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 180 | if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { |
| Russ Butler |
6984:94fc5d678e5f | 181 | filehandle_mutex->unlock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 182 | return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 183 | } |
| Russ Butler |
6361:7b5bd40de905 | 184 | filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED; |
| Russ Butler |
6984:94fc5d678e5f | 185 | filehandle_mutex->unlock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 186 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 187 | FileHandle *res; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 188 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 189 | /* FILENAME: ":0x12345678" describes a FileLike* */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 190 | if (name[0] == ':') { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 191 | void *p; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 192 | sscanf(name, ":%p", &p); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 193 | res = (FileHandle*)p; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 194 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 195 | /* FILENAME: "/file_system/file_name" */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 196 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 197 | FilePath path(name); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 198 | |
| Russ Butler |
6361:7b5bd40de905 | 199 | if (!path.exists()) { |
| Russ Butler |
6361:7b5bd40de905 | 200 | // Free file handle |
| Russ Butler |
6361:7b5bd40de905 | 201 | filehandles[fh_i] = NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 202 | return -1; |
| Russ Butler |
6361:7b5bd40de905 | 203 | } else if (path.isFile()) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 204 | res = path.file(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 205 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 206 | FileSystemLike *fs = path.fileSystem(); |
| Russ Butler |
6361:7b5bd40de905 | 207 | if (fs == NULL) { |
| Russ Butler |
6361:7b5bd40de905 | 208 | // Free file handle |
| Russ Butler |
6361:7b5bd40de905 | 209 | filehandles[fh_i] = NULL; |
| Russ Butler |
6361:7b5bd40de905 | 210 | return -1; |
| Russ Butler |
6361:7b5bd40de905 | 211 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 212 | int posix_mode = openmode_to_posix(openmode); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 213 | res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 214 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 215 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 216 | |
| Russ Butler |
6361:7b5bd40de905 | 217 | if (res == NULL) { |
| Russ Butler |
6361:7b5bd40de905 | 218 | // Free file handle |
| Russ Butler |
6361:7b5bd40de905 | 219 | filehandles[fh_i] = NULL; |
| Russ Butler |
6361:7b5bd40de905 | 220 | return -1; |
| Russ Butler |
6361:7b5bd40de905 | 221 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 222 | filehandles[fh_i] = res; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 223 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 224 | return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 225 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 226 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 227 | extern "C" int PREFIX(_close)(FILEHANDLE fh) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 228 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 229 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 230 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 231 | filehandles[fh-3] = NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 232 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 233 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 234 | return fhc->close(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 235 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 236 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 237 | #if defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 238 | extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 239 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 240 | extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 241 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 242 | int n; // n is the number of bytes written |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 243 | if (fh < 3) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 244 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 245 | if (!stdio_uart_inited) init_serial(); |
| Christopher Haster |
6549:723eda4f0297 | 246 | #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 247 | for (unsigned int i = 0; i < length; i++) { |
| Christopher Haster |
6547:5f2779e36035 | 248 | if (buffer[i] == '\n' && stdio_out_prev != '\r') { |
| Christopher Haster |
6546:b7f6a8e13048 | 249 | serial_putc(&stdio_uart, '\r'); |
| Christopher Haster |
6546:b7f6a8e13048 | 250 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 251 | serial_putc(&stdio_uart, buffer[i]); |
| Christopher Haster |
6547:5f2779e36035 | 252 | stdio_out_prev = buffer[i]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 253 | } |
| Christopher Haster |
6548:c08cb6087b0a | 254 | #else |
| Christopher Haster |
6548:c08cb6087b0a | 255 | for (unsigned int i = 0; i < length; i++) { |
| Christopher Haster |
6548:c08cb6087b0a | 256 | serial_putc(&stdio_uart, buffer[i]); |
| Christopher Haster |
6548:c08cb6087b0a | 257 | } |
| Christopher Haster |
6548:c08cb6087b0a | 258 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 259 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 260 | n = length; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 261 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 262 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 263 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 264 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 265 | n = fhc->write(buffer, length); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 266 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 267 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 268 | return length-n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 269 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 270 | return n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 271 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 272 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 273 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 274 | #if defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 275 | extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 276 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 277 | extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 278 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 279 | int n; // n is the number of bytes read |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 280 | if (fh < 3) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 281 | // only read a character at a time from stdin |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 282 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 283 | if (!stdio_uart_inited) init_serial(); |
| Christopher Haster |
6549:723eda4f0297 | 284 | #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES |
| Christopher Haster |
6547:5f2779e36035 | 285 | while (true) { |
| Christopher Haster |
6547:5f2779e36035 | 286 | char c = serial_getc(&stdio_uart); |
| Christopher Haster |
6547:5f2779e36035 | 287 | if ((c == '\r' && stdio_in_prev != '\n') || |
| Christopher Haster |
6547:5f2779e36035 | 288 | (c == '\n' && stdio_in_prev != '\r')) { |
| Christopher Haster |
6547:5f2779e36035 | 289 | stdio_in_prev = c; |
| Christopher Haster |
6547:5f2779e36035 | 290 | *buffer = '\n'; |
| Christopher Haster |
6547:5f2779e36035 | 291 | break; |
| Christopher Haster |
6547:5f2779e36035 | 292 | } else if ((c == '\r' && stdio_in_prev == '\n') || |
| Christopher Haster |
6547:5f2779e36035 | 293 | (c == '\n' && stdio_in_prev == '\r')) { |
| Christopher Haster |
6547:5f2779e36035 | 294 | stdio_in_prev = c; |
| Christopher Haster |
6547:5f2779e36035 | 295 | // onto next character |
| Christopher Haster |
6547:5f2779e36035 | 296 | continue; |
| Christopher Haster |
6547:5f2779e36035 | 297 | } else { |
| Christopher Haster |
6547:5f2779e36035 | 298 | stdio_in_prev = c; |
| Christopher Haster |
6547:5f2779e36035 | 299 | *buffer = c; |
| Christopher Haster |
6547:5f2779e36035 | 300 | break; |
| Christopher Haster |
6547:5f2779e36035 | 301 | } |
| Christopher Haster |
6547:5f2779e36035 | 302 | } |
| Christopher Haster |
6548:c08cb6087b0a | 303 | #else |
| Christopher Haster |
6548:c08cb6087b0a | 304 | *buffer = serial_getc(&stdio_uart); |
| Christopher Haster |
6548:c08cb6087b0a | 305 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 306 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 307 | n = 1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 308 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 309 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 310 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 311 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 312 | n = fhc->read(buffer, length); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 313 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 314 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 315 | return length-n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 316 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 317 | return n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 318 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 319 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 320 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 321 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 322 | extern "C" int PREFIX(_istty)(FILEHANDLE fh) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 323 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 324 | extern "C" int _isatty(FILEHANDLE fh) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 325 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 326 | { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 327 | /* stdin, stdout and stderr should be tty */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 328 | if (fh < 3) return 1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 329 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 330 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 331 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 332 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 333 | return fhc->isatty(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 334 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 335 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 336 | extern "C" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 337 | #if defined(__ARMCC_VERSION) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 338 | int _sys_seek(FILEHANDLE fh, long position) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 339 | #elif defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 340 | long __lseek(int fh, long offset, int whence) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 341 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 342 | int _lseek(FILEHANDLE fh, int offset, int whence) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 343 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 344 | { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 345 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 346 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 347 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 348 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 349 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 350 | #if defined(__ARMCC_VERSION) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 351 | return fhc->lseek(position, SEEK_SET); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 352 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 353 | return fhc->lseek(offset, whence); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 354 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 355 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 356 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 357 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 358 | extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 359 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 360 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 361 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 362 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 363 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 364 | return fhc->fsync(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 365 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 366 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 367 | extern "C" long PREFIX(_flen)(FILEHANDLE fh) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 368 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 369 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 370 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 371 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 372 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 373 | return fhc->flen(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 374 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 375 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 376 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 377 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 378 | #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 379 | extern "C" int _fstat(int fd, struct stat *st) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 380 | if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 381 | st->st_mode = S_IFCHR; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 382 | return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 383 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 384 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 385 | errno = EBADF; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 386 | return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 387 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 388 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 389 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 390 | namespace std { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 391 | extern "C" int remove(const char *path) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 392 | FilePath fp(path); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 393 | FileSystemLike *fs = fp.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 394 | if (fs == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 395 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 396 | return fs->remove(fp.fileName()); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 397 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 398 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 399 | extern "C" int rename(const char *oldname, const char *newname) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 400 | FilePath fpOld(oldname); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 401 | FilePath fpNew(newname); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 402 | FileSystemLike *fsOld = fpOld.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 403 | FileSystemLike *fsNew = fpNew.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 404 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 405 | /* rename only if both files are on the same FS */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 406 | if (fsOld != fsNew || fsOld == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 407 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 408 | return fsOld->rename(fpOld.fileName(), fpNew.fileName()); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 409 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 410 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 411 | extern "C" char *tmpnam(char *s) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 412 | return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 413 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 414 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 415 | extern "C" FILE *tmpfile() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 416 | return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 417 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 418 | } // namespace std |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 419 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 420 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 421 | extern "C" char *_sys_command_string(char *cmd, int len) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 422 | return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 423 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 424 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 425 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 426 | extern "C" DIR *opendir(const char *path) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 427 | /* root dir is FileSystemLike */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 428 | if (path[0] == '/' && path[1] == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 429 | return FileSystemLike::opendir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 430 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 431 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 432 | FilePath fp(path); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 433 | FileSystemLike* fs = fp.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 434 | if (fs == NULL) return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 435 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 436 | return fs->opendir(fp.fileName()); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 437 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 438 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 439 | extern "C" struct dirent *readdir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 440 | return dir->readdir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 441 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 442 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 443 | extern "C" int closedir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 444 | return dir->closedir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 445 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 446 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 447 | extern "C" void rewinddir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 448 | dir->rewinddir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 449 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 450 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 451 | extern "C" off_t telldir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 452 | return dir->telldir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 453 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 454 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 455 | extern "C" void seekdir(DIR *dir, off_t off) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 456 | dir->seekdir(off); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 457 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 458 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 459 | extern "C" int mkdir(const char *path, mode_t mode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 460 | FilePath fp(path); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 461 | FileSystemLike *fs = fp.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 462 | if (fs == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 463 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 464 | return fs->mkdir(fp.fileName(), mode); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 465 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 466 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 467 | #if defined(TOOLCHAIN_GCC) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 468 | /* prevents the exception handling name demangling code getting pulled in */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 469 | #include "mbed_error.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 470 | namespace __gnu_cxx { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 471 | void __verbose_terminate_handler() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 472 | error("Exception"); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 473 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 474 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 475 | extern "C" WEAK void __cxa_pure_virtual(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 476 | extern "C" WEAK void __cxa_pure_virtual(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 477 | exit(1); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 478 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 479 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 480 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 481 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 482 | #if defined(TOOLCHAIN_GCC) |
| Russ Butler |
7514:a0c71f3f3d2f | 483 | |
| Martin Kojtal |
7648:75e4c00cee42 | 484 | #ifdef FEATURE_UVISOR |
| Martin Kojtal |
7648:75e4c00cee42 | 485 | #include "uvisor-lib/uvisor-lib.h" |
| Niklas Hauser |
7539:b568b913d7a4 | 486 | #endif/* FEATURE_UVISOR */ |
| Niklas Hauser |
7539:b568b913d7a4 | 487 | |
| Niklas Hauser |
6337:760e146953ef | 488 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 489 | extern "C" WEAK void software_init_hook_rtos(void) |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 490 | { |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 491 | // Do nothing by default. |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 492 | } |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 493 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 494 | extern "C" void software_init_hook(void) |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 495 | { |
| Jaeden Amero |
6336:a0ee59c4aa27 | 496 | #ifdef FEATURE_UVISOR |
| Jaeden Amero |
6336:a0ee59c4aa27 | 497 | int return_code; |
| Jaeden Amero |
6336:a0ee59c4aa27 | 498 | |
| Jaeden Amero |
6336:a0ee59c4aa27 | 499 | return_code = uvisor_lib_init(); |
| Jaeden Amero |
6336:a0ee59c4aa27 | 500 | if (return_code) { |
| Jaeden Amero |
6336:a0ee59c4aa27 | 501 | mbed_die(); |
| Jaeden Amero |
6336:a0ee59c4aa27 | 502 | } |
| Jaeden Amero |
6336:a0ee59c4aa27 | 503 | #endif/* FEATURE_UVISOR */ |
| Jaeden Amero |
6336:a0ee59c4aa27 | 504 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 505 | software_init_hook_rtos(); |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 506 | } |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 507 | #endif |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 508 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 509 | // **************************************************************************** |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 510 | // mbed_main is a function that is called before main() |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 511 | // mbed_sdk_init() is also a function that is called before main(), but unlike |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 512 | // mbed_main(), it is not meant for user code, but for the SDK itself to perform |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 513 | // initializations before main() is called. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 514 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 515 | extern "C" WEAK void mbed_main(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 516 | extern "C" WEAK void mbed_main(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 517 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 518 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 519 | extern "C" WEAK void mbed_sdk_init(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 520 | extern "C" WEAK void mbed_sdk_init(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 521 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 522 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 523 | #if defined(TOOLCHAIN_ARM) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 524 | extern "C" int $Super$$main(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 525 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 526 | extern "C" int $Sub$$main(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 527 | mbed_sdk_init(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 528 | mbed_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 529 | return $Super$$main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 530 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 531 | #elif defined(TOOLCHAIN_GCC) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 532 | extern "C" int __real_main(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 533 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 534 | extern "C" int __wrap_main(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 535 | mbed_sdk_init(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 536 | mbed_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 537 | return __real_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 538 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 539 | #elif defined(TOOLCHAIN_IAR) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 540 | // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 541 | // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 542 | // 'main' to another symbol looses the original 'main' symbol. However, its startup |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 543 | // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 544 | // Since mbed doesn't use argc/argv, we use this function to call our mbed_main. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 545 | extern "C" void __iar_argc_argv() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 546 | mbed_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 547 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 548 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 549 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 550 | // Provide implementation of _sbrk (low-level dynamic memory allocation |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 551 | // routine) for GCC_ARM which compares new heap pointer with MSP instead of |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 552 | // SP. This make it compatible with RTX RTOS thread stacks. |
| Toyomasa Watarai |
7575:67b11b21d959 | 553 | #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 554 | // Linker defined symbol used by _sbrk to indicate where heap should start. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 555 | extern "C" int __end__; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 556 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 557 | #if defined(TARGET_CORTEX_A) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 558 | extern "C" uint32_t __HeapLimit; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 559 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 560 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 561 | // Turn off the errno macro and use actual global variable instead. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 562 | #undef errno |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 563 | extern "C" int errno; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 564 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 565 | // For ARM7 only |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 566 | register unsigned char * stack_ptr __asm ("sp"); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 567 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 568 | // Dynamic memory allocation related syscall. |
| ccli8 |
7328:33c1e9a22f71 | 569 | #if defined(TARGET_NUMAKER_PFM_NUC472) |
| ccli8 |
7328:33c1e9a22f71 | 570 | // Overwrite _sbrk() to support two region model. |
| ccli8 |
7328:33c1e9a22f71 | 571 | extern "C" void *__wrap__sbrk(int incr); |
| ccli8 |
7328:33c1e9a22f71 | 572 | extern "C" caddr_t _sbrk(int incr) { |
| ccli8 |
7328:33c1e9a22f71 | 573 | return (caddr_t) __wrap__sbrk(incr); |
| ccli8 |
7328:33c1e9a22f71 | 574 | } |
| ccli8 |
7328:33c1e9a22f71 | 575 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 576 | extern "C" caddr_t _sbrk(int incr) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 577 | static unsigned char* heap = (unsigned char*)&__end__; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 578 | unsigned char* prev_heap = heap; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 579 | unsigned char* new_heap = heap + incr; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 580 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 581 | #if defined(TARGET_ARM7) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 582 | if (new_heap >= stack_ptr) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 583 | #elif defined(TARGET_CORTEX_A) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 584 | if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 585 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 586 | if (new_heap >= (unsigned char*)__get_MSP()) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 587 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 588 | errno = ENOMEM; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 589 | return (caddr_t)-1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 590 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 591 | |
| Russ Butler |
7395:79e8c79e165c | 592 | // Additional heap checking if set |
| Russ Butler |
7395:79e8c79e165c | 593 | if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) { |
| Russ Butler |
7395:79e8c79e165c | 594 | errno = ENOMEM; |
| Russ Butler |
7395:79e8c79e165c | 595 | return (caddr_t)-1; |
| Russ Butler |
7395:79e8c79e165c | 596 | } |
| Russ Butler |
7395:79e8c79e165c | 597 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 598 | heap = new_heap; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 599 | return (caddr_t) prev_heap; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 600 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 601 | #endif |
| ccli8 |
7328:33c1e9a22f71 | 602 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 603 | |
| Toyomasa Watarai |
7575:67b11b21d959 | 604 | #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 605 | extern "C" void _exit(int return_code) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 606 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 607 | namespace std { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 608 | extern "C" void exit(int return_code) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 609 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 610 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 611 | #if DEVICE_STDIO_MESSAGES |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 612 | fflush(stdout); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 613 | fflush(stderr); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 614 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 615 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 616 | #if DEVICE_SEMIHOST |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 617 | if (mbed_interface_connected()) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 618 | semihost_exit(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 619 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 620 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 621 | if (return_code) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 622 | mbed_die(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 623 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 624 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 625 | while (1); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 626 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 627 | |
| Toyomasa Watarai |
7575:67b11b21d959 | 628 | #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 629 | } //namespace std |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 630 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 631 | |
| Vincent Coubard |
7987:0474ba76d193 | 632 | #if defined(TOOLCHAIN_ARM) || defined(TOOLCHAIN_GCC) |
| Vincent Coubard |
7985:90dbfa1a67e6 | 633 | |
| Vincent Coubard |
7985:90dbfa1a67e6 | 634 | // This series of function disable the registration of global destructors |
| Vincent Coubard |
7985:90dbfa1a67e6 | 635 | // in a dynamic table which will be called when the application exit. |
| Vincent Coubard |
7985:90dbfa1a67e6 | 636 | // In mbed, program never exit properly, it dies. |
| Vincent Coubard |
7985:90dbfa1a67e6 | 637 | // More informations about this topic for ARMCC here: |
| Vincent Coubard |
7985:90dbfa1a67e6 | 638 | // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/6449.html |
| Vincent Coubard |
7985:90dbfa1a67e6 | 639 | extern "C" { |
| Vincent Coubard |
7985:90dbfa1a67e6 | 640 | int __aeabi_atexit(void *object, void (*dtor)(void* /*this*/), void *handle) { |
| Vincent Coubard |
7985:90dbfa1a67e6 | 641 | return 1; |
| Vincent Coubard |
7985:90dbfa1a67e6 | 642 | } |
| Vincent Coubard |
7985:90dbfa1a67e6 | 643 | |
| Vincent Coubard |
7985:90dbfa1a67e6 | 644 | int __cxa_atexit(void (*dtor)(void* /*this*/), void *object, void *handle) { |
| Vincent Coubard |
7985:90dbfa1a67e6 | 645 | return 1; |
| Vincent Coubard |
7985:90dbfa1a67e6 | 646 | } |
| Vincent Coubard |
7985:90dbfa1a67e6 | 647 | |
| Vincent Coubard |
7985:90dbfa1a67e6 | 648 | void __cxa_finalize(void *handle) { |
| Vincent Coubard |
7985:90dbfa1a67e6 | 649 | } |
| Vincent Coubard |
7985:90dbfa1a67e6 | 650 | |
| Vincent Coubard |
7985:90dbfa1a67e6 | 651 | } // end of extern "C" |
| Vincent Coubard |
7985:90dbfa1a67e6 | 652 | |
| Vincent Coubard |
7987:0474ba76d193 | 653 | #endif |
| Vincent Coubard |
7987:0474ba76d193 | 654 | |
| Vincent Coubard |
7987:0474ba76d193 | 655 | |
| Vincent Coubard |
7987:0474ba76d193 | 656 | #if defined(TOOLCHAIN_GCC) |
| Vincent Coubard |
7987:0474ba76d193 | 657 | |
| Vincent Coubard |
7987:0474ba76d193 | 658 | /* |
| Vincent Coubard |
7987:0474ba76d193 | 659 | * Depending on how newlib is configured, it is often not enough to define |
| Vincent Coubard |
7987:0474ba76d193 | 660 | * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the |
| Vincent Coubard |
7987:0474ba76d193 | 661 | * behavior regarding the registration of handlers with atexit. |
| Vincent Coubard |
7987:0474ba76d193 | 662 | * |
| Vincent Coubard |
7987:0474ba76d193 | 663 | * To overcome this limitation, exit and atexit are overriden here. |
| Vincent Coubard |
7987:0474ba76d193 | 664 | */ |
| Vincent Coubard |
7987:0474ba76d193 | 665 | extern "C"{ |
| Vincent Coubard |
7987:0474ba76d193 | 666 | |
| Vincent Coubard |
7987:0474ba76d193 | 667 | /** |
| Vincent Coubard |
7987:0474ba76d193 | 668 | * @brief Retarget of exit for GCC. |
| Vincent Coubard |
7987:0474ba76d193 | 669 | * @details Unlike the standard version, this function doesn't call any function |
| Vincent Coubard |
7987:0474ba76d193 | 670 | * registered with atexit before calling _exit. |
| Vincent Coubard |
7987:0474ba76d193 | 671 | */ |
| Vincent Coubard |
7987:0474ba76d193 | 672 | void __wrap_exit(int return_code) { |
| Vincent Coubard |
7987:0474ba76d193 | 673 | _exit(return_code); |
| Vincent Coubard |
7987:0474ba76d193 | 674 | } |
| Vincent Coubard |
7987:0474ba76d193 | 675 | |
| Vincent Coubard |
7987:0474ba76d193 | 676 | /** |
| Vincent Coubard |
7987:0474ba76d193 | 677 | * @brief Retarget atexit from GCC. |
| Vincent Coubard |
7987:0474ba76d193 | 678 | * @details This function will always fail and never register any handler to be |
| Vincent Coubard |
7987:0474ba76d193 | 679 | * called at exit. |
| Vincent Coubard |
7987:0474ba76d193 | 680 | */ |
| Vincent Coubard |
7987:0474ba76d193 | 681 | int __wrap_atexit(void (*func)()) { |
| Vincent Coubard |
7987:0474ba76d193 | 682 | return 1; |
| Vincent Coubard |
7987:0474ba76d193 | 683 | } |
| Vincent Coubard |
7987:0474ba76d193 | 684 | |
| Vincent Coubard |
7987:0474ba76d193 | 685 | } |
| Vincent Coubard |
7985:90dbfa1a67e6 | 686 | |
| Vincent Coubard |
7985:90dbfa1a67e6 | 687 | #endif |
| Vincent Coubard |
7985:90dbfa1a67e6 | 688 | |
| Vincent Coubard |
7985:90dbfa1a67e6 | 689 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 690 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 691 | namespace mbed { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 692 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 693 | void mbed_set_unbuffered_stream(FILE *_file) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 694 | #if defined (__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 695 | char buf[2]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 696 | std::setvbuf(_file,buf,_IONBF,NULL); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 697 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 698 | setbuf(_file, NULL); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 699 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 700 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 701 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 702 | int mbed_getc(FILE *_file){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 703 | #if defined (__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 704 | /*This is only valid for unbuffered streams*/ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 705 | int res = std::fgetc(_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 706 | if (res>=0){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 707 | _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 708 | _file->_Rend = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 709 | _file->_Next = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 710 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 711 | return res; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 712 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 713 | return std::fgetc(_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 714 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 715 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 716 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 717 | char* mbed_gets(char*s, int size, FILE *_file){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 718 | #if defined (__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 719 | /*This is only valid for unbuffered streams*/ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 720 | char *str = fgets(s,size,_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 721 | if (str!=NULL){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 722 | _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 723 | _file->_Rend = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 724 | _file->_Next = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 725 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 726 | return str; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 727 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 728 | return std::fgets(s,size,_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 729 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 730 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 731 | |
| Russ Butler |
7514:a0c71f3f3d2f | 732 | } // namespace mbed |
| Russ Butler |
7514:a0c71f3f3d2f | 733 | |
| Russ Butler |
6200:8000bcdea61d | 734 | #if defined (__ICCARM__) |
| Russ Butler |
6200:8000bcdea61d | 735 | // Stub out locks when an rtos is not present |
| Russ Butler |
6200:8000bcdea61d | 736 | extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 737 | extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 738 | extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 739 | extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 740 | extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 741 | extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 742 | extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 743 | extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6387:1e339dc397e1 | 744 | #elif defined(__CC_ARM) |
| Russ Butler |
6387:1e339dc397e1 | 745 | // Do nothing |
| Russ Butler |
6387:1e339dc397e1 | 746 | #elif defined (__GNUC__) |
| Russ Butler |
6387:1e339dc397e1 | 747 | struct _reent; |
| Russ Butler |
6387:1e339dc397e1 | 748 | // Stub out locks when an rtos is not present |
| Russ Butler |
6387:1e339dc397e1 | 749 | extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 750 | extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 751 | extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 752 | extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 753 | |
| Russ Butler |
6396:723dcc4c67dd | 754 | extern "C" void __malloc_lock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 755 | { |
| Russ Butler |
6387:1e339dc397e1 | 756 | __rtos_malloc_lock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 757 | } |
| Russ Butler |
6387:1e339dc397e1 | 758 | |
| Russ Butler |
6396:723dcc4c67dd | 759 | extern "C" void __malloc_unlock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 760 | { |
| Russ Butler |
6387:1e339dc397e1 | 761 | __rtos_malloc_unlock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 762 | } |
| Russ Butler |
6387:1e339dc397e1 | 763 | |
| Russ Butler |
6396:723dcc4c67dd | 764 | extern "C" void __env_lock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 765 | { |
| Russ Butler |
6387:1e339dc397e1 | 766 | __rtos_env_lock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 767 | } |
| Russ Butler |
6387:1e339dc397e1 | 768 | |
| Russ Butler |
6396:723dcc4c67dd | 769 | extern "C" void __env_unlock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 770 | { |
| Russ Butler |
6387:1e339dc397e1 | 771 | __rtos_env_unlock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 772 | } |
| Russ Butler |
7720:7391e7e92fda | 773 | |
| Russ Butler |
7720:7391e7e92fda | 774 | #define CXA_GUARD_INIT_DONE (1 << 0) |
| Russ Butler |
7720:7391e7e92fda | 775 | #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1) |
| Russ Butler |
7720:7391e7e92fda | 776 | #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS) |
| Russ Butler |
7720:7391e7e92fda | 777 | |
| Russ Butler |
7720:7391e7e92fda | 778 | extern "C" int __cxa_guard_acquire(int *guard_object_p) |
| Russ Butler |
7720:7391e7e92fda | 779 | { |
| Russ Butler |
7720:7391e7e92fda | 780 | uint8_t *guard_object = (uint8_t *)guard_object_p; |
| Russ Butler |
7720:7391e7e92fda | 781 | if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { |
| Russ Butler |
7720:7391e7e92fda | 782 | return 0; |
| Russ Butler |
7720:7391e7e92fda | 783 | } |
| Russ Butler |
7720:7391e7e92fda | 784 | singleton_lock(); |
| Russ Butler |
7720:7391e7e92fda | 785 | if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { |
| Russ Butler |
7720:7391e7e92fda | 786 | singleton_unlock(); |
| Russ Butler |
7720:7391e7e92fda | 787 | return 0; |
| Russ Butler |
7720:7391e7e92fda | 788 | } |
| Russ Butler |
7720:7391e7e92fda | 789 | MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK)); |
| Russ Butler |
7720:7391e7e92fda | 790 | *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS; |
| Russ Butler |
7720:7391e7e92fda | 791 | return 1; |
| Russ Butler |
7720:7391e7e92fda | 792 | } |
| Russ Butler |
7720:7391e7e92fda | 793 | |
| Russ Butler |
7720:7391e7e92fda | 794 | extern "C" void __cxa_guard_release(int *guard_object_p) |
| Russ Butler |
7720:7391e7e92fda | 795 | { |
| Russ Butler |
7720:7391e7e92fda | 796 | uint8_t *guard_object = (uint8_t *)guard_object_p; |
| Russ Butler |
7720:7391e7e92fda | 797 | MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); |
| Russ Butler |
7720:7391e7e92fda | 798 | *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE; |
| Russ Butler |
7720:7391e7e92fda | 799 | singleton_unlock(); |
| Russ Butler |
7720:7391e7e92fda | 800 | } |
| Russ Butler |
7720:7391e7e92fda | 801 | |
| Russ Butler |
7720:7391e7e92fda | 802 | extern "C" void __cxa_guard_abort(int *guard_object_p) |
| Russ Butler |
7720:7391e7e92fda | 803 | { |
| Russ Butler |
7720:7391e7e92fda | 804 | uint8_t *guard_object = (uint8_t *)guard_object_p; |
| Russ Butler |
7720:7391e7e92fda | 805 | MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); |
| Russ Butler |
7720:7391e7e92fda | 806 | *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS; |
| Russ Butler |
7720:7391e7e92fda | 807 | singleton_unlock(); |
| Russ Butler |
7720:7391e7e92fda | 808 | } |
| Russ Butler |
7720:7391e7e92fda | 809 | |
| Russ Butler |
6200:8000bcdea61d | 810 | #endif |
| Russ Butler |
6200:8000bcdea61d | 811 | |
| Russ Butler |
7397:7448008aec84 | 812 | void *operator new(std::size_t count) |
| Russ Butler |
7397:7448008aec84 | 813 | { |
| Russ Butler |
7397:7448008aec84 | 814 | void *buffer = malloc(count); |
| Russ Butler |
7397:7448008aec84 | 815 | if (NULL == buffer) { |
| Russ Butler |
7397:7448008aec84 | 816 | error("Operator new out of memory\r\n"); |
| Russ Butler |
7397:7448008aec84 | 817 | } |
| Russ Butler |
7397:7448008aec84 | 818 | return buffer; |
| Russ Butler |
7397:7448008aec84 | 819 | } |
| Russ Butler |
7397:7448008aec84 | 820 | |
| Russ Butler |
7397:7448008aec84 | 821 | void *operator new[](std::size_t count) |
| Russ Butler |
7397:7448008aec84 | 822 | { |
| Russ Butler |
7397:7448008aec84 | 823 | void *buffer = malloc(count); |
| Russ Butler |
7397:7448008aec84 | 824 | if (NULL == buffer) { |
| Russ Butler |
7397:7448008aec84 | 825 | error("Operator new[] out of memory\r\n"); |
| Russ Butler |
7397:7448008aec84 | 826 | } |
| Russ Butler |
7397:7448008aec84 | 827 | return buffer; |
| Russ Butler |
7397:7448008aec84 | 828 | } |
| Russ Butler |
7397:7448008aec84 | 829 | |
| Russ Butler |
7397:7448008aec84 | 830 | void operator delete(void *ptr) |
| Russ Butler |
7397:7448008aec84 | 831 | { |
| Russ Butler |
7397:7448008aec84 | 832 | if (ptr != NULL) { |
| Russ Butler |
7397:7448008aec84 | 833 | free(ptr); |
| Russ Butler |
7397:7448008aec84 | 834 | } |
| Russ Butler |
7397:7448008aec84 | 835 | } |
| Russ Butler |
7397:7448008aec84 | 836 | void operator delete[](void *ptr) |
| Russ Butler |
7397:7448008aec84 | 837 | { |
| Russ Butler |
7397:7448008aec84 | 838 | if (ptr != NULL) { |
| Russ Butler |
7397:7448008aec84 | 839 | free(ptr); |
| Russ Butler |
7397:7448008aec84 | 840 | } |
| Russ Butler |
7397:7448008aec84 | 841 | } |