mbed-os for GR-LYCHEE

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

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