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:
Russ Butler
Date:
Sat Aug 13 17:12:03 2016 -0500
Revision:
7514:a0c71f3f3d2f
Parent:
7397:7448008aec84
Child:
7539:b568b913d7a4
Heap statistics

Keep track of the current size allocated, maximum size allocated,
number of allocations, failed allocations and total size allocated for
both GCC and ARM. Report the maximum size allocated at the end of
testing.

Also, add a test to verify heap metrics are working as expected.

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
Russ Butler 7514:a0c71f3f3d2f 482 /* Size must be a multiple of 8 to keep alignment */
Russ Butler 7514:a0c71f3f3d2f 483 typedef struct {
Russ Butler 7514:a0c71f3f3d2f 484 uint32_t size;
Russ Butler 7514:a0c71f3f3d2f 485 uint32_t pad;
Russ Butler 7514:a0c71f3f3d2f 486 } alloc_info_t;
Russ Butler 7514:a0c71f3f3d2f 487
Russ Butler 7514:a0c71f3f3d2f 488 static SingletonPtr<PlatformMutex> malloc_stats_mutex;
Russ Butler 7514:a0c71f3f3d2f 489 static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0};
Russ Butler 7514:a0c71f3f3d2f 490
Russ Butler 7514:a0c71f3f3d2f 491 void mbed_stats_heap_get(mbed_stats_heap_t *stats)
Russ Butler 7514:a0c71f3f3d2f 492 {
Russ Butler 7514:a0c71f3f3d2f 493 malloc_stats_mutex->lock();
Russ Butler 7514:a0c71f3f3d2f 494 memcpy(stats, &heap_stats, sizeof(mbed_stats_heap_t));
Russ Butler 7514:a0c71f3f3d2f 495 malloc_stats_mutex->unlock();
Russ Butler 7514:a0c71f3f3d2f 496 }
Russ Butler 7514:a0c71f3f3d2f 497
Jaeden Amero 6335:6fbbee1c9fd1 498 #if defined(TOOLCHAIN_GCC)
Jaeden Amero 6336:a0ee59c4aa27 499 #ifdef FEATURE_UVISOR
Jaeden Amero 6336:a0ee59c4aa27 500 #include "uvisor-lib/uvisor-lib.h"
Jaeden Amero 6336:a0ee59c4aa27 501 #endif/* FEATURE_UVISOR */
Jaeden Amero 6336:a0ee59c4aa27 502
Niklas Hauser 6337:760e146953ef 503 #ifndef FEATURE_UVISOR
Niklas Hauser 6337:760e146953ef 504 extern "C" {
Russ Butler 7514:a0c71f3f3d2f 505
Russ Butler 7514:a0c71f3f3d2f 506 extern "C" void __malloc_lock( struct _reent *_r );
Russ Butler 7514:a0c71f3f3d2f 507 extern "C" void __malloc_unlock( struct _reent *_r );
Russ Butler 7514:a0c71f3f3d2f 508
Niklas Hauser 6337:760e146953ef 509 void * __wrap__malloc_r(struct _reent * r, size_t size) {
Niklas Hauser 6337:760e146953ef 510 extern void * __real__malloc_r(struct _reent * r, size_t size);
Russ Butler 7514:a0c71f3f3d2f 511 #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED
Niklas Hauser 6337:760e146953ef 512 return __real__malloc_r(r, size);
Russ Butler 7514:a0c71f3f3d2f 513 #else
Russ Butler 7514:a0c71f3f3d2f 514
Russ Butler 7514:a0c71f3f3d2f 515 malloc_stats_mutex->lock();
Russ Butler 7514:a0c71f3f3d2f 516 alloc_info_t *alloc_info = (alloc_info_t*)__real__malloc_r(r, size + sizeof(alloc_info_t));
Russ Butler 7514:a0c71f3f3d2f 517 void *ptr = NULL;
Russ Butler 7514:a0c71f3f3d2f 518 if (alloc_info != NULL) {
Russ Butler 7514:a0c71f3f3d2f 519 alloc_info->size = size;
Russ Butler 7514:a0c71f3f3d2f 520 ptr = (void*)(alloc_info + 1);
Russ Butler 7514:a0c71f3f3d2f 521 heap_stats.current_size += size;
Russ Butler 7514:a0c71f3f3d2f 522 heap_stats.total_size += size;
Russ Butler 7514:a0c71f3f3d2f 523 heap_stats.alloc_cnt += 1;
Russ Butler 7514:a0c71f3f3d2f 524 if (heap_stats.current_size > heap_stats.max_size) {
Russ Butler 7514:a0c71f3f3d2f 525 heap_stats.max_size = heap_stats.current_size;
Russ Butler 7514:a0c71f3f3d2f 526 }
Russ Butler 7514:a0c71f3f3d2f 527 } else {
Russ Butler 7514:a0c71f3f3d2f 528 heap_stats.alloc_fail_cnt += 1;
Russ Butler 7514:a0c71f3f3d2f 529 }
Russ Butler 7514:a0c71f3f3d2f 530 malloc_stats_mutex->unlock();
Russ Butler 7514:a0c71f3f3d2f 531
Russ Butler 7514:a0c71f3f3d2f 532 return ptr;
Russ Butler 7514:a0c71f3f3d2f 533 #endif
Niklas Hauser 6337:760e146953ef 534 }
Niklas Hauser 6337:760e146953ef 535 void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size) {
Russ Butler 7514:a0c71f3f3d2f 536 #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED
Niklas Hauser 6337:760e146953ef 537 extern void * __real__realloc_r(struct _reent * r, void * ptr, size_t size);
Niklas Hauser 6337:760e146953ef 538 return __real__realloc_r(r, ptr, size);
Russ Butler 7514:a0c71f3f3d2f 539 #else
Russ Butler 7514:a0c71f3f3d2f 540
Russ Butler 7514:a0c71f3f3d2f 541 // Implement realloc_r with malloc and free.
Russ Butler 7514:a0c71f3f3d2f 542 // The function realloc_r can't be used here directly since
Russ Butler 7514:a0c71f3f3d2f 543 // it can call into __wrap__malloc_r (returns ptr + 4) or
Russ Butler 7514:a0c71f3f3d2f 544 // resize memory directly (returns ptr + 0).
Russ Butler 7514:a0c71f3f3d2f 545
Russ Butler 7514:a0c71f3f3d2f 546 // Note - no lock needed since malloc and free are thread safe
Russ Butler 7514:a0c71f3f3d2f 547
Russ Butler 7514:a0c71f3f3d2f 548 // Get old size
Russ Butler 7514:a0c71f3f3d2f 549 uint32_t old_size = 0;
Russ Butler 7514:a0c71f3f3d2f 550 if (ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 551 alloc_info_t *alloc_info = ((alloc_info_t*)ptr) - 1;
Russ Butler 7514:a0c71f3f3d2f 552 old_size = alloc_info->size;
Russ Butler 7514:a0c71f3f3d2f 553 }
Russ Butler 7514:a0c71f3f3d2f 554
Russ Butler 7514:a0c71f3f3d2f 555 // Allocate space
Russ Butler 7514:a0c71f3f3d2f 556 void *new_ptr = NULL;
Russ Butler 7514:a0c71f3f3d2f 557 if (size != 0) {
Russ Butler 7514:a0c71f3f3d2f 558 new_ptr = malloc(size);
Russ Butler 7514:a0c71f3f3d2f 559 }
Russ Butler 7514:a0c71f3f3d2f 560
Russ Butler 7514:a0c71f3f3d2f 561 // If the new buffer has been allocated copy the data to it
Russ Butler 7514:a0c71f3f3d2f 562 // and free the old buffer
Russ Butler 7514:a0c71f3f3d2f 563 if (new_ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 564 uint32_t copy_size = (old_size < size) ? old_size : size;
Russ Butler 7514:a0c71f3f3d2f 565 memcpy(new_ptr, (void*)ptr, copy_size);
Russ Butler 7514:a0c71f3f3d2f 566 free(ptr);
Russ Butler 7514:a0c71f3f3d2f 567 }
Russ Butler 7514:a0c71f3f3d2f 568
Russ Butler 7514:a0c71f3f3d2f 569 return new_ptr;
Russ Butler 7514:a0c71f3f3d2f 570 #endif
Niklas Hauser 6337:760e146953ef 571 }
Niklas Hauser 6337:760e146953ef 572 void __wrap__free_r(struct _reent * r, void * ptr) {
Niklas Hauser 6337:760e146953ef 573 extern void __real__free_r(struct _reent * r, void * ptr);
Russ Butler 7514:a0c71f3f3d2f 574 #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED
Niklas Hauser 6337:760e146953ef 575 __real__free_r(r, ptr);
Russ Butler 7514:a0c71f3f3d2f 576 #else
Russ Butler 7514:a0c71f3f3d2f 577
Russ Butler 7514:a0c71f3f3d2f 578 malloc_stats_mutex->lock();
Russ Butler 7514:a0c71f3f3d2f 579 alloc_info_t *alloc_info = NULL;
Russ Butler 7514:a0c71f3f3d2f 580 if (ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 581 alloc_info = ((alloc_info_t*)ptr) - 1;
Russ Butler 7514:a0c71f3f3d2f 582 heap_stats.current_size -= alloc_info->size;
Russ Butler 7514:a0c71f3f3d2f 583 heap_stats.alloc_cnt -= 1;
Russ Butler 7514:a0c71f3f3d2f 584 }
Russ Butler 7514:a0c71f3f3d2f 585 __real__free_r(r, (void*)alloc_info);
Russ Butler 7514:a0c71f3f3d2f 586 malloc_stats_mutex->unlock();
Russ Butler 7514:a0c71f3f3d2f 587 #endif
Russ Butler 7514:a0c71f3f3d2f 588 }
Russ Butler 7514:a0c71f3f3d2f 589 void* __wrap__calloc_r(struct _reent * r, size_t num, size_t size) {
Russ Butler 7514:a0c71f3f3d2f 590 #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED
Russ Butler 7514:a0c71f3f3d2f 591 extern void* __real__calloc_r(struct _reent * r, size_t num, size_t size);
Russ Butler 7514:a0c71f3f3d2f 592 return __real__calloc_r(r, num, size);
Russ Butler 7514:a0c71f3f3d2f 593 #else
Russ Butler 7514:a0c71f3f3d2f 594
Russ Butler 7514:a0c71f3f3d2f 595 // Note - no lock needed since malloc is thread safe
Russ Butler 7514:a0c71f3f3d2f 596
Russ Butler 7514:a0c71f3f3d2f 597 void *ptr = malloc(num * size);
Russ Butler 7514:a0c71f3f3d2f 598 if (ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 599 memset(ptr, 0, num * size);
Russ Butler 7514:a0c71f3f3d2f 600 }
Russ Butler 7514:a0c71f3f3d2f 601
Russ Butler 7514:a0c71f3f3d2f 602 return ptr;
Russ Butler 7514:a0c71f3f3d2f 603 #endif
Niklas Hauser 6337:760e146953ef 604 }
Niklas Hauser 6337:760e146953ef 605 }
Niklas Hauser 6337:760e146953ef 606 #endif/* FEATURE_UVISOR */
Niklas Hauser 6337:760e146953ef 607
Jaeden Amero 6335:6fbbee1c9fd1 608 extern "C" WEAK void software_init_hook_rtos(void)
Jaeden Amero 6335:6fbbee1c9fd1 609 {
Jaeden Amero 6335:6fbbee1c9fd1 610 // Do nothing by default.
Jaeden Amero 6335:6fbbee1c9fd1 611 }
Jaeden Amero 6335:6fbbee1c9fd1 612
Jaeden Amero 6335:6fbbee1c9fd1 613 extern "C" void software_init_hook(void)
Jaeden Amero 6335:6fbbee1c9fd1 614 {
Jaeden Amero 6336:a0ee59c4aa27 615 #ifdef FEATURE_UVISOR
Jaeden Amero 6336:a0ee59c4aa27 616 int return_code;
Jaeden Amero 6336:a0ee59c4aa27 617
Jaeden Amero 6336:a0ee59c4aa27 618 return_code = uvisor_lib_init();
Jaeden Amero 6336:a0ee59c4aa27 619 if (return_code) {
Jaeden Amero 6336:a0ee59c4aa27 620 mbed_die();
Jaeden Amero 6336:a0ee59c4aa27 621 }
Jaeden Amero 6336:a0ee59c4aa27 622 #endif/* FEATURE_UVISOR */
Jaeden Amero 6336:a0ee59c4aa27 623
Jaeden Amero 6335:6fbbee1c9fd1 624 software_init_hook_rtos();
Jaeden Amero 6335:6fbbee1c9fd1 625 }
Jaeden Amero 6335:6fbbee1c9fd1 626 #endif
Jaeden Amero 6335:6fbbee1c9fd1 627
Russ Butler 7514:a0c71f3f3d2f 628 #if defined(TOOLCHAIN_ARM) && (defined(MBED_HEAP_STATS_ENABLED ) && MBED_HEAP_STATS_ENABLED )
Russ Butler 7514:a0c71f3f3d2f 629
Russ Butler 7514:a0c71f3f3d2f 630 extern "C" void *$Super$$malloc(size_t size);
Russ Butler 7514:a0c71f3f3d2f 631 extern "C" void *$Super$$realloc(void * ptr, size_t size);
Russ Butler 7514:a0c71f3f3d2f 632 extern "C" void $Super$$free(void * ptr);
Russ Butler 7514:a0c71f3f3d2f 633
Russ Butler 7514:a0c71f3f3d2f 634 extern "C" void *$Sub$$malloc(size_t size)
Russ Butler 7514:a0c71f3f3d2f 635 {
Russ Butler 7514:a0c71f3f3d2f 636 malloc_stats_mutex->lock();
Russ Butler 7514:a0c71f3f3d2f 637 alloc_info_t *alloc_info = (alloc_info_t*)$Super$$malloc(size + sizeof(alloc_info_t));
Russ Butler 7514:a0c71f3f3d2f 638 void *ptr = NULL;
Russ Butler 7514:a0c71f3f3d2f 639 if (alloc_info != NULL) {
Russ Butler 7514:a0c71f3f3d2f 640 alloc_info->size = size;
Russ Butler 7514:a0c71f3f3d2f 641 ptr = (void*)(alloc_info + 1);
Russ Butler 7514:a0c71f3f3d2f 642 heap_stats.current_size += size;
Russ Butler 7514:a0c71f3f3d2f 643 heap_stats.total_size += size;
Russ Butler 7514:a0c71f3f3d2f 644 heap_stats.alloc_cnt += 1;
Russ Butler 7514:a0c71f3f3d2f 645 if (heap_stats.current_size > heap_stats.max_size) {
Russ Butler 7514:a0c71f3f3d2f 646 heap_stats.max_size = heap_stats.current_size;
Russ Butler 7514:a0c71f3f3d2f 647 }
Russ Butler 7514:a0c71f3f3d2f 648 } else {
Russ Butler 7514:a0c71f3f3d2f 649 heap_stats.alloc_fail_cnt += 1;
Russ Butler 7514:a0c71f3f3d2f 650 }
Russ Butler 7514:a0c71f3f3d2f 651 malloc_stats_mutex->unlock();
Russ Butler 7514:a0c71f3f3d2f 652
Russ Butler 7514:a0c71f3f3d2f 653 return ptr;
Russ Butler 7514:a0c71f3f3d2f 654 }
Russ Butler 7514:a0c71f3f3d2f 655
Russ Butler 7514:a0c71f3f3d2f 656 extern "C" void *$Sub$$realloc(void * ptr, size_t size)
Russ Butler 7514:a0c71f3f3d2f 657 {
Russ Butler 7514:a0c71f3f3d2f 658 // Note - no lock needed since malloc and free are thread safe
Russ Butler 7514:a0c71f3f3d2f 659
Russ Butler 7514:a0c71f3f3d2f 660 // Get old size
Russ Butler 7514:a0c71f3f3d2f 661 uint32_t old_size = 0;
Russ Butler 7514:a0c71f3f3d2f 662 if (ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 663 alloc_info_t *alloc_info = ((alloc_info_t*)ptr) - 1;
Russ Butler 7514:a0c71f3f3d2f 664 old_size = alloc_info->size;
Russ Butler 7514:a0c71f3f3d2f 665 }
Russ Butler 7514:a0c71f3f3d2f 666
Russ Butler 7514:a0c71f3f3d2f 667 // Allocate space
Russ Butler 7514:a0c71f3f3d2f 668 void *new_ptr = NULL;
Russ Butler 7514:a0c71f3f3d2f 669 if (size != 0) {
Russ Butler 7514:a0c71f3f3d2f 670 new_ptr = malloc(size);
Russ Butler 7514:a0c71f3f3d2f 671 }
Russ Butler 7514:a0c71f3f3d2f 672
Russ Butler 7514:a0c71f3f3d2f 673 // If the new buffer has been allocated copy the data to it
Russ Butler 7514:a0c71f3f3d2f 674 // and free the old buffer
Russ Butler 7514:a0c71f3f3d2f 675 if (new_ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 676 uint32_t copy_size = (old_size < size) ? old_size : size;
Russ Butler 7514:a0c71f3f3d2f 677 memcpy(new_ptr, (void*)ptr, copy_size);
Russ Butler 7514:a0c71f3f3d2f 678 free(ptr);
Russ Butler 7514:a0c71f3f3d2f 679 }
Russ Butler 7514:a0c71f3f3d2f 680
Russ Butler 7514:a0c71f3f3d2f 681 return new_ptr;
Russ Butler 7514:a0c71f3f3d2f 682 }
Russ Butler 7514:a0c71f3f3d2f 683 extern "C" void $Sub$$free(void * ptr)
Russ Butler 7514:a0c71f3f3d2f 684 {
Russ Butler 7514:a0c71f3f3d2f 685 malloc_stats_mutex->lock();
Russ Butler 7514:a0c71f3f3d2f 686 alloc_info_t *alloc_info = NULL;
Russ Butler 7514:a0c71f3f3d2f 687 if (ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 688 alloc_info = ((alloc_info_t*)ptr) - 1;
Russ Butler 7514:a0c71f3f3d2f 689 heap_stats.current_size -= alloc_info->size;
Russ Butler 7514:a0c71f3f3d2f 690 heap_stats.alloc_cnt -= 1;
Russ Butler 7514:a0c71f3f3d2f 691 }
Russ Butler 7514:a0c71f3f3d2f 692 $Super$$free((void*)alloc_info);
Russ Butler 7514:a0c71f3f3d2f 693 malloc_stats_mutex->unlock();
Russ Butler 7514:a0c71f3f3d2f 694 }
Russ Butler 7514:a0c71f3f3d2f 695 extern "C" void *$Sub$$calloc(size_t num, size_t size)
Russ Butler 7514:a0c71f3f3d2f 696 {
Russ Butler 7514:a0c71f3f3d2f 697 // Note - no lock needed since malloc is thread safe
Russ Butler 7514:a0c71f3f3d2f 698 void *ptr = malloc(num * size);
Russ Butler 7514:a0c71f3f3d2f 699 if (ptr != NULL) {
Russ Butler 7514:a0c71f3f3d2f 700 memset(ptr, 0, num * size);
Russ Butler 7514:a0c71f3f3d2f 701 }
Russ Butler 7514:a0c71f3f3d2f 702 return ptr;
Russ Butler 7514:a0c71f3f3d2f 703 }
Russ Butler 7514:a0c71f3f3d2f 704
Russ Butler 7514:a0c71f3f3d2f 705 #endif /* defined(TOOLCHAIN_ARM) && (defined(MBED_HEAP_STATS_ENABLED ) && MBED_HEAP_STATS_ENABLED ) */
Russ Butler 7514:a0c71f3f3d2f 706
Mihail Stoyanov 6088:e1cf77a573c5 707 // ****************************************************************************
Mihail Stoyanov 6088:e1cf77a573c5 708 // mbed_main is a function that is called before main()
Mihail Stoyanov 6088:e1cf77a573c5 709 // mbed_sdk_init() is also a function that is called before main(), but unlike
Mihail Stoyanov 6088:e1cf77a573c5 710 // mbed_main(), it is not meant for user code, but for the SDK itself to perform
Mihail Stoyanov 6088:e1cf77a573c5 711 // initializations before main() is called.
Mihail Stoyanov 6088:e1cf77a573c5 712
Mihail Stoyanov 6088:e1cf77a573c5 713 extern "C" WEAK void mbed_main(void);
Mihail Stoyanov 6088:e1cf77a573c5 714 extern "C" WEAK void mbed_main(void) {
Mihail Stoyanov 6088:e1cf77a573c5 715 }
Mihail Stoyanov 6088:e1cf77a573c5 716
Mihail Stoyanov 6088:e1cf77a573c5 717 extern "C" WEAK void mbed_sdk_init(void);
Mihail Stoyanov 6088:e1cf77a573c5 718 extern "C" WEAK void mbed_sdk_init(void) {
Mihail Stoyanov 6088:e1cf77a573c5 719 }
Mihail Stoyanov 6088:e1cf77a573c5 720
Mihail Stoyanov 6088:e1cf77a573c5 721 #if defined(TOOLCHAIN_ARM)
Mihail Stoyanov 6088:e1cf77a573c5 722 extern "C" int $Super$$main(void);
Mihail Stoyanov 6088:e1cf77a573c5 723
Mihail Stoyanov 6088:e1cf77a573c5 724 extern "C" int $Sub$$main(void) {
Mihail Stoyanov 6088:e1cf77a573c5 725 mbed_sdk_init();
Mihail Stoyanov 6088:e1cf77a573c5 726 mbed_main();
Mihail Stoyanov 6088:e1cf77a573c5 727 return $Super$$main();
Mihail Stoyanov 6088:e1cf77a573c5 728 }
Mihail Stoyanov 6088:e1cf77a573c5 729 #elif defined(TOOLCHAIN_GCC)
Mihail Stoyanov 6088:e1cf77a573c5 730 extern "C" int __real_main(void);
Mihail Stoyanov 6088:e1cf77a573c5 731
Mihail Stoyanov 6088:e1cf77a573c5 732 extern "C" int __wrap_main(void) {
Mihail Stoyanov 6088:e1cf77a573c5 733 mbed_sdk_init();
Mihail Stoyanov 6088:e1cf77a573c5 734 mbed_main();
Mihail Stoyanov 6088:e1cf77a573c5 735 return __real_main();
Mihail Stoyanov 6088:e1cf77a573c5 736 }
Mihail Stoyanov 6088:e1cf77a573c5 737 #elif defined(TOOLCHAIN_IAR)
Mihail Stoyanov 6088:e1cf77a573c5 738 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
Mihail Stoyanov 6088:e1cf77a573c5 739 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
Mihail Stoyanov 6088:e1cf77a573c5 740 // 'main' to another symbol looses the original 'main' symbol. However, its startup
Mihail Stoyanov 6088:e1cf77a573c5 741 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
Mihail Stoyanov 6088:e1cf77a573c5 742 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
Mihail Stoyanov 6088:e1cf77a573c5 743 extern "C" void __iar_argc_argv() {
Mihail Stoyanov 6088:e1cf77a573c5 744 mbed_main();
Mihail Stoyanov 6088:e1cf77a573c5 745 }
Mihail Stoyanov 6088:e1cf77a573c5 746 #endif
Mihail Stoyanov 6088:e1cf77a573c5 747
Mihail Stoyanov 6088:e1cf77a573c5 748 // Provide implementation of _sbrk (low-level dynamic memory allocation
Mihail Stoyanov 6088:e1cf77a573c5 749 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
Mihail Stoyanov 6088:e1cf77a573c5 750 // SP. This make it compatible with RTX RTOS thread stacks.
Mihail Stoyanov 6088:e1cf77a573c5 751 #if defined(TOOLCHAIN_GCC_ARM)
Mihail Stoyanov 6088:e1cf77a573c5 752 // Linker defined symbol used by _sbrk to indicate where heap should start.
Mihail Stoyanov 6088:e1cf77a573c5 753 extern "C" int __end__;
Mihail Stoyanov 6088:e1cf77a573c5 754
Mihail Stoyanov 6088:e1cf77a573c5 755 #if defined(TARGET_CORTEX_A)
Mihail Stoyanov 6088:e1cf77a573c5 756 extern "C" uint32_t __HeapLimit;
Mihail Stoyanov 6088:e1cf77a573c5 757 #endif
Mihail Stoyanov 6088:e1cf77a573c5 758
Mihail Stoyanov 6088:e1cf77a573c5 759 // Turn off the errno macro and use actual global variable instead.
Mihail Stoyanov 6088:e1cf77a573c5 760 #undef errno
Mihail Stoyanov 6088:e1cf77a573c5 761 extern "C" int errno;
Mihail Stoyanov 6088:e1cf77a573c5 762
Mihail Stoyanov 6088:e1cf77a573c5 763 // For ARM7 only
Mihail Stoyanov 6088:e1cf77a573c5 764 register unsigned char * stack_ptr __asm ("sp");
Mihail Stoyanov 6088:e1cf77a573c5 765
Mihail Stoyanov 6088:e1cf77a573c5 766 // Dynamic memory allocation related syscall.
ccli8 7328:33c1e9a22f71 767 #if defined(TARGET_NUMAKER_PFM_NUC472)
ccli8 7328:33c1e9a22f71 768 // Overwrite _sbrk() to support two region model.
ccli8 7328:33c1e9a22f71 769 extern "C" void *__wrap__sbrk(int incr);
ccli8 7328:33c1e9a22f71 770 extern "C" caddr_t _sbrk(int incr) {
ccli8 7328:33c1e9a22f71 771 return (caddr_t) __wrap__sbrk(incr);
ccli8 7328:33c1e9a22f71 772 }
ccli8 7328:33c1e9a22f71 773 #else
Mihail Stoyanov 6088:e1cf77a573c5 774 extern "C" caddr_t _sbrk(int incr) {
Mihail Stoyanov 6088:e1cf77a573c5 775 static unsigned char* heap = (unsigned char*)&__end__;
Mihail Stoyanov 6088:e1cf77a573c5 776 unsigned char* prev_heap = heap;
Mihail Stoyanov 6088:e1cf77a573c5 777 unsigned char* new_heap = heap + incr;
Mihail Stoyanov 6088:e1cf77a573c5 778
Mihail Stoyanov 6088:e1cf77a573c5 779 #if defined(TARGET_ARM7)
Mihail Stoyanov 6088:e1cf77a573c5 780 if (new_heap >= stack_ptr) {
Mihail Stoyanov 6088:e1cf77a573c5 781 #elif defined(TARGET_CORTEX_A)
Mihail Stoyanov 6088:e1cf77a573c5 782 if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */
Mihail Stoyanov 6088:e1cf77a573c5 783 #else
Mihail Stoyanov 6088:e1cf77a573c5 784 if (new_heap >= (unsigned char*)__get_MSP()) {
Mihail Stoyanov 6088:e1cf77a573c5 785 #endif
Mihail Stoyanov 6088:e1cf77a573c5 786 errno = ENOMEM;
Mihail Stoyanov 6088:e1cf77a573c5 787 return (caddr_t)-1;
Mihail Stoyanov 6088:e1cf77a573c5 788 }
Mihail Stoyanov 6088:e1cf77a573c5 789
Russ Butler 7395:79e8c79e165c 790 // Additional heap checking if set
Russ Butler 7395:79e8c79e165c 791 if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) {
Russ Butler 7395:79e8c79e165c 792 errno = ENOMEM;
Russ Butler 7395:79e8c79e165c 793 return (caddr_t)-1;
Russ Butler 7395:79e8c79e165c 794 }
Russ Butler 7395:79e8c79e165c 795
Mihail Stoyanov 6088:e1cf77a573c5 796 heap = new_heap;
Mihail Stoyanov 6088:e1cf77a573c5 797 return (caddr_t) prev_heap;
Mihail Stoyanov 6088:e1cf77a573c5 798 }
Mihail Stoyanov 6088:e1cf77a573c5 799 #endif
ccli8 7328:33c1e9a22f71 800 #endif
Mihail Stoyanov 6088:e1cf77a573c5 801
Mihail Stoyanov 6088:e1cf77a573c5 802 #if defined TOOLCHAIN_GCC_ARM
Mihail Stoyanov 6088:e1cf77a573c5 803 extern "C" void _exit(int return_code) {
Mihail Stoyanov 6088:e1cf77a573c5 804 #else
Mihail Stoyanov 6088:e1cf77a573c5 805 namespace std {
Mihail Stoyanov 6088:e1cf77a573c5 806 extern "C" void exit(int return_code) {
Mihail Stoyanov 6088:e1cf77a573c5 807 #endif
Mihail Stoyanov 6088:e1cf77a573c5 808
Mihail Stoyanov 6088:e1cf77a573c5 809 #if DEVICE_STDIO_MESSAGES
Mihail Stoyanov 6088:e1cf77a573c5 810 fflush(stdout);
Mihail Stoyanov 6088:e1cf77a573c5 811 fflush(stderr);
Mihail Stoyanov 6088:e1cf77a573c5 812 #endif
Mihail Stoyanov 6088:e1cf77a573c5 813
Mihail Stoyanov 6088:e1cf77a573c5 814 #if DEVICE_SEMIHOST
Mihail Stoyanov 6088:e1cf77a573c5 815 if (mbed_interface_connected()) {
Mihail Stoyanov 6088:e1cf77a573c5 816 semihost_exit();
Mihail Stoyanov 6088:e1cf77a573c5 817 }
Mihail Stoyanov 6088:e1cf77a573c5 818 #endif
Mihail Stoyanov 6088:e1cf77a573c5 819 if (return_code) {
Mihail Stoyanov 6088:e1cf77a573c5 820 mbed_die();
Mihail Stoyanov 6088:e1cf77a573c5 821 }
Mihail Stoyanov 6088:e1cf77a573c5 822
Mihail Stoyanov 6088:e1cf77a573c5 823 while (1);
Mihail Stoyanov 6088:e1cf77a573c5 824 }
Mihail Stoyanov 6088:e1cf77a573c5 825
Mihail Stoyanov 6088:e1cf77a573c5 826 #if !defined(TOOLCHAIN_GCC_ARM)
Mihail Stoyanov 6088:e1cf77a573c5 827 } //namespace std
Mihail Stoyanov 6088:e1cf77a573c5 828 #endif
Mihail Stoyanov 6088:e1cf77a573c5 829
Mihail Stoyanov 6088:e1cf77a573c5 830
Mihail Stoyanov 6088:e1cf77a573c5 831 namespace mbed {
Mihail Stoyanov 6088:e1cf77a573c5 832
Mihail Stoyanov 6088:e1cf77a573c5 833 void mbed_set_unbuffered_stream(FILE *_file) {
Mihail Stoyanov 6088:e1cf77a573c5 834 #if defined (__ICCARM__)
Mihail Stoyanov 6088:e1cf77a573c5 835 char buf[2];
Mihail Stoyanov 6088:e1cf77a573c5 836 std::setvbuf(_file,buf,_IONBF,NULL);
Mihail Stoyanov 6088:e1cf77a573c5 837 #else
Mihail Stoyanov 6088:e1cf77a573c5 838 setbuf(_file, NULL);
Mihail Stoyanov 6088:e1cf77a573c5 839 #endif
Mihail Stoyanov 6088:e1cf77a573c5 840 }
Mihail Stoyanov 6088:e1cf77a573c5 841
Mihail Stoyanov 6088:e1cf77a573c5 842 int mbed_getc(FILE *_file){
Mihail Stoyanov 6088:e1cf77a573c5 843 #if defined (__ICCARM__)
Mihail Stoyanov 6088:e1cf77a573c5 844 /*This is only valid for unbuffered streams*/
Mihail Stoyanov 6088:e1cf77a573c5 845 int res = std::fgetc(_file);
Mihail Stoyanov 6088:e1cf77a573c5 846 if (res>=0){
Mihail Stoyanov 6088:e1cf77a573c5 847 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
Mihail Stoyanov 6088:e1cf77a573c5 848 _file->_Rend = _file->_Wend;
Mihail Stoyanov 6088:e1cf77a573c5 849 _file->_Next = _file->_Wend;
Mihail Stoyanov 6088:e1cf77a573c5 850 }
Mihail Stoyanov 6088:e1cf77a573c5 851 return res;
Mihail Stoyanov 6088:e1cf77a573c5 852 #else
Mihail Stoyanov 6088:e1cf77a573c5 853 return std::fgetc(_file);
Mihail Stoyanov 6088:e1cf77a573c5 854 #endif
Mihail Stoyanov 6088:e1cf77a573c5 855 }
Mihail Stoyanov 6088:e1cf77a573c5 856
Mihail Stoyanov 6088:e1cf77a573c5 857 char* mbed_gets(char*s, int size, FILE *_file){
Mihail Stoyanov 6088:e1cf77a573c5 858 #if defined (__ICCARM__)
Mihail Stoyanov 6088:e1cf77a573c5 859 /*This is only valid for unbuffered streams*/
Mihail Stoyanov 6088:e1cf77a573c5 860 char *str = fgets(s,size,_file);
Mihail Stoyanov 6088:e1cf77a573c5 861 if (str!=NULL){
Mihail Stoyanov 6088:e1cf77a573c5 862 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
Mihail Stoyanov 6088:e1cf77a573c5 863 _file->_Rend = _file->_Wend;
Mihail Stoyanov 6088:e1cf77a573c5 864 _file->_Next = _file->_Wend;
Mihail Stoyanov 6088:e1cf77a573c5 865 }
Mihail Stoyanov 6088:e1cf77a573c5 866 return str;
Mihail Stoyanov 6088:e1cf77a573c5 867 #else
Mihail Stoyanov 6088:e1cf77a573c5 868 return std::fgets(s,size,_file);
Mihail Stoyanov 6088:e1cf77a573c5 869 #endif
Mihail Stoyanov 6088:e1cf77a573c5 870 }
Mihail Stoyanov 6088:e1cf77a573c5 871
Russ Butler 7514:a0c71f3f3d2f 872 } // namespace mbed
Russ Butler 7514:a0c71f3f3d2f 873
Russ Butler 6200:8000bcdea61d 874 #if defined (__ICCARM__)
Russ Butler 6200:8000bcdea61d 875 // Stub out locks when an rtos is not present
Russ Butler 6200:8000bcdea61d 876 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 877 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 878 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 879 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 880 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 881 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 882 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {}
Russ Butler 6200:8000bcdea61d 883 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {}
Russ Butler 6387:1e339dc397e1 884 #elif defined(__CC_ARM)
Russ Butler 6387:1e339dc397e1 885 // Do nothing
Russ Butler 6387:1e339dc397e1 886 #elif defined (__GNUC__)
Russ Butler 6387:1e339dc397e1 887 struct _reent;
Russ Butler 6387:1e339dc397e1 888 // Stub out locks when an rtos is not present
Russ Butler 6387:1e339dc397e1 889 extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {}
Russ Butler 6387:1e339dc397e1 890 extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {}
Russ Butler 6387:1e339dc397e1 891 extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {}
Russ Butler 6387:1e339dc397e1 892 extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {}
Russ Butler 6387:1e339dc397e1 893
Russ Butler 6396:723dcc4c67dd 894 extern "C" void __malloc_lock( struct _reent *_r )
Russ Butler 6387:1e339dc397e1 895 {
Russ Butler 6387:1e339dc397e1 896 __rtos_malloc_lock(_r);
Russ Butler 6387:1e339dc397e1 897 }
Russ Butler 6387:1e339dc397e1 898
Russ Butler 6396:723dcc4c67dd 899 extern "C" void __malloc_unlock( struct _reent *_r )
Russ Butler 6387:1e339dc397e1 900 {
Russ Butler 6387:1e339dc397e1 901 __rtos_malloc_unlock(_r);
Russ Butler 6387:1e339dc397e1 902 }
Russ Butler 6387:1e339dc397e1 903
Russ Butler 6396:723dcc4c67dd 904 extern "C" void __env_lock( struct _reent *_r )
Russ Butler 6387:1e339dc397e1 905 {
Russ Butler 6387:1e339dc397e1 906 __rtos_env_lock(_r);
Russ Butler 6387:1e339dc397e1 907 }
Russ Butler 6387:1e339dc397e1 908
Russ Butler 6396:723dcc4c67dd 909 extern "C" void __env_unlock( struct _reent *_r )
Russ Butler 6387:1e339dc397e1 910 {
Russ Butler 6387:1e339dc397e1 911 __rtos_env_unlock(_r);
Russ Butler 6387:1e339dc397e1 912 }
Russ Butler 6200:8000bcdea61d 913 #endif
Russ Butler 6200:8000bcdea61d 914
Russ Butler 7397:7448008aec84 915 void *operator new(std::size_t count)
Russ Butler 7397:7448008aec84 916 {
Russ Butler 7397:7448008aec84 917 void *buffer = malloc(count);
Russ Butler 7397:7448008aec84 918 if (NULL == buffer) {
Russ Butler 7397:7448008aec84 919 error("Operator new out of memory\r\n");
Russ Butler 7397:7448008aec84 920 }
Russ Butler 7397:7448008aec84 921 return buffer;
Russ Butler 7397:7448008aec84 922 }
Russ Butler 7397:7448008aec84 923
Russ Butler 7397:7448008aec84 924 void *operator new[](std::size_t count)
Russ Butler 7397:7448008aec84 925 {
Russ Butler 7397:7448008aec84 926 void *buffer = malloc(count);
Russ Butler 7397:7448008aec84 927 if (NULL == buffer) {
Russ Butler 7397:7448008aec84 928 error("Operator new[] out of memory\r\n");
Russ Butler 7397:7448008aec84 929 }
Russ Butler 7397:7448008aec84 930 return buffer;
Russ Butler 7397:7448008aec84 931 }
Russ Butler 7397:7448008aec84 932
Russ Butler 7397:7448008aec84 933 void operator delete(void *ptr)
Russ Butler 7397:7448008aec84 934 {
Russ Butler 7397:7448008aec84 935 if (ptr != NULL) {
Russ Butler 7397:7448008aec84 936 free(ptr);
Russ Butler 7397:7448008aec84 937 }
Russ Butler 7397:7448008aec84 938 }
Russ Butler 7397:7448008aec84 939 void operator delete[](void *ptr)
Russ Butler 7397:7448008aec84 940 {
Russ Butler 7397:7448008aec84 941 if (ptr != NULL) {
Russ Butler 7397:7448008aec84 942 free(ptr);
Russ Butler 7397:7448008aec84 943 }
Russ Butler 7397:7448008aec84 944 }