Vipin Ranka / MGAS_GR_Peach

Dependencies:   GR-PEACH_video GraphicsFramework HTTPServer R_BSP mbed-rpc mbed-rtos Socket lwip-eth lwip-sys lwip FATFileSystem

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Committer:
vipinranka
Date:
Wed Jan 11 11:41:30 2017 +0000
Revision:
12:9a20164dcc47
This is the final version MGAS Project for Renesas GR Peach Design Contest

Who changed what in which revision?

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