This fork captures the mbed lib v125 for ease of integration into older projects.

Fork of mbed-dev by mbed official

Committer:
apluscw
Date:
Fri Jul 20 21:24:42 2018 +0000
Revision:
187:92cbb9eec47b
Mbed library with source code from mbed lib v125. Posted to ease integration with some older projects.

Who changed what in which revision?

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