mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
85:4b017b08d507
Child:
147:30b64687e01f
This updates the lib to the mbed lib v125

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