,,

Fork of Application by Daniel Sygut

Committer:
Zaitsev
Date:
Thu Feb 15 14:29:23 2018 +0000
Revision:
15:2a20c3d2616e
Parent:
10:41552d038a69
j

Who changed what in which revision?

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