TUKS MCU Introductory course / TUKS-COURSE-TIMER
Committer:
elmot
Date:
Fri Feb 24 21:13:56 2017 +0000
Revision:
1:d0dfbce63a89
Ready-to-copy

Who changed what in which revision?

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