mbed library sources. Supersedes mbed-src.

Fork of mbed by teralytic

Committer:
rodriguise
Date:
Mon Oct 17 18:47:01 2016 +0000
Revision:
148:4802eb17e82b
Parent:
147:30b64687e01f
backup

Who changed what in which revision?

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