The prosthetic control(MIT)

Committer:
ganlikun
Date:
Thu Jun 23 05:23:34 2022 +0000
Revision:
0:20e0c61e0684
01

Who changed what in which revision?

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