inport from local

Dependents:   Hobbyking_Cheetah_0511

Committer:
NYX
Date:
Mon Mar 16 06:35:48 2020 +0000
Revision:
0:85b3fd62ea1a
reinport to mbed;

Who changed what in which revision?

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