ST / ST_Events-old

Dependents:   HelloWorld_CCA01M1 HelloWorld_CCA02M1 CI-data-logger-server HelloWorld_CCA02M1 ... more

This is a fork of the events subdirectory of https://github.com/ARMmbed/mbed-os.

Note, you must import this library with import name: events!!!

Committer:
Vincent Coubard
Date:
Mon Sep 19 15:17:39 2016 +0100
Revision:
7987:0474ba76d193
Parent:
7985:90dbfa1a67e6
Child:
8147:c2e43990f039
Override exit and atexit functions from newlib.

This change simplify the exit and initialization process.
It also reduce the number of hidden memory allocation made by atexit.

Who changed what in which revision?

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