mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
Anna Bridge
Date:
Wed Jan 17 15:23:54 2018 +0000
Revision:
180:96ed750bd169
Parent:
179:b0033dcd6934
Child:
181:57724642e740
mbed-dev libray. Release version 158

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 160:d5399cc887bb 1 /* mbed Microcontroller Library
<> 160:d5399cc887bb 2 * Copyright (c) 2006-2015 ARM Limited
<> 160:d5399cc887bb 3 *
<> 160:d5399cc887bb 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 160:d5399cc887bb 5 * you may not use this file except in compliance with the License.
<> 160:d5399cc887bb 6 * You may obtain a copy of the License at
<> 160:d5399cc887bb 7 *
<> 160:d5399cc887bb 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 160:d5399cc887bb 9 *
<> 160:d5399cc887bb 10 * Unless required by applicable law or agreed to in writing, software
<> 160:d5399cc887bb 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 160:d5399cc887bb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 160:d5399cc887bb 13 * See the License for the specific language governing permissions and
<> 160:d5399cc887bb 14 * limitations under the License.
<> 160:d5399cc887bb 15 */
AnnaBridge 175:af195413fb11 16 #include <time.h>
<> 160:d5399cc887bb 17 #include "platform/platform.h"
AnnaBridge 167:e84263d55307 18 #include "platform/FilePath.h"
<> 160:d5399cc887bb 19 #include "hal/serial_api.h"
AnnaBridge 175:af195413fb11 20 #include "hal/us_ticker_api.h"
<> 160:d5399cc887bb 21 #include "platform/mbed_toolchain.h"
<> 160:d5399cc887bb 22 #include "platform/mbed_semihost_api.h"
<> 160:d5399cc887bb 23 #include "platform/mbed_interface.h"
<> 160:d5399cc887bb 24 #include "platform/SingletonPtr.h"
<> 160:d5399cc887bb 25 #include "platform/PlatformMutex.h"
<> 160:d5399cc887bb 26 #include "platform/mbed_error.h"
<> 160:d5399cc887bb 27 #include "platform/mbed_stats.h"
AnnaBridge 167:e84263d55307 28 #include "platform/mbed_critical.h"
AnnaBridge 175:af195413fb11 29 #include "platform/PlatformMutex.h"
Anna Bridge 180:96ed750bd169 30 #include "us_ticker_api.h"
Anna Bridge 180:96ed750bd169 31 #include "lp_ticker_api.h"
<> 160:d5399cc887bb 32 #include <stdlib.h>
<> 160:d5399cc887bb 33 #include <string.h>
AnnaBridge 167:e84263d55307 34 #include <limits.h>
<> 160:d5399cc887bb 35 #if DEVICE_STDIO_MESSAGES
<> 160:d5399cc887bb 36 #include <stdio.h>
<> 160:d5399cc887bb 37 #endif
<> 160:d5399cc887bb 38 #include <errno.h>
<> 160:d5399cc887bb 39 #include "platform/mbed_retarget.h"
<> 160:d5399cc887bb 40
AnnaBridge 175:af195413fb11 41 static SingletonPtr<PlatformMutex> _mutex;
AnnaBridge 175:af195413fb11 42
<> 160:d5399cc887bb 43 #if defined(__ARMCC_VERSION)
AnnaBridge 174:b96e65c34a4d 44 # if __ARMCC_VERSION >= 6010050
AnnaBridge 174:b96e65c34a4d 45 # include <arm_compat.h>
AnnaBridge 174:b96e65c34a4d 46 # endif
<> 160:d5399cc887bb 47 # include <rt_sys.h>
AnnaBridge 174:b96e65c34a4d 48 # include <rt_misc.h>
AnnaBridge 174:b96e65c34a4d 49 # include <stdint.h>
<> 160:d5399cc887bb 50 # define PREFIX(x) _sys##x
<> 160:d5399cc887bb 51 # define OPEN_MAX _SYS_OPEN
<> 160:d5399cc887bb 52 # ifdef __MICROLIB
<> 160:d5399cc887bb 53 # pragma import(__use_full_stdio)
<> 160:d5399cc887bb 54 # endif
<> 160:d5399cc887bb 55
<> 160:d5399cc887bb 56 #elif defined(__ICCARM__)
<> 160:d5399cc887bb 57 # include <yfuns.h>
<> 160:d5399cc887bb 58 # define PREFIX(x) _##x
<> 160:d5399cc887bb 59 # define OPEN_MAX 16
<> 160:d5399cc887bb 60
<> 160:d5399cc887bb 61 # define STDIN_FILENO 0
<> 160:d5399cc887bb 62 # define STDOUT_FILENO 1
<> 160:d5399cc887bb 63 # define STDERR_FILENO 2
<> 160:d5399cc887bb 64
<> 160:d5399cc887bb 65 #else
<> 160:d5399cc887bb 66 # include <sys/syslimits.h>
<> 160:d5399cc887bb 67 # define PREFIX(x) x
<> 160:d5399cc887bb 68 #endif
<> 160:d5399cc887bb 69
<> 160:d5399cc887bb 70 #define FILE_HANDLE_RESERVED 0xFFFFFFFF
<> 160:d5399cc887bb 71
<> 160:d5399cc887bb 72 using namespace mbed;
<> 160:d5399cc887bb 73
<> 160:d5399cc887bb 74 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
<> 160:d5399cc887bb 75 // Before version 5.03, we were using a patched version of microlib with proper names
<> 160:d5399cc887bb 76 extern const char __stdin_name[] = ":tt";
<> 160:d5399cc887bb 77 extern const char __stdout_name[] = ":tt";
<> 160:d5399cc887bb 78 extern const char __stderr_name[] = ":tt";
<> 160:d5399cc887bb 79
<> 160:d5399cc887bb 80 #else
<> 160:d5399cc887bb 81 extern const char __stdin_name[] = "/stdin";
<> 160:d5399cc887bb 82 extern const char __stdout_name[] = "/stdout";
<> 160:d5399cc887bb 83 extern const char __stderr_name[] = "/stderr";
<> 160:d5399cc887bb 84 #endif
<> 160:d5399cc887bb 85
<> 160:d5399cc887bb 86 unsigned char *mbed_heap_start = 0;
<> 160:d5399cc887bb 87 uint32_t mbed_heap_size = 0;
<> 160:d5399cc887bb 88
<> 160:d5399cc887bb 89 /* newlib has the filehandle field in the FILE struct as a short, so
<> 160:d5399cc887bb 90 * we can't just return a Filehandle* from _open and instead have to
<> 160:d5399cc887bb 91 * put it in a filehandles array and return the index into that array
<> 160:d5399cc887bb 92 * (or rather index+3, as filehandles 0-2 are stdin/out/err).
<> 160:d5399cc887bb 93 */
AnnaBridge 167:e84263d55307 94 static FileHandle *filehandles[OPEN_MAX];
<> 160:d5399cc887bb 95 static SingletonPtr<PlatformMutex> filehandle_mutex;
<> 160:d5399cc887bb 96
<> 160:d5399cc887bb 97 namespace mbed {
AnnaBridge 167:e84263d55307 98 void remove_filehandle(FileHandle *file) {
<> 160:d5399cc887bb 99 filehandle_mutex->lock();
<> 160:d5399cc887bb 100 /* Remove all open filehandles for this */
<> 160:d5399cc887bb 101 for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
<> 160:d5399cc887bb 102 if (filehandles[fh_i] == file) {
<> 160:d5399cc887bb 103 filehandles[fh_i] = NULL;
<> 160:d5399cc887bb 104 }
<> 160:d5399cc887bb 105 }
<> 160:d5399cc887bb 106 filehandle_mutex->unlock();
<> 160:d5399cc887bb 107 }
<> 160:d5399cc887bb 108 }
<> 160:d5399cc887bb 109
<> 160:d5399cc887bb 110 #if DEVICE_SERIAL
<> 160:d5399cc887bb 111 extern int stdio_uart_inited;
<> 160:d5399cc887bb 112 extern serial_t stdio_uart;
<> 160:d5399cc887bb 113 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
<> 160:d5399cc887bb 114 static char stdio_in_prev;
<> 160:d5399cc887bb 115 static char stdio_out_prev;
<> 160:d5399cc887bb 116 #endif
<> 160:d5399cc887bb 117 #endif
<> 160:d5399cc887bb 118
<> 160:d5399cc887bb 119 static void init_serial() {
<> 160:d5399cc887bb 120 #if DEVICE_SERIAL
<> 160:d5399cc887bb 121 if (stdio_uart_inited) return;
<> 160:d5399cc887bb 122 serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
<> 160:d5399cc887bb 123 #if MBED_CONF_PLATFORM_STDIO_BAUD_RATE
<> 160:d5399cc887bb 124 serial_baud(&stdio_uart, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
<> 160:d5399cc887bb 125 #endif
<> 160:d5399cc887bb 126 #endif
<> 160:d5399cc887bb 127 }
<> 160:d5399cc887bb 128
AnnaBridge 167:e84263d55307 129 /**
AnnaBridge 167:e84263d55307 130 * Sets errno when file opening fails.
AnnaBridge 167:e84263d55307 131 * Wipes out the filehandle too.
AnnaBridge 167:e84263d55307 132 *
AnnaBridge 167:e84263d55307 133 * @param error is a negative error code returned from an mbed function and
AnnaBridge 167:e84263d55307 134 * will be negated to store a positive error code in errno
AnnaBridge 167:e84263d55307 135 */
AnnaBridge 167:e84263d55307 136 static int handle_open_errors(int error, unsigned filehandle_idx) {
AnnaBridge 167:e84263d55307 137 errno = -error;
AnnaBridge 167:e84263d55307 138 // Free file handle
AnnaBridge 167:e84263d55307 139 filehandles[filehandle_idx] = NULL;
AnnaBridge 167:e84263d55307 140 return -1;
AnnaBridge 167:e84263d55307 141 }
AnnaBridge 167:e84263d55307 142
<> 160:d5399cc887bb 143 static inline int openmode_to_posix(int openmode) {
<> 160:d5399cc887bb 144 int posix = openmode;
<> 160:d5399cc887bb 145 #ifdef __ARMCC_VERSION
<> 160:d5399cc887bb 146 if (openmode & OPEN_PLUS) {
<> 160:d5399cc887bb 147 posix = O_RDWR;
<> 160:d5399cc887bb 148 } else if(openmode & OPEN_W) {
<> 160:d5399cc887bb 149 posix = O_WRONLY;
<> 160:d5399cc887bb 150 } else if(openmode & OPEN_A) {
<> 160:d5399cc887bb 151 posix = O_WRONLY|O_APPEND;
<> 160:d5399cc887bb 152 } else {
<> 160:d5399cc887bb 153 posix = O_RDONLY;
<> 160:d5399cc887bb 154 }
<> 160:d5399cc887bb 155 /* a, w, a+, w+ all create if file does not already exist */
<> 160:d5399cc887bb 156 if (openmode & (OPEN_A|OPEN_W)) {
<> 160:d5399cc887bb 157 posix |= O_CREAT;
<> 160:d5399cc887bb 158 }
<> 160:d5399cc887bb 159 /* w and w+ truncate */
<> 160:d5399cc887bb 160 if (openmode & OPEN_W) {
<> 160:d5399cc887bb 161 posix |= O_TRUNC;
<> 160:d5399cc887bb 162 }
<> 160:d5399cc887bb 163 #elif defined(__ICCARM__)
<> 160:d5399cc887bb 164 switch (openmode & _LLIO_RDWRMASK) {
<> 160:d5399cc887bb 165 case _LLIO_RDONLY: posix = O_RDONLY; break;
<> 160:d5399cc887bb 166 case _LLIO_WRONLY: posix = O_WRONLY; break;
<> 160:d5399cc887bb 167 case _LLIO_RDWR : posix = O_RDWR ; break;
<> 160:d5399cc887bb 168 }
<> 160:d5399cc887bb 169 if (openmode & _LLIO_CREAT ) posix |= O_CREAT;
<> 160:d5399cc887bb 170 if (openmode & _LLIO_APPEND) posix |= O_APPEND;
<> 160:d5399cc887bb 171 if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC;
<> 160:d5399cc887bb 172 #elif defined(TOOLCHAIN_GCC)
<> 160:d5399cc887bb 173 posix &= ~O_BINARY;
<> 160:d5399cc887bb 174 #endif
<> 160:d5399cc887bb 175 return posix;
<> 160:d5399cc887bb 176 }
<> 160:d5399cc887bb 177
<> 160:d5399cc887bb 178 /* @brief standard c library fopen() retargeting function.
<> 160:d5399cc887bb 179 *
<> 160:d5399cc887bb 180 * This function is invoked by the standard c library retargeting to handle fopen()
<> 160:d5399cc887bb 181 *
<> 160:d5399cc887bb 182 * @return
<> 160:d5399cc887bb 183 * On success, a valid FILEHANDLE is returned.
<> 160:d5399cc887bb 184 * On failure, -1 is returned and errno is set to an appropriate value e.g.
AnnaBridge 167:e84263d55307 185 * ENOENT file not found (default errno setting)
<> 160:d5399cc887bb 186 * EMFILE the maximum number of open files was exceeded.
<> 160:d5399cc887bb 187 *
<> 160:d5399cc887bb 188 * */
<> 160:d5399cc887bb 189 extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
<> 160:d5399cc887bb 190 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
AnnaBridge 168:9672193075cf 191 #if !defined(MBED_CONF_RTOS_PRESENT)
AnnaBridge 168:9672193075cf 192 // valid only for mbed 2
AnnaBridge 168:9672193075cf 193 // for ulib, this is invoked after RAM init, prior c++
AnnaBridge 168:9672193075cf 194 // used as hook, as post stack/heap is not active there
AnnaBridge 168:9672193075cf 195 extern void mbed_copy_nvic(void);
AnnaBridge 168:9672193075cf 196 extern void mbed_sdk_init(void);
AnnaBridge 168:9672193075cf 197
AnnaBridge 168:9672193075cf 198 static int mbed_sdk_inited = 0;
AnnaBridge 168:9672193075cf 199 if (!mbed_sdk_inited) {
AnnaBridge 168:9672193075cf 200 mbed_copy_nvic();
AnnaBridge 168:9672193075cf 201 mbed_sdk_init();
AnnaBridge 168:9672193075cf 202 mbed_sdk_inited = 1;
AnnaBridge 168:9672193075cf 203 }
AnnaBridge 168:9672193075cf 204 #endif
<> 160:d5399cc887bb 205 // Before version 5.03, we were using a patched version of microlib with proper names
<> 160:d5399cc887bb 206 // This is the workaround that the microlib author suggested us
<> 160:d5399cc887bb 207 static int n = 0;
<> 160:d5399cc887bb 208 if (!std::strcmp(name, ":tt")) return n++;
<> 160:d5399cc887bb 209 #else
<> 160:d5399cc887bb 210 /* Use the posix convention that stdin,out,err are filehandles 0,1,2.
<> 160:d5399cc887bb 211 */
<> 160:d5399cc887bb 212 if (std::strcmp(name, __stdin_name) == 0) {
<> 160:d5399cc887bb 213 init_serial();
<> 160:d5399cc887bb 214 return 0;
<> 160:d5399cc887bb 215 } else if (std::strcmp(name, __stdout_name) == 0) {
<> 160:d5399cc887bb 216 init_serial();
<> 160:d5399cc887bb 217 return 1;
<> 160:d5399cc887bb 218 } else if (std::strcmp(name, __stderr_name) == 0) {
<> 160:d5399cc887bb 219 init_serial();
<> 160:d5399cc887bb 220 return 2;
<> 160:d5399cc887bb 221 }
<> 160:d5399cc887bb 222 #endif
<> 160:d5399cc887bb 223
<> 160:d5399cc887bb 224 // find the first empty slot in filehandles
<> 160:d5399cc887bb 225 filehandle_mutex->lock();
<> 160:d5399cc887bb 226 unsigned int fh_i;
<> 160:d5399cc887bb 227 for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
<> 160:d5399cc887bb 228 /* Take a next free filehandle slot available. */
<> 160:d5399cc887bb 229 if (filehandles[fh_i] == NULL) break;
<> 160:d5399cc887bb 230 }
<> 160:d5399cc887bb 231 if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) {
<> 160:d5399cc887bb 232 /* Too many file handles have been opened */
<> 160:d5399cc887bb 233 errno = EMFILE;
<> 160:d5399cc887bb 234 filehandle_mutex->unlock();
<> 160:d5399cc887bb 235 return -1;
<> 160:d5399cc887bb 236 }
AnnaBridge 167:e84263d55307 237 filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED;
<> 160:d5399cc887bb 238 filehandle_mutex->unlock();
<> 160:d5399cc887bb 239
AnnaBridge 167:e84263d55307 240 FileHandle *res = NULL;
<> 160:d5399cc887bb 241
AnnaBridge 172:7d866c31b3c5 242 /* FILENAME: ":(pointer)" describes a FileHandle* */
<> 160:d5399cc887bb 243 if (name[0] == ':') {
<> 160:d5399cc887bb 244 void *p;
AnnaBridge 172:7d866c31b3c5 245 memcpy(&p, name + 1, sizeof(p));
AnnaBridge 167:e84263d55307 246 res = (FileHandle*)p;
<> 160:d5399cc887bb 247
<> 160:d5399cc887bb 248 /* FILENAME: "/file_system/file_name" */
<> 160:d5399cc887bb 249 } else {
<> 160:d5399cc887bb 250 FilePath path(name);
<> 160:d5399cc887bb 251
<> 160:d5399cc887bb 252 if (!path.exists()) {
<> 160:d5399cc887bb 253 /* The first part of the filename (between first 2 '/') is not a
<> 160:d5399cc887bb 254 * registered mount point in the namespace.
<> 160:d5399cc887bb 255 */
AnnaBridge 177:d650f5d4c87a 256 return handle_open_errors(-ENODEV, fh_i);
AnnaBridge 167:e84263d55307 257 }
AnnaBridge 167:e84263d55307 258
AnnaBridge 167:e84263d55307 259 if (path.isFile()) {
<> 160:d5399cc887bb 260 res = path.file();
<> 160:d5399cc887bb 261 } else {
AnnaBridge 167:e84263d55307 262 FileSystemHandle *fs = path.fileSystem();
<> 160:d5399cc887bb 263 if (fs == NULL) {
AnnaBridge 177:d650f5d4c87a 264 return handle_open_errors(-ENODEV, fh_i);
<> 160:d5399cc887bb 265 }
<> 160:d5399cc887bb 266 int posix_mode = openmode_to_posix(openmode);
AnnaBridge 167:e84263d55307 267 int err = fs->open(&res, path.fileName(), posix_mode);
AnnaBridge 167:e84263d55307 268 if (err) {
AnnaBridge 167:e84263d55307 269 return handle_open_errors(err, fh_i);
<> 160:d5399cc887bb 270 }
<> 160:d5399cc887bb 271 }
<> 160:d5399cc887bb 272 }
<> 160:d5399cc887bb 273
<> 160:d5399cc887bb 274 filehandles[fh_i] = res;
<> 160:d5399cc887bb 275
<> 160:d5399cc887bb 276 return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err
<> 160:d5399cc887bb 277 }
<> 160:d5399cc887bb 278
<> 160:d5399cc887bb 279 extern "C" int PREFIX(_close)(FILEHANDLE fh) {
<> 160:d5399cc887bb 280 if (fh < 3) return 0;
<> 160:d5399cc887bb 281
AnnaBridge 167:e84263d55307 282 FileHandle* fhc = filehandles[fh-3];
<> 160:d5399cc887bb 283 filehandles[fh-3] = NULL;
AnnaBridge 167:e84263d55307 284 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 285 errno = EBADF;
AnnaBridge 167:e84263d55307 286 return -1;
AnnaBridge 167:e84263d55307 287 }
<> 160:d5399cc887bb 288
<> 160:d5399cc887bb 289 int err = fhc->close();
<> 160:d5399cc887bb 290 if (err < 0) {
<> 160:d5399cc887bb 291 errno = -err;
<> 160:d5399cc887bb 292 return -1;
<> 160:d5399cc887bb 293 } else {
<> 160:d5399cc887bb 294 return 0;
<> 160:d5399cc887bb 295 }
<> 160:d5399cc887bb 296 }
<> 160:d5399cc887bb 297
<> 160:d5399cc887bb 298 #if defined(__ICCARM__)
<> 160:d5399cc887bb 299 extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) {
<> 160:d5399cc887bb 300 #else
<> 160:d5399cc887bb 301 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) {
<> 160:d5399cc887bb 302 #endif
<> 160:d5399cc887bb 303 int n; // n is the number of bytes written
<> 160:d5399cc887bb 304
AnnaBridge 167:e84263d55307 305 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT)
AnnaBridge 167:e84263d55307 306 if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
AnnaBridge 167:e84263d55307 307 error("Error - writing to a file in an ISR or critical section\r\n");
AnnaBridge 167:e84263d55307 308 }
AnnaBridge 167:e84263d55307 309 #endif
AnnaBridge 167:e84263d55307 310
<> 160:d5399cc887bb 311 if (fh < 3) {
<> 160:d5399cc887bb 312 #if DEVICE_SERIAL
<> 160:d5399cc887bb 313 if (!stdio_uart_inited) init_serial();
<> 160:d5399cc887bb 314 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
<> 160:d5399cc887bb 315 for (unsigned int i = 0; i < length; i++) {
<> 160:d5399cc887bb 316 if (buffer[i] == '\n' && stdio_out_prev != '\r') {
<> 160:d5399cc887bb 317 serial_putc(&stdio_uart, '\r');
<> 160:d5399cc887bb 318 }
<> 160:d5399cc887bb 319 serial_putc(&stdio_uart, buffer[i]);
<> 160:d5399cc887bb 320 stdio_out_prev = buffer[i];
<> 160:d5399cc887bb 321 }
<> 160:d5399cc887bb 322 #else
<> 160:d5399cc887bb 323 for (unsigned int i = 0; i < length; i++) {
<> 160:d5399cc887bb 324 serial_putc(&stdio_uart, buffer[i]);
<> 160:d5399cc887bb 325 }
<> 160:d5399cc887bb 326 #endif
<> 160:d5399cc887bb 327 #endif
<> 160:d5399cc887bb 328 n = length;
<> 160:d5399cc887bb 329 } else {
AnnaBridge 167:e84263d55307 330 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 167:e84263d55307 331 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 332 errno = EBADF;
AnnaBridge 167:e84263d55307 333 return -1;
AnnaBridge 167:e84263d55307 334 }
<> 160:d5399cc887bb 335
<> 160:d5399cc887bb 336 n = fhc->write(buffer, length);
<> 160:d5399cc887bb 337 if (n < 0) {
<> 160:d5399cc887bb 338 errno = -n;
<> 160:d5399cc887bb 339 }
<> 160:d5399cc887bb 340 }
<> 160:d5399cc887bb 341 #ifdef __ARMCC_VERSION
<> 160:d5399cc887bb 342 return length-n;
<> 160:d5399cc887bb 343 #else
<> 160:d5399cc887bb 344 return n;
<> 160:d5399cc887bb 345 #endif
<> 160:d5399cc887bb 346 }
<> 160:d5399cc887bb 347
AnnaBridge 174:b96e65c34a4d 348 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
AnnaBridge 174:b96e65c34a4d 349 extern "C" void PREFIX(_exit)(int return_code) {
AnnaBridge 174:b96e65c34a4d 350 while(1) {}
AnnaBridge 174:b96e65c34a4d 351 }
AnnaBridge 174:b96e65c34a4d 352
AnnaBridge 174:b96e65c34a4d 353 extern "C" void _ttywrch(int ch) {
Anna Bridge 180:96ed750bd169 354 #if DEVICE_SERIAL
AnnaBridge 174:b96e65c34a4d 355 serial_putc(&stdio_uart, ch);
Anna Bridge 180:96ed750bd169 356 #endif
AnnaBridge 174:b96e65c34a4d 357 }
AnnaBridge 174:b96e65c34a4d 358 #endif
AnnaBridge 174:b96e65c34a4d 359
<> 160:d5399cc887bb 360 #if defined(__ICCARM__)
<> 160:d5399cc887bb 361 extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) {
<> 160:d5399cc887bb 362 #else
<> 160:d5399cc887bb 363 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) {
<> 160:d5399cc887bb 364 #endif
<> 160:d5399cc887bb 365 int n; // n is the number of bytes read
<> 160:d5399cc887bb 366
AnnaBridge 167:e84263d55307 367 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT)
AnnaBridge 167:e84263d55307 368 if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
AnnaBridge 167:e84263d55307 369 error("Error - reading from a file in an ISR or critical section\r\n");
AnnaBridge 167:e84263d55307 370 }
AnnaBridge 167:e84263d55307 371 #endif
AnnaBridge 167:e84263d55307 372
<> 160:d5399cc887bb 373 if (fh < 3) {
<> 160:d5399cc887bb 374 // only read a character at a time from stdin
<> 160:d5399cc887bb 375 #if DEVICE_SERIAL
<> 160:d5399cc887bb 376 if (!stdio_uart_inited) init_serial();
<> 160:d5399cc887bb 377 #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
<> 160:d5399cc887bb 378 while (true) {
<> 160:d5399cc887bb 379 char c = serial_getc(&stdio_uart);
<> 160:d5399cc887bb 380 if ((c == '\r' && stdio_in_prev != '\n') ||
<> 160:d5399cc887bb 381 (c == '\n' && stdio_in_prev != '\r')) {
<> 160:d5399cc887bb 382 stdio_in_prev = c;
<> 160:d5399cc887bb 383 *buffer = '\n';
<> 160:d5399cc887bb 384 break;
<> 160:d5399cc887bb 385 } else if ((c == '\r' && stdio_in_prev == '\n') ||
<> 160:d5399cc887bb 386 (c == '\n' && stdio_in_prev == '\r')) {
<> 160:d5399cc887bb 387 stdio_in_prev = c;
<> 160:d5399cc887bb 388 // onto next character
<> 160:d5399cc887bb 389 continue;
<> 160:d5399cc887bb 390 } else {
<> 160:d5399cc887bb 391 stdio_in_prev = c;
<> 160:d5399cc887bb 392 *buffer = c;
<> 160:d5399cc887bb 393 break;
<> 160:d5399cc887bb 394 }
<> 160:d5399cc887bb 395 }
<> 160:d5399cc887bb 396 #else
<> 160:d5399cc887bb 397 *buffer = serial_getc(&stdio_uart);
<> 160:d5399cc887bb 398 #endif
<> 160:d5399cc887bb 399 #endif
<> 160:d5399cc887bb 400 n = 1;
<> 160:d5399cc887bb 401 } else {
AnnaBridge 167:e84263d55307 402 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 167:e84263d55307 403 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 404 errno = EBADF;
AnnaBridge 167:e84263d55307 405 return -1;
AnnaBridge 167:e84263d55307 406 }
<> 160:d5399cc887bb 407
<> 160:d5399cc887bb 408 n = fhc->read(buffer, length);
<> 160:d5399cc887bb 409 if (n < 0) {
<> 160:d5399cc887bb 410 errno = -n;
<> 160:d5399cc887bb 411 }
<> 160:d5399cc887bb 412 }
<> 160:d5399cc887bb 413 #ifdef __ARMCC_VERSION
<> 160:d5399cc887bb 414 return length-n;
<> 160:d5399cc887bb 415 #else
<> 160:d5399cc887bb 416 return n;
<> 160:d5399cc887bb 417 #endif
<> 160:d5399cc887bb 418 }
<> 160:d5399cc887bb 419
AnnaBridge 167:e84263d55307 420
<> 160:d5399cc887bb 421 #ifdef __ARMCC_VERSION
<> 160:d5399cc887bb 422 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
<> 160:d5399cc887bb 423 #else
<> 160:d5399cc887bb 424 extern "C" int _isatty(FILEHANDLE fh)
<> 160:d5399cc887bb 425 #endif
<> 160:d5399cc887bb 426 {
<> 160:d5399cc887bb 427 /* stdin, stdout and stderr should be tty */
<> 160:d5399cc887bb 428 if (fh < 3) return 1;
<> 160:d5399cc887bb 429
AnnaBridge 167:e84263d55307 430 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 167:e84263d55307 431 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 432 errno = EBADF;
AnnaBridge 167:e84263d55307 433 return 0;
AnnaBridge 167:e84263d55307 434 }
<> 160:d5399cc887bb 435
AnnaBridge 167:e84263d55307 436 int tty = fhc->isatty();
AnnaBridge 167:e84263d55307 437 if (tty < 0) {
AnnaBridge 167:e84263d55307 438 errno = -tty;
AnnaBridge 167:e84263d55307 439 return 0;
<> 160:d5399cc887bb 440 } else {
AnnaBridge 167:e84263d55307 441 return tty;
<> 160:d5399cc887bb 442 }
<> 160:d5399cc887bb 443 }
<> 160:d5399cc887bb 444
<> 160:d5399cc887bb 445 extern "C"
<> 160:d5399cc887bb 446 #if defined(__ARMCC_VERSION)
AnnaBridge 167:e84263d55307 447 int _sys_seek(FILEHANDLE fh, long offset)
<> 160:d5399cc887bb 448 #elif defined(__ICCARM__)
<> 160:d5399cc887bb 449 long __lseek(int fh, long offset, int whence)
<> 160:d5399cc887bb 450 #else
<> 160:d5399cc887bb 451 int _lseek(FILEHANDLE fh, int offset, int whence)
<> 160:d5399cc887bb 452 #endif
<> 160:d5399cc887bb 453 {
AnnaBridge 167:e84263d55307 454 #if defined(__ARMCC_VERSION)
AnnaBridge 167:e84263d55307 455 int whence = SEEK_SET;
AnnaBridge 167:e84263d55307 456 #endif
AnnaBridge 175:af195413fb11 457
AnnaBridge 167:e84263d55307 458 if (fh < 3) {
AnnaBridge 167:e84263d55307 459 errno = ESPIPE;
AnnaBridge 167:e84263d55307 460 return -1;
AnnaBridge 167:e84263d55307 461 }
<> 160:d5399cc887bb 462
AnnaBridge 167:e84263d55307 463 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 167:e84263d55307 464 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 465 errno = EBADF;
AnnaBridge 167:e84263d55307 466 return -1;
AnnaBridge 167:e84263d55307 467 }
AnnaBridge 167:e84263d55307 468
AnnaBridge 167:e84263d55307 469 off_t off = fhc->seek(offset, whence);
AnnaBridge 167:e84263d55307 470 if (off < 0) {
AnnaBridge 167:e84263d55307 471 errno = -off;
AnnaBridge 167:e84263d55307 472 return -1;
AnnaBridge 167:e84263d55307 473 }
AnnaBridge 167:e84263d55307 474 // Assuming INT_MAX = LONG_MAX, so we don't care about prototype difference
AnnaBridge 167:e84263d55307 475 if (off > INT_MAX) {
AnnaBridge 167:e84263d55307 476 errno = EOVERFLOW;
AnnaBridge 167:e84263d55307 477 return -1;
AnnaBridge 167:e84263d55307 478 }
AnnaBridge 167:e84263d55307 479 return off;
<> 160:d5399cc887bb 480 }
<> 160:d5399cc887bb 481
<> 160:d5399cc887bb 482 #ifdef __ARMCC_VERSION
<> 160:d5399cc887bb 483 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
<> 160:d5399cc887bb 484 if (fh < 3) return 0;
<> 160:d5399cc887bb 485
AnnaBridge 167:e84263d55307 486 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 167:e84263d55307 487 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 488 errno = EBADF;
AnnaBridge 167:e84263d55307 489 return -1;
AnnaBridge 167:e84263d55307 490 }
<> 160:d5399cc887bb 491
<> 160:d5399cc887bb 492 int err = fhc->sync();
<> 160:d5399cc887bb 493 if (err < 0) {
<> 160:d5399cc887bb 494 errno = -err;
<> 160:d5399cc887bb 495 return -1;
<> 160:d5399cc887bb 496 } else {
<> 160:d5399cc887bb 497 return 0;
<> 160:d5399cc887bb 498 }
<> 160:d5399cc887bb 499 }
<> 160:d5399cc887bb 500
<> 160:d5399cc887bb 501 extern "C" long PREFIX(_flen)(FILEHANDLE fh) {
AnnaBridge 167:e84263d55307 502 if (fh < 3) {
AnnaBridge 167:e84263d55307 503 errno = EINVAL;
AnnaBridge 167:e84263d55307 504 return -1;
AnnaBridge 167:e84263d55307 505 }
AnnaBridge 167:e84263d55307 506
AnnaBridge 167:e84263d55307 507 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 167:e84263d55307 508 if (fhc == NULL) {
AnnaBridge 167:e84263d55307 509 errno = EBADF;
AnnaBridge 167:e84263d55307 510 return -1;
AnnaBridge 167:e84263d55307 511 }
<> 160:d5399cc887bb 512
AnnaBridge 167:e84263d55307 513 off_t size = fhc->size();
AnnaBridge 167:e84263d55307 514 if (size < 0) {
AnnaBridge 167:e84263d55307 515 errno = -size;
AnnaBridge 167:e84263d55307 516 return -1;
AnnaBridge 167:e84263d55307 517 }
AnnaBridge 167:e84263d55307 518 if (size > LONG_MAX) {
AnnaBridge 167:e84263d55307 519 errno = EOVERFLOW;
AnnaBridge 167:e84263d55307 520 return -1;
AnnaBridge 167:e84263d55307 521 }
AnnaBridge 167:e84263d55307 522 return size;
<> 160:d5399cc887bb 523 }
AnnaBridge 174:b96e65c34a4d 524
AnnaBridge 174:b96e65c34a4d 525 extern "C" char Image$$RW_IRAM1$$ZI$$Limit[];
AnnaBridge 174:b96e65c34a4d 526
AnnaBridge 174:b96e65c34a4d 527 extern "C" MBED_WEAK __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
AnnaBridge 174:b96e65c34a4d 528 {
AnnaBridge 174:b96e65c34a4d 529 uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
AnnaBridge 174:b96e65c34a4d 530 uint32_t sp_limit = __current_sp();
AnnaBridge 174:b96e65c34a4d 531
AnnaBridge 174:b96e65c34a4d 532 zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
AnnaBridge 174:b96e65c34a4d 533
AnnaBridge 174:b96e65c34a4d 534 struct __initial_stackheap r;
AnnaBridge 174:b96e65c34a4d 535 r.heap_base = zi_limit;
AnnaBridge 174:b96e65c34a4d 536 r.heap_limit = sp_limit;
AnnaBridge 174:b96e65c34a4d 537 return r;
AnnaBridge 174:b96e65c34a4d 538 }
AnnaBridge 174:b96e65c34a4d 539
AnnaBridge 174:b96e65c34a4d 540 extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
AnnaBridge 174:b96e65c34a4d 541 return _mbed_user_setup_stackheap(R0, R1, R2, R3);
AnnaBridge 174:b96e65c34a4d 542 }
AnnaBridge 174:b96e65c34a4d 543
<> 160:d5399cc887bb 544 #endif
<> 160:d5399cc887bb 545
<> 160:d5399cc887bb 546
<> 160:d5399cc887bb 547 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
AnnaBridge 175:af195413fb11 548 extern "C" int _fstat(int fh, struct stat *st) {
AnnaBridge 175:af195413fb11 549 if (fh < 3) {
<> 160:d5399cc887bb 550 st->st_mode = S_IFCHR;
<> 160:d5399cc887bb 551 return 0;
<> 160:d5399cc887bb 552 }
AnnaBridge 175:af195413fb11 553
AnnaBridge 175:af195413fb11 554 FileHandle* fhc = filehandles[fh-3];
AnnaBridge 175:af195413fb11 555 if (fhc == NULL) {
AnnaBridge 175:af195413fb11 556 errno = EBADF;
AnnaBridge 175:af195413fb11 557 return -1;
AnnaBridge 175:af195413fb11 558 }
AnnaBridge 175:af195413fb11 559
AnnaBridge 175:af195413fb11 560 st->st_mode = fhc->isatty() ? S_IFCHR : S_IFREG;
AnnaBridge 175:af195413fb11 561 st->st_size = fhc->size();
AnnaBridge 175:af195413fb11 562 return 0;
<> 160:d5399cc887bb 563 }
<> 160:d5399cc887bb 564 #endif
<> 160:d5399cc887bb 565
<> 160:d5399cc887bb 566 namespace std {
<> 160:d5399cc887bb 567 extern "C" int remove(const char *path) {
<> 160:d5399cc887bb 568 FilePath fp(path);
AnnaBridge 167:e84263d55307 569 FileSystemHandle *fs = fp.fileSystem();
AnnaBridge 167:e84263d55307 570 if (fs == NULL) {
AnnaBridge 177:d650f5d4c87a 571 errno = ENODEV;
AnnaBridge 167:e84263d55307 572 return -1;
AnnaBridge 167:e84263d55307 573 }
<> 160:d5399cc887bb 574
<> 160:d5399cc887bb 575 int err = fs->remove(fp.fileName());
<> 160:d5399cc887bb 576 if (err < 0) {
<> 160:d5399cc887bb 577 errno = -err;
<> 160:d5399cc887bb 578 return -1;
<> 160:d5399cc887bb 579 } else {
<> 160:d5399cc887bb 580 return 0;
<> 160:d5399cc887bb 581 }
<> 160:d5399cc887bb 582 }
<> 160:d5399cc887bb 583
<> 160:d5399cc887bb 584 extern "C" int rename(const char *oldname, const char *newname) {
<> 160:d5399cc887bb 585 FilePath fpOld(oldname);
<> 160:d5399cc887bb 586 FilePath fpNew(newname);
AnnaBridge 167:e84263d55307 587 FileSystemHandle *fsOld = fpOld.fileSystem();
AnnaBridge 167:e84263d55307 588 FileSystemHandle *fsNew = fpNew.fileSystem();
AnnaBridge 167:e84263d55307 589
AnnaBridge 167:e84263d55307 590 if (fsOld == NULL) {
AnnaBridge 177:d650f5d4c87a 591 errno = ENODEV;
AnnaBridge 167:e84263d55307 592 return -1;
AnnaBridge 167:e84263d55307 593 }
<> 160:d5399cc887bb 594
<> 160:d5399cc887bb 595 /* rename only if both files are on the same FS */
AnnaBridge 167:e84263d55307 596 if (fsOld != fsNew) {
AnnaBridge 167:e84263d55307 597 errno = EXDEV;
AnnaBridge 167:e84263d55307 598 return -1;
AnnaBridge 167:e84263d55307 599 }
<> 160:d5399cc887bb 600
<> 160:d5399cc887bb 601 int err = fsOld->rename(fpOld.fileName(), fpNew.fileName());
<> 160:d5399cc887bb 602 if (err < 0) {
<> 160:d5399cc887bb 603 errno = -err;
<> 160:d5399cc887bb 604 return -1;
<> 160:d5399cc887bb 605 } else {
<> 160:d5399cc887bb 606 return 0;
<> 160:d5399cc887bb 607 }
<> 160:d5399cc887bb 608 }
<> 160:d5399cc887bb 609
<> 160:d5399cc887bb 610 extern "C" char *tmpnam(char *s) {
<> 160:d5399cc887bb 611 errno = EBADF;
<> 160:d5399cc887bb 612 return NULL;
<> 160:d5399cc887bb 613 }
<> 160:d5399cc887bb 614
<> 160:d5399cc887bb 615 extern "C" FILE *tmpfile() {
<> 160:d5399cc887bb 616 errno = EBADF;
<> 160:d5399cc887bb 617 return NULL;
<> 160:d5399cc887bb 618 }
<> 160:d5399cc887bb 619 } // namespace std
<> 160:d5399cc887bb 620
<> 160:d5399cc887bb 621 #ifdef __ARMCC_VERSION
<> 160:d5399cc887bb 622 extern "C" char *_sys_command_string(char *cmd, int len) {
<> 160:d5399cc887bb 623 return NULL;
<> 160:d5399cc887bb 624 }
<> 160:d5399cc887bb 625 #endif
<> 160:d5399cc887bb 626
<> 160:d5399cc887bb 627 extern "C" DIR *opendir(const char *path) {
AnnaBridge 167:e84263d55307 628 FilePath fp(path);
AnnaBridge 167:e84263d55307 629 FileSystemHandle* fs = fp.fileSystem();
AnnaBridge 167:e84263d55307 630 if (fs == NULL) {
AnnaBridge 177:d650f5d4c87a 631 errno = ENODEV;
AnnaBridge 167:e84263d55307 632 return NULL;
AnnaBridge 167:e84263d55307 633 }
<> 160:d5399cc887bb 634
AnnaBridge 167:e84263d55307 635 DirHandle *dir;
AnnaBridge 167:e84263d55307 636 int err = fs->open(&dir, fp.fileName());
<> 160:d5399cc887bb 637 if (err < 0) {
<> 160:d5399cc887bb 638 errno = -err;
AnnaBridge 167:e84263d55307 639 return NULL;
<> 160:d5399cc887bb 640 }
<> 160:d5399cc887bb 641
<> 160:d5399cc887bb 642 return dir;
<> 160:d5399cc887bb 643 }
<> 160:d5399cc887bb 644
<> 160:d5399cc887bb 645 extern "C" struct dirent *readdir(DIR *dir) {
<> 160:d5399cc887bb 646 static struct dirent ent;
<> 160:d5399cc887bb 647 int err = dir->read(&ent);
<> 160:d5399cc887bb 648 if (err < 1) {
<> 160:d5399cc887bb 649 if (err < 0) {
<> 160:d5399cc887bb 650 errno = -err;
<> 160:d5399cc887bb 651 }
<> 160:d5399cc887bb 652 return NULL;
<> 160:d5399cc887bb 653 }
<> 160:d5399cc887bb 654
<> 160:d5399cc887bb 655 return &ent;
<> 160:d5399cc887bb 656 }
<> 160:d5399cc887bb 657
<> 160:d5399cc887bb 658 extern "C" int closedir(DIR *dir) {
<> 160:d5399cc887bb 659 int err = dir->close();
<> 160:d5399cc887bb 660 if (err < 0) {
<> 160:d5399cc887bb 661 errno = -err;
<> 160:d5399cc887bb 662 return -1;
<> 160:d5399cc887bb 663 } else {
<> 160:d5399cc887bb 664 return 0;
<> 160:d5399cc887bb 665 }
<> 160:d5399cc887bb 666 }
<> 160:d5399cc887bb 667
<> 160:d5399cc887bb 668 extern "C" void rewinddir(DIR *dir) {
<> 160:d5399cc887bb 669 dir->rewind();
<> 160:d5399cc887bb 670 }
<> 160:d5399cc887bb 671
<> 160:d5399cc887bb 672 extern "C" off_t telldir(DIR *dir) {
<> 160:d5399cc887bb 673 return dir->tell();
<> 160:d5399cc887bb 674 }
<> 160:d5399cc887bb 675
<> 160:d5399cc887bb 676 extern "C" void seekdir(DIR *dir, off_t off) {
<> 160:d5399cc887bb 677 dir->seek(off);
<> 160:d5399cc887bb 678 }
<> 160:d5399cc887bb 679
<> 160:d5399cc887bb 680 extern "C" int mkdir(const char *path, mode_t mode) {
<> 160:d5399cc887bb 681 FilePath fp(path);
AnnaBridge 167:e84263d55307 682 FileSystemHandle *fs = fp.fileSystem();
AnnaBridge 177:d650f5d4c87a 683 if (fs == NULL) {
AnnaBridge 177:d650f5d4c87a 684 errno = ENODEV;
AnnaBridge 177:d650f5d4c87a 685 return -1;
AnnaBridge 177:d650f5d4c87a 686 }
<> 160:d5399cc887bb 687
<> 160:d5399cc887bb 688 int err = fs->mkdir(fp.fileName(), mode);
<> 160:d5399cc887bb 689 if (err < 0) {
<> 160:d5399cc887bb 690 errno = -err;
<> 160:d5399cc887bb 691 return -1;
<> 160:d5399cc887bb 692 } else {
<> 160:d5399cc887bb 693 return 0;
<> 160:d5399cc887bb 694 }
<> 160:d5399cc887bb 695 }
<> 160:d5399cc887bb 696
<> 160:d5399cc887bb 697 extern "C" int stat(const char *path, struct stat *st) {
<> 160:d5399cc887bb 698 FilePath fp(path);
AnnaBridge 167:e84263d55307 699 FileSystemHandle *fs = fp.fileSystem();
AnnaBridge 177:d650f5d4c87a 700 if (fs == NULL) {
AnnaBridge 177:d650f5d4c87a 701 errno = ENODEV;
AnnaBridge 177:d650f5d4c87a 702 return -1;
AnnaBridge 177:d650f5d4c87a 703 }
<> 160:d5399cc887bb 704
<> 160:d5399cc887bb 705 int err = fs->stat(fp.fileName(), st);
<> 160:d5399cc887bb 706 if (err < 0) {
<> 160:d5399cc887bb 707 errno = -err;
<> 160:d5399cc887bb 708 return -1;
<> 160:d5399cc887bb 709 } else {
<> 160:d5399cc887bb 710 return 0;
<> 160:d5399cc887bb 711 }
<> 160:d5399cc887bb 712 }
<> 160:d5399cc887bb 713
<> 160:d5399cc887bb 714 #if defined(TOOLCHAIN_GCC)
<> 160:d5399cc887bb 715 /* prevents the exception handling name demangling code getting pulled in */
<> 160:d5399cc887bb 716 #include "mbed_error.h"
<> 160:d5399cc887bb 717 namespace __gnu_cxx {
<> 160:d5399cc887bb 718 void __verbose_terminate_handler() {
<> 160:d5399cc887bb 719 error("Exception");
<> 160:d5399cc887bb 720 }
<> 160:d5399cc887bb 721 }
<> 160:d5399cc887bb 722 extern "C" WEAK void __cxa_pure_virtual(void);
<> 160:d5399cc887bb 723 extern "C" WEAK void __cxa_pure_virtual(void) {
<> 160:d5399cc887bb 724 exit(1);
<> 160:d5399cc887bb 725 }
<> 160:d5399cc887bb 726
<> 160:d5399cc887bb 727 #endif
<> 160:d5399cc887bb 728
<> 160:d5399cc887bb 729 // Provide implementation of _sbrk (low-level dynamic memory allocation
<> 160:d5399cc887bb 730 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
<> 160:d5399cc887bb 731 // SP. This make it compatible with RTX RTOS thread stacks.
<> 160:d5399cc887bb 732 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
<> 160:d5399cc887bb 733
<> 160:d5399cc887bb 734 #if defined(TARGET_CORTEX_A)
<> 160:d5399cc887bb 735 extern "C" uint32_t __HeapLimit;
<> 160:d5399cc887bb 736 #endif
<> 160:d5399cc887bb 737
<> 160:d5399cc887bb 738 // Turn off the errno macro and use actual global variable instead.
<> 160:d5399cc887bb 739 #undef errno
<> 160:d5399cc887bb 740 extern "C" int errno;
<> 160:d5399cc887bb 741
<> 160:d5399cc887bb 742 // Dynamic memory allocation related syscall.
AnnaBridge 172:7d866c31b3c5 743 #if defined(TARGET_NUVOTON)
Anna Bridge 180:96ed750bd169 744
<> 160:d5399cc887bb 745 // Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
<> 160:d5399cc887bb 746 // __wrap__sbrk() is implemented in:
AnnaBridge 172:7d866c31b3c5 747 // TARGET_NUMAKER_PFM_NUC472 targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/nuc472_retarget.c
AnnaBridge 172:7d866c31b3c5 748 // TARGET_NUMAKER_PFM_M453 targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/m451_retarget.c
<> 160:d5399cc887bb 749 extern "C" void *__wrap__sbrk(int incr);
<> 160:d5399cc887bb 750 extern "C" caddr_t _sbrk(int incr) {
<> 160:d5399cc887bb 751 return (caddr_t) __wrap__sbrk(incr);
<> 160:d5399cc887bb 752 }
<> 160:d5399cc887bb 753 #else
AnnaBridge 167:e84263d55307 754 // Linker defined symbol used by _sbrk to indicate where heap should start.
AnnaBridge 167:e84263d55307 755 extern "C" uint32_t __end__;
<> 160:d5399cc887bb 756 extern "C" caddr_t _sbrk(int incr) {
<> 160:d5399cc887bb 757 static unsigned char* heap = (unsigned char*)&__end__;
<> 160:d5399cc887bb 758 unsigned char* prev_heap = heap;
<> 160:d5399cc887bb 759 unsigned char* new_heap = heap + incr;
<> 160:d5399cc887bb 760
AnnaBridge 167:e84263d55307 761 #if defined(TARGET_CORTEX_A)
<> 160:d5399cc887bb 762 if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */
<> 160:d5399cc887bb 763 #else
<> 160:d5399cc887bb 764 if (new_heap >= (unsigned char*)__get_MSP()) {
<> 160:d5399cc887bb 765 #endif
<> 160:d5399cc887bb 766 errno = ENOMEM;
<> 160:d5399cc887bb 767 return (caddr_t)-1;
<> 160:d5399cc887bb 768 }
<> 160:d5399cc887bb 769
<> 160:d5399cc887bb 770 // Additional heap checking if set
<> 160:d5399cc887bb 771 if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) {
<> 160:d5399cc887bb 772 errno = ENOMEM;
<> 160:d5399cc887bb 773 return (caddr_t)-1;
<> 160:d5399cc887bb 774 }
<> 160:d5399cc887bb 775
<> 160:d5399cc887bb 776 heap = new_heap;
<> 160:d5399cc887bb 777 return (caddr_t) prev_heap;
<> 160:d5399cc887bb 778 }
<> 160:d5399cc887bb 779 #endif
<> 160:d5399cc887bb 780 #endif
<> 160:d5399cc887bb 781
<> 160:d5399cc887bb 782 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
<> 160:d5399cc887bb 783 extern "C" void _exit(int return_code) {
<> 160:d5399cc887bb 784 #else
<> 160:d5399cc887bb 785 namespace std {
<> 160:d5399cc887bb 786 extern "C" void exit(int return_code) {
<> 160:d5399cc887bb 787 #endif
<> 160:d5399cc887bb 788
<> 160:d5399cc887bb 789 #if DEVICE_STDIO_MESSAGES
<> 160:d5399cc887bb 790 #if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
<> 160:d5399cc887bb 791 fflush(stdout);
<> 160:d5399cc887bb 792 fflush(stderr);
<> 160:d5399cc887bb 793 #endif
<> 160:d5399cc887bb 794 #endif
<> 160:d5399cc887bb 795
<> 160:d5399cc887bb 796 #if DEVICE_SEMIHOST
<> 160:d5399cc887bb 797 if (mbed_interface_connected()) {
<> 160:d5399cc887bb 798 semihost_exit();
<> 160:d5399cc887bb 799 }
<> 160:d5399cc887bb 800 #endif
<> 160:d5399cc887bb 801 if (return_code) {
<> 160:d5399cc887bb 802 mbed_die();
<> 160:d5399cc887bb 803 }
<> 160:d5399cc887bb 804
<> 160:d5399cc887bb 805 while (1);
<> 160:d5399cc887bb 806 }
<> 160:d5399cc887bb 807
<> 160:d5399cc887bb 808 #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR)
<> 160:d5399cc887bb 809 } //namespace std
<> 160:d5399cc887bb 810 #endif
<> 160:d5399cc887bb 811
<> 160:d5399cc887bb 812 #if defined(TOOLCHAIN_ARM) || defined(TOOLCHAIN_GCC)
<> 160:d5399cc887bb 813
<> 160:d5399cc887bb 814 // This series of function disable the registration of global destructors
<> 160:d5399cc887bb 815 // in a dynamic table which will be called when the application exit.
<> 160:d5399cc887bb 816 // In mbed, program never exit properly, it dies.
<> 160:d5399cc887bb 817 // More informations about this topic for ARMCC here:
<> 160:d5399cc887bb 818 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/6449.html
<> 160:d5399cc887bb 819 extern "C" {
<> 160:d5399cc887bb 820 int __aeabi_atexit(void *object, void (*dtor)(void* /*this*/), void *handle) {
<> 160:d5399cc887bb 821 return 1;
<> 160:d5399cc887bb 822 }
<> 160:d5399cc887bb 823
<> 160:d5399cc887bb 824 int __cxa_atexit(void (*dtor)(void* /*this*/), void *object, void *handle) {
<> 160:d5399cc887bb 825 return 1;
<> 160:d5399cc887bb 826 }
<> 160:d5399cc887bb 827
<> 160:d5399cc887bb 828 void __cxa_finalize(void *handle) {
<> 160:d5399cc887bb 829 }
<> 160:d5399cc887bb 830
<> 160:d5399cc887bb 831 } // end of extern "C"
<> 160:d5399cc887bb 832
<> 160:d5399cc887bb 833 #endif
<> 160:d5399cc887bb 834
<> 160:d5399cc887bb 835
<> 160:d5399cc887bb 836 #if defined(TOOLCHAIN_GCC)
<> 160:d5399cc887bb 837
<> 160:d5399cc887bb 838 /*
<> 160:d5399cc887bb 839 * Depending on how newlib is configured, it is often not enough to define
<> 160:d5399cc887bb 840 * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the
<> 160:d5399cc887bb 841 * behavior regarding the registration of handlers with atexit.
<> 160:d5399cc887bb 842 *
<> 160:d5399cc887bb 843 * To overcome this limitation, exit and atexit are overriden here.
<> 160:d5399cc887bb 844 */
<> 160:d5399cc887bb 845 extern "C"{
<> 160:d5399cc887bb 846
<> 160:d5399cc887bb 847 /**
<> 160:d5399cc887bb 848 * @brief Retarget of exit for GCC.
<> 160:d5399cc887bb 849 * @details Unlike the standard version, this function doesn't call any function
<> 160:d5399cc887bb 850 * registered with atexit before calling _exit.
<> 160:d5399cc887bb 851 */
<> 160:d5399cc887bb 852 void __wrap_exit(int return_code) {
<> 160:d5399cc887bb 853 _exit(return_code);
<> 160:d5399cc887bb 854 }
<> 160:d5399cc887bb 855
<> 160:d5399cc887bb 856 /**
<> 160:d5399cc887bb 857 * @brief Retarget atexit from GCC.
<> 160:d5399cc887bb 858 * @details This function will always fail and never register any handler to be
<> 160:d5399cc887bb 859 * called at exit.
<> 160:d5399cc887bb 860 */
<> 160:d5399cc887bb 861 int __wrap_atexit(void (*func)()) {
<> 160:d5399cc887bb 862 return 1;
<> 160:d5399cc887bb 863 }
<> 160:d5399cc887bb 864
<> 160:d5399cc887bb 865 }
<> 160:d5399cc887bb 866
<> 160:d5399cc887bb 867 #endif
<> 160:d5399cc887bb 868
<> 160:d5399cc887bb 869
<> 160:d5399cc887bb 870
<> 160:d5399cc887bb 871 namespace mbed {
<> 160:d5399cc887bb 872
AnnaBridge 167:e84263d55307 873 void mbed_set_unbuffered_stream(std::FILE *_file) {
<> 160:d5399cc887bb 874 #if defined (__ICCARM__)
<> 160:d5399cc887bb 875 char buf[2];
AnnaBridge 167:e84263d55307 876 std::setvbuf(_file,buf,_IONBF,NULL);
<> 160:d5399cc887bb 877 #else
<> 160:d5399cc887bb 878 setbuf(_file, NULL);
<> 160:d5399cc887bb 879 #endif
<> 160:d5399cc887bb 880 }
<> 160:d5399cc887bb 881
AnnaBridge 167:e84263d55307 882 /* Applications are expected to use fdopen()
AnnaBridge 167:e84263d55307 883 * not this function directly. This code had to live here because FILE and FileHandle
AnnaBridge 167:e84263d55307 884 * processes are all linked together here.
AnnaBridge 167:e84263d55307 885 */
AnnaBridge 167:e84263d55307 886 std::FILE *mbed_fdopen(FileHandle *fh, const char *mode)
AnnaBridge 167:e84263d55307 887 {
AnnaBridge 172:7d866c31b3c5 888 // This is to avoid scanf(buf, ":%.4s", fh) and the bloat it brings.
AnnaBridge 172:7d866c31b3c5 889 char buf[1 + sizeof(fh)]; /* :(pointer) */
AnnaBridge 172:7d866c31b3c5 890 MBED_STATIC_ASSERT(sizeof(buf) == 5, "Pointers should be 4 bytes.");
AnnaBridge 172:7d866c31b3c5 891 buf[0] = ':';
AnnaBridge 172:7d866c31b3c5 892 memcpy(buf + 1, &fh, sizeof(fh));
AnnaBridge 172:7d866c31b3c5 893
AnnaBridge 167:e84263d55307 894 std::FILE *stream = std::fopen(buf, mode);
AnnaBridge 167:e84263d55307 895 /* newlib-nano doesn't appear to ever call _isatty itself, so
AnnaBridge 167:e84263d55307 896 * happily fully buffers an interactive stream. Deal with that here.
AnnaBridge 167:e84263d55307 897 */
AnnaBridge 167:e84263d55307 898 if (stream && fh->isatty()) {
AnnaBridge 167:e84263d55307 899 mbed_set_unbuffered_stream(stream);
AnnaBridge 167:e84263d55307 900 }
AnnaBridge 167:e84263d55307 901 return stream;
AnnaBridge 167:e84263d55307 902 }
AnnaBridge 167:e84263d55307 903
AnnaBridge 167:e84263d55307 904 int mbed_getc(std::FILE *_file){
AnnaBridge 174:b96e65c34a4d 905 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ < 8000000)
<> 160:d5399cc887bb 906 /*This is only valid for unbuffered streams*/
<> 160:d5399cc887bb 907 int res = std::fgetc(_file);
<> 160:d5399cc887bb 908 if (res>=0){
<> 160:d5399cc887bb 909 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
<> 160:d5399cc887bb 910 _file->_Rend = _file->_Wend;
<> 160:d5399cc887bb 911 _file->_Next = _file->_Wend;
AnnaBridge 167:e84263d55307 912 }
<> 160:d5399cc887bb 913 return res;
AnnaBridge 167:e84263d55307 914 #else
<> 160:d5399cc887bb 915 return std::fgetc(_file);
AnnaBridge 167:e84263d55307 916 #endif
<> 160:d5399cc887bb 917 }
<> 160:d5399cc887bb 918
AnnaBridge 167:e84263d55307 919 char* mbed_gets(char*s, int size, std::FILE *_file){
AnnaBridge 174:b96e65c34a4d 920 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ < 8000000)
<> 160:d5399cc887bb 921 /*This is only valid for unbuffered streams*/
<> 160:d5399cc887bb 922 char *str = fgets(s,size,_file);
<> 160:d5399cc887bb 923 if (str!=NULL){
<> 160:d5399cc887bb 924 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
<> 160:d5399cc887bb 925 _file->_Rend = _file->_Wend;
<> 160:d5399cc887bb 926 _file->_Next = _file->_Wend;
<> 160:d5399cc887bb 927 }
<> 160:d5399cc887bb 928 return str;
AnnaBridge 167:e84263d55307 929 #else
<> 160:d5399cc887bb 930 return std::fgets(s,size,_file);
<> 160:d5399cc887bb 931 #endif
<> 160:d5399cc887bb 932 }
<> 160:d5399cc887bb 933
<> 160:d5399cc887bb 934 } // namespace mbed
<> 160:d5399cc887bb 935
<> 160:d5399cc887bb 936 #if defined (__ICCARM__)
<> 160:d5399cc887bb 937 // Stub out locks when an rtos is not present
<> 160:d5399cc887bb 938 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 939 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 940 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 941 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 942 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 943 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 944 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {}
<> 160:d5399cc887bb 945 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {}
AnnaBridge 174:b96e65c34a4d 946 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000)
AnnaBridge 179:b0033dcd6934 947 #pragma section="__iar_tls$$DATA"
AnnaBridge 179:b0033dcd6934 948 extern "C" WEAK void *__aeabi_read_tp (void) {
AnnaBridge 179:b0033dcd6934 949 // Thread Local storage is not supported, using main thread memory for errno
AnnaBridge 179:b0033dcd6934 950 return __section_begin("__iar_tls$$DATA");
AnnaBridge 179:b0033dcd6934 951 }
AnnaBridge 174:b96e65c34a4d 952 #endif
<> 160:d5399cc887bb 953 #elif defined(__CC_ARM)
<> 160:d5399cc887bb 954 // Do nothing
<> 160:d5399cc887bb 955 #elif defined (__GNUC__)
<> 160:d5399cc887bb 956 struct _reent;
<> 160:d5399cc887bb 957 // Stub out locks when an rtos is not present
<> 160:d5399cc887bb 958 extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {}
<> 160:d5399cc887bb 959 extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {}
<> 160:d5399cc887bb 960 extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {}
<> 160:d5399cc887bb 961 extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {}
<> 160:d5399cc887bb 962
<> 160:d5399cc887bb 963 extern "C" void __malloc_lock( struct _reent *_r )
<> 160:d5399cc887bb 964 {
<> 160:d5399cc887bb 965 __rtos_malloc_lock(_r);
<> 160:d5399cc887bb 966 }
<> 160:d5399cc887bb 967
<> 160:d5399cc887bb 968 extern "C" void __malloc_unlock( struct _reent *_r )
<> 160:d5399cc887bb 969 {
<> 160:d5399cc887bb 970 __rtos_malloc_unlock(_r);
<> 160:d5399cc887bb 971 }
<> 160:d5399cc887bb 972
<> 160:d5399cc887bb 973 extern "C" void __env_lock( struct _reent *_r )
<> 160:d5399cc887bb 974 {
<> 160:d5399cc887bb 975 __rtos_env_lock(_r);
<> 160:d5399cc887bb 976 }
<> 160:d5399cc887bb 977
<> 160:d5399cc887bb 978 extern "C" void __env_unlock( struct _reent *_r )
<> 160:d5399cc887bb 979 {
<> 160:d5399cc887bb 980 __rtos_env_unlock(_r);
<> 160:d5399cc887bb 981 }
<> 160:d5399cc887bb 982
Anna Bridge 180:96ed750bd169 983 #endif
Anna Bridge 180:96ed750bd169 984
Anna Bridge 180:96ed750bd169 985 #if defined (__GNUC__) || defined(__CC_ARM) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
Anna Bridge 180:96ed750bd169 986
<> 160:d5399cc887bb 987 #define CXA_GUARD_INIT_DONE (1 << 0)
<> 160:d5399cc887bb 988 #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1)
<> 160:d5399cc887bb 989 #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS)
<> 160:d5399cc887bb 990
<> 160:d5399cc887bb 991 extern "C" int __cxa_guard_acquire(int *guard_object_p)
<> 160:d5399cc887bb 992 {
<> 160:d5399cc887bb 993 uint8_t *guard_object = (uint8_t *)guard_object_p;
<> 160:d5399cc887bb 994 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
<> 160:d5399cc887bb 995 return 0;
<> 160:d5399cc887bb 996 }
<> 160:d5399cc887bb 997 singleton_lock();
<> 160:d5399cc887bb 998 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
<> 160:d5399cc887bb 999 singleton_unlock();
<> 160:d5399cc887bb 1000 return 0;
<> 160:d5399cc887bb 1001 }
<> 160:d5399cc887bb 1002 MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK));
<> 160:d5399cc887bb 1003 *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS;
<> 160:d5399cc887bb 1004 return 1;
<> 160:d5399cc887bb 1005 }
<> 160:d5399cc887bb 1006
<> 160:d5399cc887bb 1007 extern "C" void __cxa_guard_release(int *guard_object_p)
<> 160:d5399cc887bb 1008 {
<> 160:d5399cc887bb 1009 uint8_t *guard_object = (uint8_t *)guard_object_p;
<> 160:d5399cc887bb 1010 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
<> 160:d5399cc887bb 1011 *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE;
<> 160:d5399cc887bb 1012 singleton_unlock();
<> 160:d5399cc887bb 1013 }
<> 160:d5399cc887bb 1014
<> 160:d5399cc887bb 1015 extern "C" void __cxa_guard_abort(int *guard_object_p)
<> 160:d5399cc887bb 1016 {
<> 160:d5399cc887bb 1017 uint8_t *guard_object = (uint8_t *)guard_object_p;
<> 160:d5399cc887bb 1018 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
<> 160:d5399cc887bb 1019 *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS;
<> 160:d5399cc887bb 1020 singleton_unlock();
<> 160:d5399cc887bb 1021 }
<> 160:d5399cc887bb 1022
<> 160:d5399cc887bb 1023 #endif
<> 160:d5399cc887bb 1024
<> 160:d5399cc887bb 1025 void *operator new(std::size_t count)
<> 160:d5399cc887bb 1026 {
<> 160:d5399cc887bb 1027 void *buffer = malloc(count);
<> 160:d5399cc887bb 1028 if (NULL == buffer) {
<> 160:d5399cc887bb 1029 error("Operator new out of memory\r\n");
<> 160:d5399cc887bb 1030 }
<> 160:d5399cc887bb 1031 return buffer;
<> 160:d5399cc887bb 1032 }
<> 160:d5399cc887bb 1033
<> 160:d5399cc887bb 1034 void *operator new[](std::size_t count)
<> 160:d5399cc887bb 1035 {
<> 160:d5399cc887bb 1036 void *buffer = malloc(count);
<> 160:d5399cc887bb 1037 if (NULL == buffer) {
<> 160:d5399cc887bb 1038 error("Operator new[] out of memory\r\n");
<> 160:d5399cc887bb 1039 }
<> 160:d5399cc887bb 1040 return buffer;
<> 160:d5399cc887bb 1041 }
<> 160:d5399cc887bb 1042
AnnaBridge 175:af195413fb11 1043 void *operator new(std::size_t count, const std::nothrow_t& tag)
AnnaBridge 175:af195413fb11 1044 {
AnnaBridge 175:af195413fb11 1045 return malloc(count);
AnnaBridge 175:af195413fb11 1046 }
AnnaBridge 175:af195413fb11 1047
AnnaBridge 175:af195413fb11 1048 void *operator new[](std::size_t count, const std::nothrow_t& tag)
AnnaBridge 175:af195413fb11 1049 {
AnnaBridge 175:af195413fb11 1050 return malloc(count);
AnnaBridge 175:af195413fb11 1051 }
AnnaBridge 175:af195413fb11 1052
<> 160:d5399cc887bb 1053 void operator delete(void *ptr)
<> 160:d5399cc887bb 1054 {
Anna Bridge 180:96ed750bd169 1055 free(ptr);
<> 160:d5399cc887bb 1056 }
<> 160:d5399cc887bb 1057 void operator delete[](void *ptr)
<> 160:d5399cc887bb 1058 {
Anna Bridge 180:96ed750bd169 1059 free(ptr);
<> 160:d5399cc887bb 1060 }
AnnaBridge 175:af195413fb11 1061
AnnaBridge 175:af195413fb11 1062 /* @brief standard c library clock() function.
AnnaBridge 175:af195413fb11 1063 *
AnnaBridge 175:af195413fb11 1064 * This function returns the number of clock ticks elapsed since the start of the program.
AnnaBridge 175:af195413fb11 1065 *
AnnaBridge 175:af195413fb11 1066 * @note Synchronization level: Thread safe
AnnaBridge 175:af195413fb11 1067 *
AnnaBridge 175:af195413fb11 1068 * @return
AnnaBridge 175:af195413fb11 1069 * the number of clock ticks elapsed since the start of the program.
AnnaBridge 175:af195413fb11 1070 *
AnnaBridge 175:af195413fb11 1071 * */
AnnaBridge 175:af195413fb11 1072 extern "C" clock_t clock()
AnnaBridge 175:af195413fb11 1073 {
AnnaBridge 175:af195413fb11 1074 _mutex->lock();
AnnaBridge 175:af195413fb11 1075 clock_t t = ticker_read(get_us_ticker_data());
AnnaBridge 175:af195413fb11 1076 t /= 1000000 / CLOCKS_PER_SEC; // convert to processor time
AnnaBridge 175:af195413fb11 1077 _mutex->unlock();
AnnaBridge 175:af195413fb11 1078 return t;
AnnaBridge 175:af195413fb11 1079 }
Anna Bridge 180:96ed750bd169 1080
Anna Bridge 180:96ed750bd169 1081 // temporary - Default to 1MHz at 32 bits if target does not have us_ticker_get_info
Anna Bridge 180:96ed750bd169 1082 MBED_WEAK const ticker_info_t* us_ticker_get_info()
Anna Bridge 180:96ed750bd169 1083 {
Anna Bridge 180:96ed750bd169 1084 static const ticker_info_t info = {
Anna Bridge 180:96ed750bd169 1085 1000000,
Anna Bridge 180:96ed750bd169 1086 32
Anna Bridge 180:96ed750bd169 1087 };
Anna Bridge 180:96ed750bd169 1088 return &info;
Anna Bridge 180:96ed750bd169 1089 }
Anna Bridge 180:96ed750bd169 1090
Anna Bridge 180:96ed750bd169 1091 // temporary - Default to 1MHz at 32 bits if target does not have lp_ticker_get_info
Anna Bridge 180:96ed750bd169 1092 MBED_WEAK const ticker_info_t* lp_ticker_get_info()
Anna Bridge 180:96ed750bd169 1093 {
Anna Bridge 180:96ed750bd169 1094 static const ticker_info_t info = {
Anna Bridge 180:96ed750bd169 1095 1000000,
Anna Bridge 180:96ed750bd169 1096 32
Anna Bridge 180:96ed750bd169 1097 };
Anna Bridge 180:96ed750bd169 1098 return &info;
Anna Bridge 180:96ed750bd169 1099 }