mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
Anna Bridge
Date:
Fri Apr 28 14:04:18 2017 +0100
Revision:
163:74e0ce7f98e8
Parent:
160:d5399cc887bb
Child:
167:e84263d55307
This updates the lib to the mbed lib v141

Who changed what in which revision?

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