mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Thu Jul 31 13:45:07 2014 +0100
Revision:
269:0e58554f11d5
Parent:
251:de9a1e4ffd79
Child:
284:859ffaa7c331
Synchronized with git revision dd71fab893892a11e3cc82b3b40714922b823099

Full URL: https://github.com/mbedmicro/mbed/commit/dd71fab893892a11e3cc82b3b40714922b823099/

Bugfix: Make redirected stdio write initialize UART

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 13:0645d8841f51 1 /* mbed Microcontroller Library
bogdanm 13:0645d8841f51 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 13:0645d8841f51 3 *
bogdanm 13:0645d8841f51 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 13:0645d8841f51 5 * you may not use this file except in compliance with the License.
bogdanm 13:0645d8841f51 6 * You may obtain a copy of the License at
bogdanm 13:0645d8841f51 7 *
bogdanm 13:0645d8841f51 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 13:0645d8841f51 9 *
bogdanm 13:0645d8841f51 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 13:0645d8841f51 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 13:0645d8841f51 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 13:0645d8841f51 13 * See the License for the specific language governing permissions and
bogdanm 13:0645d8841f51 14 * limitations under the License.
bogdanm 13:0645d8841f51 15 */
bogdanm 13:0645d8841f51 16 #include "platform.h"
bogdanm 13:0645d8841f51 17 #include "FileHandle.h"
bogdanm 13:0645d8841f51 18 #include "FileSystemLike.h"
bogdanm 13:0645d8841f51 19 #include "FilePath.h"
bogdanm 13:0645d8841f51 20 #include "serial_api.h"
bogdanm 13:0645d8841f51 21 #include "toolchain.h"
bogdanm 13:0645d8841f51 22 #include <errno.h>
bogdanm 13:0645d8841f51 23
bogdanm 13:0645d8841f51 24 #if defined(__ARMCC_VERSION)
bogdanm 13:0645d8841f51 25 # include <rt_sys.h>
bogdanm 13:0645d8841f51 26 # define PREFIX(x) _sys##x
bogdanm 13:0645d8841f51 27 # define OPEN_MAX _SYS_OPEN
bogdanm 13:0645d8841f51 28 # ifdef __MICROLIB
bogdanm 13:0645d8841f51 29 # pragma import(__use_full_stdio)
bogdanm 13:0645d8841f51 30 # endif
bogdanm 13:0645d8841f51 31
bogdanm 13:0645d8841f51 32 #elif defined(__ICCARM__)
bogdanm 13:0645d8841f51 33 # include <yfuns.h>
bogdanm 13:0645d8841f51 34 # define PREFIX(x) _##x
bogdanm 13:0645d8841f51 35 # define OPEN_MAX 16
bogdanm 13:0645d8841f51 36
bogdanm 13:0645d8841f51 37 # define STDIN_FILENO 0
bogdanm 13:0645d8841f51 38 # define STDOUT_FILENO 1
bogdanm 13:0645d8841f51 39 # define STDERR_FILENO 2
bogdanm 13:0645d8841f51 40
bogdanm 13:0645d8841f51 41 #else
bogdanm 13:0645d8841f51 42 # include <sys/stat.h>
bogdanm 13:0645d8841f51 43 # include <sys/unistd.h>
bogdanm 13:0645d8841f51 44 # include <sys/syslimits.h>
bogdanm 13:0645d8841f51 45 # define PREFIX(x) x
bogdanm 13:0645d8841f51 46 #endif
bogdanm 13:0645d8841f51 47
bogdanm 13:0645d8841f51 48 using namespace mbed;
bogdanm 13:0645d8841f51 49
bogdanm 13:0645d8841f51 50 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
bogdanm 13:0645d8841f51 51 // Before version 5.03, we were using a patched version of microlib with proper names
bogdanm 13:0645d8841f51 52 extern const char __stdin_name[] = ":tt";
bogdanm 13:0645d8841f51 53 extern const char __stdout_name[] = ":tt";
bogdanm 13:0645d8841f51 54 extern const char __stderr_name[] = ":tt";
bogdanm 13:0645d8841f51 55
bogdanm 13:0645d8841f51 56 #else
bogdanm 13:0645d8841f51 57 extern const char __stdin_name[] = "/stdin";
bogdanm 13:0645d8841f51 58 extern const char __stdout_name[] = "/stdout";
bogdanm 13:0645d8841f51 59 extern const char __stderr_name[] = "/stderr";
bogdanm 13:0645d8841f51 60 #endif
bogdanm 13:0645d8841f51 61
bogdanm 13:0645d8841f51 62 /* newlib has the filehandle field in the FILE struct as a short, so
bogdanm 13:0645d8841f51 63 * we can't just return a Filehandle* from _open and instead have to
bogdanm 13:0645d8841f51 64 * put it in a filehandles array and return the index into that array
bogdanm 13:0645d8841f51 65 * (or rather index+3, as filehandles 0-2 are stdin/out/err).
bogdanm 13:0645d8841f51 66 */
bogdanm 13:0645d8841f51 67 static FileHandle *filehandles[OPEN_MAX];
bogdanm 13:0645d8841f51 68
bogdanm 13:0645d8841f51 69 FileHandle::~FileHandle() {
bogdanm 13:0645d8841f51 70 /* Remove all open filehandles for this */
bogdanm 13:0645d8841f51 71 for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
bogdanm 13:0645d8841f51 72 if (filehandles[fh_i] == this) {
bogdanm 13:0645d8841f51 73 filehandles[fh_i] = NULL;
bogdanm 13:0645d8841f51 74 }
bogdanm 13:0645d8841f51 75 }
bogdanm 13:0645d8841f51 76 }
bogdanm 13:0645d8841f51 77
bogdanm 13:0645d8841f51 78 #if DEVICE_SERIAL
bogdanm 13:0645d8841f51 79 extern int stdio_uart_inited;
bogdanm 13:0645d8841f51 80 extern serial_t stdio_uart;
bogdanm 13:0645d8841f51 81 #endif
bogdanm 13:0645d8841f51 82
bogdanm 13:0645d8841f51 83 static void init_serial() {
bogdanm 13:0645d8841f51 84 #if DEVICE_SERIAL
bogdanm 13:0645d8841f51 85 if (stdio_uart_inited) return;
bogdanm 13:0645d8841f51 86 serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
bogdanm 13:0645d8841f51 87 #endif
bogdanm 13:0645d8841f51 88 }
bogdanm 13:0645d8841f51 89
bogdanm 13:0645d8841f51 90 static inline int openmode_to_posix(int openmode) {
bogdanm 13:0645d8841f51 91 int posix = openmode;
bogdanm 13:0645d8841f51 92 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 93 if (openmode & OPEN_PLUS) {
bogdanm 13:0645d8841f51 94 posix = O_RDWR;
bogdanm 13:0645d8841f51 95 } else if(openmode & OPEN_W) {
bogdanm 13:0645d8841f51 96 posix = O_WRONLY;
bogdanm 13:0645d8841f51 97 } else if(openmode & OPEN_A) {
bogdanm 13:0645d8841f51 98 posix = O_WRONLY|O_APPEND;
bogdanm 13:0645d8841f51 99 } else {
bogdanm 13:0645d8841f51 100 posix = O_RDONLY;
bogdanm 13:0645d8841f51 101 }
bogdanm 13:0645d8841f51 102 /* a, w, a+, w+ all create if file does not already exist */
bogdanm 13:0645d8841f51 103 if (openmode & (OPEN_A|OPEN_W)) {
bogdanm 13:0645d8841f51 104 posix |= O_CREAT;
bogdanm 13:0645d8841f51 105 }
bogdanm 13:0645d8841f51 106 /* w and w+ truncate */
bogdanm 13:0645d8841f51 107 if (openmode & OPEN_W) {
bogdanm 13:0645d8841f51 108 posix |= O_TRUNC;
bogdanm 13:0645d8841f51 109 }
bogdanm 13:0645d8841f51 110 #elif defined(__ICCARM__)
bogdanm 13:0645d8841f51 111 switch (openmode & _LLIO_RDWRMASK) {
bogdanm 13:0645d8841f51 112 case _LLIO_RDONLY: posix = O_RDONLY; break;
bogdanm 13:0645d8841f51 113 case _LLIO_WRONLY: posix = O_WRONLY; break;
bogdanm 13:0645d8841f51 114 case _LLIO_RDWR : posix = O_RDWR ; break;
bogdanm 13:0645d8841f51 115 }
bogdanm 13:0645d8841f51 116 if (openmode & _LLIO_CREAT ) posix |= O_CREAT;
bogdanm 13:0645d8841f51 117 if (openmode & _LLIO_APPEND) posix |= O_APPEND;
bogdanm 13:0645d8841f51 118 if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC;
bogdanm 13:0645d8841f51 119 #endif
bogdanm 13:0645d8841f51 120 return posix;
bogdanm 13:0645d8841f51 121 }
bogdanm 13:0645d8841f51 122
bogdanm 13:0645d8841f51 123 extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
bogdanm 13:0645d8841f51 124 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
bogdanm 13:0645d8841f51 125 // Before version 5.03, we were using a patched version of microlib with proper names
bogdanm 13:0645d8841f51 126 // This is the workaround that the microlib author suggested us
bogdanm 13:0645d8841f51 127 static int n = 0;
bogdanm 13:0645d8841f51 128 if (!std::strcmp(name, ":tt")) return n++;
mbed_official 221:8276e3a4886f 129
bogdanm 13:0645d8841f51 130 #else
bogdanm 13:0645d8841f51 131 /* Use the posix convention that stdin,out,err are filehandles 0,1,2.
bogdanm 13:0645d8841f51 132 */
bogdanm 13:0645d8841f51 133 if (std::strcmp(name, __stdin_name) == 0) {
bogdanm 13:0645d8841f51 134 init_serial();
bogdanm 13:0645d8841f51 135 return 0;
bogdanm 13:0645d8841f51 136 } else if (std::strcmp(name, __stdout_name) == 0) {
bogdanm 13:0645d8841f51 137 init_serial();
bogdanm 13:0645d8841f51 138 return 1;
bogdanm 13:0645d8841f51 139 } else if (std::strcmp(name, __stderr_name) == 0) {
bogdanm 13:0645d8841f51 140 init_serial();
bogdanm 13:0645d8841f51 141 return 2;
bogdanm 13:0645d8841f51 142 }
bogdanm 13:0645d8841f51 143 #endif
mbed_official 221:8276e3a4886f 144
bogdanm 13:0645d8841f51 145 // find the first empty slot in filehandles
bogdanm 13:0645d8841f51 146 unsigned int fh_i;
bogdanm 13:0645d8841f51 147 for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
bogdanm 13:0645d8841f51 148 if (filehandles[fh_i] == NULL) break;
bogdanm 13:0645d8841f51 149 }
bogdanm 13:0645d8841f51 150 if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) {
bogdanm 13:0645d8841f51 151 return -1;
bogdanm 13:0645d8841f51 152 }
bogdanm 13:0645d8841f51 153
bogdanm 13:0645d8841f51 154 FileHandle *res;
bogdanm 13:0645d8841f51 155
bogdanm 13:0645d8841f51 156 /* FILENAME: ":0x12345678" describes a FileLike* */
bogdanm 13:0645d8841f51 157 if (name[0] == ':') {
bogdanm 13:0645d8841f51 158 void *p;
bogdanm 13:0645d8841f51 159 sscanf(name, ":%p", &p);
bogdanm 13:0645d8841f51 160 res = (FileHandle*)p;
bogdanm 13:0645d8841f51 161
bogdanm 13:0645d8841f51 162 /* FILENAME: "/file_system/file_name" */
bogdanm 13:0645d8841f51 163 } else {
bogdanm 13:0645d8841f51 164 FilePath path(name);
bogdanm 13:0645d8841f51 165
bogdanm 20:4263a77256ae 166 if (!path.exists())
bogdanm 20:4263a77256ae 167 return -1;
bogdanm 20:4263a77256ae 168 else if (path.isFile()) {
bogdanm 13:0645d8841f51 169 res = path.file();
bogdanm 13:0645d8841f51 170 } else {
bogdanm 13:0645d8841f51 171 FileSystemLike *fs = path.fileSystem();
bogdanm 13:0645d8841f51 172 if (fs == NULL) return -1;
bogdanm 13:0645d8841f51 173 int posix_mode = openmode_to_posix(openmode);
bogdanm 13:0645d8841f51 174 res = fs->open(path.fileName(), posix_mode); /* NULL if fails */
bogdanm 13:0645d8841f51 175 }
bogdanm 13:0645d8841f51 176 }
bogdanm 13:0645d8841f51 177
bogdanm 13:0645d8841f51 178 if (res == NULL) return -1;
bogdanm 13:0645d8841f51 179 filehandles[fh_i] = res;
bogdanm 13:0645d8841f51 180
bogdanm 13:0645d8841f51 181 return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err
bogdanm 13:0645d8841f51 182 }
bogdanm 13:0645d8841f51 183
bogdanm 13:0645d8841f51 184 extern "C" int PREFIX(_close)(FILEHANDLE fh) {
bogdanm 13:0645d8841f51 185 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 186
bogdanm 13:0645d8841f51 187 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 188 filehandles[fh-3] = NULL;
bogdanm 13:0645d8841f51 189 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 190
bogdanm 13:0645d8841f51 191 return fhc->close();
bogdanm 13:0645d8841f51 192 }
bogdanm 13:0645d8841f51 193
bogdanm 13:0645d8841f51 194 #if defined(__ICCARM__)
bogdanm 13:0645d8841f51 195 extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) {
bogdanm 13:0645d8841f51 196 #else
bogdanm 13:0645d8841f51 197 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) {
bogdanm 13:0645d8841f51 198 #endif
bogdanm 13:0645d8841f51 199 int n; // n is the number of bytes written
bogdanm 13:0645d8841f51 200 if (fh < 3) {
bogdanm 13:0645d8841f51 201 #if DEVICE_SERIAL
bogdanm 13:0645d8841f51 202 if (!stdio_uart_inited) init_serial();
bogdanm 13:0645d8841f51 203 for (unsigned int i = 0; i < length; i++) {
bogdanm 13:0645d8841f51 204 serial_putc(&stdio_uart, buffer[i]);
bogdanm 13:0645d8841f51 205 }
bogdanm 13:0645d8841f51 206 #endif
bogdanm 13:0645d8841f51 207 n = length;
bogdanm 13:0645d8841f51 208 } else {
bogdanm 13:0645d8841f51 209 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 210 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 211
bogdanm 13:0645d8841f51 212 n = fhc->write(buffer, length);
bogdanm 13:0645d8841f51 213 }
bogdanm 13:0645d8841f51 214 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 215 return length-n;
bogdanm 13:0645d8841f51 216 #else
bogdanm 13:0645d8841f51 217 return n;
bogdanm 13:0645d8841f51 218 #endif
bogdanm 13:0645d8841f51 219 }
bogdanm 13:0645d8841f51 220
bogdanm 13:0645d8841f51 221 #if defined(__ICCARM__)
bogdanm 13:0645d8841f51 222 extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) {
bogdanm 13:0645d8841f51 223 #else
bogdanm 13:0645d8841f51 224 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) {
bogdanm 13:0645d8841f51 225 #endif
bogdanm 13:0645d8841f51 226 int n; // n is the number of bytes read
bogdanm 13:0645d8841f51 227 if (fh < 3) {
bogdanm 13:0645d8841f51 228 // only read a character at a time from stdin
bogdanm 13:0645d8841f51 229 #if DEVICE_SERIAL
mbed_official 269:0e58554f11d5 230 if (!stdio_uart_inited) init_serial();
bogdanm 13:0645d8841f51 231 *buffer = serial_getc(&stdio_uart);
bogdanm 13:0645d8841f51 232 #endif
bogdanm 13:0645d8841f51 233 n = 1;
bogdanm 13:0645d8841f51 234 } else {
bogdanm 13:0645d8841f51 235 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 236 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 237
bogdanm 13:0645d8841f51 238 n = fhc->read(buffer, length);
bogdanm 13:0645d8841f51 239 }
bogdanm 13:0645d8841f51 240 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 241 return length-n;
bogdanm 13:0645d8841f51 242 #else
bogdanm 13:0645d8841f51 243 return n;
bogdanm 13:0645d8841f51 244 #endif
bogdanm 13:0645d8841f51 245 }
bogdanm 13:0645d8841f51 246
bogdanm 13:0645d8841f51 247 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 248 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
bogdanm 13:0645d8841f51 249 #else
bogdanm 13:0645d8841f51 250 extern "C" int _isatty(FILEHANDLE fh)
bogdanm 13:0645d8841f51 251 #endif
bogdanm 13:0645d8841f51 252 {
bogdanm 13:0645d8841f51 253 /* stdin, stdout and stderr should be tty */
bogdanm 13:0645d8841f51 254 if (fh < 3) return 1;
bogdanm 13:0645d8841f51 255
bogdanm 13:0645d8841f51 256 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 257 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 258
bogdanm 13:0645d8841f51 259 return fhc->isatty();
bogdanm 13:0645d8841f51 260 }
bogdanm 13:0645d8841f51 261
bogdanm 13:0645d8841f51 262 extern "C"
bogdanm 13:0645d8841f51 263 #if defined(__ARMCC_VERSION)
bogdanm 13:0645d8841f51 264 int _sys_seek(FILEHANDLE fh, long position)
bogdanm 13:0645d8841f51 265 #elif defined(__ICCARM__)
bogdanm 13:0645d8841f51 266 long __lseek(int fh, long offset, int whence)
bogdanm 13:0645d8841f51 267 #else
bogdanm 13:0645d8841f51 268 int _lseek(FILEHANDLE fh, int offset, int whence)
bogdanm 13:0645d8841f51 269 #endif
bogdanm 13:0645d8841f51 270 {
bogdanm 13:0645d8841f51 271 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 272
bogdanm 13:0645d8841f51 273 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 274 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 275
bogdanm 13:0645d8841f51 276 #if defined(__ARMCC_VERSION)
bogdanm 13:0645d8841f51 277 return fhc->lseek(position, SEEK_SET);
bogdanm 13:0645d8841f51 278 #else
bogdanm 13:0645d8841f51 279 return fhc->lseek(offset, whence);
bogdanm 13:0645d8841f51 280 #endif
bogdanm 13:0645d8841f51 281 }
bogdanm 13:0645d8841f51 282
bogdanm 13:0645d8841f51 283 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 284 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
bogdanm 13:0645d8841f51 285 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 286
bogdanm 13:0645d8841f51 287 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 288 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 289
bogdanm 13:0645d8841f51 290 return fhc->fsync();
bogdanm 13:0645d8841f51 291 }
bogdanm 13:0645d8841f51 292
bogdanm 13:0645d8841f51 293 extern "C" long PREFIX(_flen)(FILEHANDLE fh) {
bogdanm 13:0645d8841f51 294 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 295
bogdanm 13:0645d8841f51 296 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 297 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 298
bogdanm 13:0645d8841f51 299 return fhc->flen();
bogdanm 13:0645d8841f51 300 }
bogdanm 13:0645d8841f51 301 #endif
bogdanm 13:0645d8841f51 302
bogdanm 13:0645d8841f51 303
bogdanm 13:0645d8841f51 304 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
bogdanm 13:0645d8841f51 305 extern "C" int _fstat(int fd, struct stat *st) {
bogdanm 13:0645d8841f51 306 if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) {
bogdanm 13:0645d8841f51 307 st->st_mode = S_IFCHR;
bogdanm 13:0645d8841f51 308 return 0;
bogdanm 13:0645d8841f51 309 }
bogdanm 13:0645d8841f51 310
bogdanm 13:0645d8841f51 311 errno = EBADF;
bogdanm 13:0645d8841f51 312 return -1;
bogdanm 13:0645d8841f51 313 }
bogdanm 13:0645d8841f51 314 #endif
bogdanm 13:0645d8841f51 315
bogdanm 13:0645d8841f51 316 namespace std {
bogdanm 13:0645d8841f51 317 extern "C" int remove(const char *path) {
bogdanm 13:0645d8841f51 318 FilePath fp(path);
bogdanm 13:0645d8841f51 319 FileSystemLike *fs = fp.fileSystem();
bogdanm 13:0645d8841f51 320 if (fs == NULL) return -1;
bogdanm 13:0645d8841f51 321
bogdanm 13:0645d8841f51 322 return fs->remove(fp.fileName());
bogdanm 13:0645d8841f51 323 }
bogdanm 13:0645d8841f51 324
bogdanm 13:0645d8841f51 325 extern "C" int rename(const char *oldname, const char *newname) {
bogdanm 13:0645d8841f51 326 return -1;
bogdanm 13:0645d8841f51 327 }
bogdanm 13:0645d8841f51 328
bogdanm 13:0645d8841f51 329 extern "C" char *tmpnam(char *s) {
bogdanm 13:0645d8841f51 330 return NULL;
bogdanm 13:0645d8841f51 331 }
bogdanm 13:0645d8841f51 332
bogdanm 13:0645d8841f51 333 extern "C" FILE *tmpfile() {
bogdanm 13:0645d8841f51 334 return NULL;
bogdanm 13:0645d8841f51 335 }
bogdanm 13:0645d8841f51 336 } // namespace std
bogdanm 13:0645d8841f51 337
bogdanm 13:0645d8841f51 338 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 339 extern "C" char *_sys_command_string(char *cmd, int len) {
bogdanm 13:0645d8841f51 340 return NULL;
bogdanm 13:0645d8841f51 341 }
bogdanm 13:0645d8841f51 342 #endif
bogdanm 13:0645d8841f51 343
bogdanm 13:0645d8841f51 344 extern "C" DIR *opendir(const char *path) {
bogdanm 13:0645d8841f51 345 /* root dir is FileSystemLike */
bogdanm 13:0645d8841f51 346 if (path[0] == '/' && path[1] == 0) {
bogdanm 13:0645d8841f51 347 return FileSystemLike::opendir();
bogdanm 13:0645d8841f51 348 }
bogdanm 13:0645d8841f51 349
bogdanm 13:0645d8841f51 350 FilePath fp(path);
bogdanm 13:0645d8841f51 351 FileSystemLike* fs = fp.fileSystem();
bogdanm 13:0645d8841f51 352 if (fs == NULL) return NULL;
bogdanm 13:0645d8841f51 353
bogdanm 13:0645d8841f51 354 return fs->opendir(fp.fileName());
bogdanm 13:0645d8841f51 355 }
bogdanm 13:0645d8841f51 356
bogdanm 13:0645d8841f51 357 extern "C" struct dirent *readdir(DIR *dir) {
bogdanm 13:0645d8841f51 358 return dir->readdir();
bogdanm 13:0645d8841f51 359 }
bogdanm 13:0645d8841f51 360
bogdanm 13:0645d8841f51 361 extern "C" int closedir(DIR *dir) {
bogdanm 13:0645d8841f51 362 return dir->closedir();
bogdanm 13:0645d8841f51 363 }
bogdanm 13:0645d8841f51 364
bogdanm 13:0645d8841f51 365 extern "C" void rewinddir(DIR *dir) {
bogdanm 13:0645d8841f51 366 dir->rewinddir();
bogdanm 13:0645d8841f51 367 }
bogdanm 13:0645d8841f51 368
bogdanm 13:0645d8841f51 369 extern "C" off_t telldir(DIR *dir) {
bogdanm 13:0645d8841f51 370 return dir->telldir();
bogdanm 13:0645d8841f51 371 }
bogdanm 13:0645d8841f51 372
bogdanm 13:0645d8841f51 373 extern "C" void seekdir(DIR *dir, off_t off) {
bogdanm 13:0645d8841f51 374 dir->seekdir(off);
bogdanm 13:0645d8841f51 375 }
bogdanm 13:0645d8841f51 376
bogdanm 13:0645d8841f51 377 extern "C" int mkdir(const char *path, mode_t mode) {
bogdanm 13:0645d8841f51 378 FilePath fp(path);
bogdanm 13:0645d8841f51 379 FileSystemLike *fs = fp.fileSystem();
bogdanm 13:0645d8841f51 380 if (fs == NULL) return -1;
bogdanm 13:0645d8841f51 381
bogdanm 13:0645d8841f51 382 return fs->mkdir(fp.fileName(), mode);
bogdanm 13:0645d8841f51 383 }
bogdanm 13:0645d8841f51 384
bogdanm 13:0645d8841f51 385 #if defined(TOOLCHAIN_GCC)
bogdanm 13:0645d8841f51 386 /* prevents the exception handling name demangling code getting pulled in */
mbed_official 251:de9a1e4ffd79 387 #include "error.h"
bogdanm 13:0645d8841f51 388 namespace __gnu_cxx {
bogdanm 13:0645d8841f51 389 void __verbose_terminate_handler() {
bogdanm 13:0645d8841f51 390 error("Exception");
bogdanm 13:0645d8841f51 391 }
bogdanm 13:0645d8841f51 392 }
bogdanm 13:0645d8841f51 393 extern "C" WEAK void __cxa_pure_virtual(void);
bogdanm 13:0645d8841f51 394 extern "C" WEAK void __cxa_pure_virtual(void) {
bogdanm 13:0645d8841f51 395 exit(1);
bogdanm 13:0645d8841f51 396 }
bogdanm 13:0645d8841f51 397
bogdanm 13:0645d8841f51 398 #endif
bogdanm 13:0645d8841f51 399
bogdanm 13:0645d8841f51 400 // ****************************************************************************
bogdanm 13:0645d8841f51 401 // mbed_main is a function that is called before main()
mbed_official 83:5a6f638110fe 402 // mbed_sdk_init() is also a function that is called before main(), but unlike
mbed_official 83:5a6f638110fe 403 // mbed_main(), it is not meant for user code, but for the SDK itself to perform
mbed_official 83:5a6f638110fe 404 // initializations before main() is called.
bogdanm 13:0645d8841f51 405
bogdanm 13:0645d8841f51 406 extern "C" WEAK void mbed_main(void);
bogdanm 13:0645d8841f51 407 extern "C" WEAK void mbed_main(void) {
bogdanm 13:0645d8841f51 408 }
bogdanm 13:0645d8841f51 409
mbed_official 83:5a6f638110fe 410 extern "C" WEAK void mbed_sdk_init(void);
mbed_official 83:5a6f638110fe 411 extern "C" WEAK void mbed_sdk_init(void) {
mbed_official 83:5a6f638110fe 412 }
mbed_official 83:5a6f638110fe 413
bogdanm 13:0645d8841f51 414 #if defined(TOOLCHAIN_ARM)
bogdanm 13:0645d8841f51 415 extern "C" int $Super$$main(void);
bogdanm 13:0645d8841f51 416
bogdanm 13:0645d8841f51 417 extern "C" int $Sub$$main(void) {
mbed_official 83:5a6f638110fe 418 mbed_sdk_init();
bogdanm 13:0645d8841f51 419 mbed_main();
bogdanm 13:0645d8841f51 420 return $Super$$main();
bogdanm 13:0645d8841f51 421 }
bogdanm 13:0645d8841f51 422 #elif defined(TOOLCHAIN_GCC)
bogdanm 13:0645d8841f51 423 extern "C" int __real_main(void);
bogdanm 13:0645d8841f51 424
bogdanm 13:0645d8841f51 425 extern "C" int __wrap_main(void) {
mbed_official 83:5a6f638110fe 426 mbed_sdk_init();
bogdanm 13:0645d8841f51 427 mbed_main();
bogdanm 13:0645d8841f51 428 return __real_main();
bogdanm 13:0645d8841f51 429 }
bogdanm 13:0645d8841f51 430 #elif defined(TOOLCHAIN_IAR)
bogdanm 13:0645d8841f51 431 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
bogdanm 13:0645d8841f51 432 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
bogdanm 13:0645d8841f51 433 // 'main' to another symbol looses the original 'main' symbol. However, its startup
bogdanm 13:0645d8841f51 434 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
bogdanm 13:0645d8841f51 435 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
bogdanm 13:0645d8841f51 436 extern "C" void __iar_argc_argv() {
mbed_official 83:5a6f638110fe 437 mbed_sdk_init();
bogdanm 13:0645d8841f51 438 mbed_main();
bogdanm 13:0645d8841f51 439 }
bogdanm 13:0645d8841f51 440 #endif
bogdanm 20:4263a77256ae 441
bogdanm 20:4263a77256ae 442 // Provide implementation of _sbrk (low-level dynamic memory allocation
bogdanm 20:4263a77256ae 443 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
bogdanm 20:4263a77256ae 444 // SP. This make it compatible with RTX RTOS thread stacks.
bogdanm 20:4263a77256ae 445 #if defined(TOOLCHAIN_GCC_ARM)
bogdanm 20:4263a77256ae 446 // Linker defined symbol used by _sbrk to indicate where heap should start.
bogdanm 20:4263a77256ae 447 extern "C" int __end__;
bogdanm 20:4263a77256ae 448
bogdanm 20:4263a77256ae 449 // Turn off the errno macro and use actual global variable instead.
bogdanm 20:4263a77256ae 450 #undef errno
bogdanm 20:4263a77256ae 451 extern "C" int errno;
bogdanm 20:4263a77256ae 452
mbed_official 23:8d50de55f208 453 // For ARM7 only
mbed_official 23:8d50de55f208 454 register unsigned char * stack_ptr __asm ("sp");
mbed_official 23:8d50de55f208 455
bogdanm 20:4263a77256ae 456 // Dynamic memory allocation related syscall.
bogdanm 20:4263a77256ae 457 extern "C" caddr_t _sbrk(int incr) {
bogdanm 20:4263a77256ae 458 static unsigned char* heap = (unsigned char*)&__end__;
bogdanm 20:4263a77256ae 459 unsigned char* prev_heap = heap;
bogdanm 20:4263a77256ae 460 unsigned char* new_heap = heap + incr;
bogdanm 20:4263a77256ae 461
mbed_official 24:75304dd5f5fb 462 #if defined(TARGET_ARM7)
mbed_official 24:75304dd5f5fb 463 if (new_heap >= stack_ptr) {
mbed_official 24:75304dd5f5fb 464 #else
bogdanm 20:4263a77256ae 465 if (new_heap >= (unsigned char*)__get_MSP()) {
mbed_official 23:8d50de55f208 466 #endif
bogdanm 20:4263a77256ae 467 errno = ENOMEM;
bogdanm 20:4263a77256ae 468 return (caddr_t)-1;
bogdanm 20:4263a77256ae 469 }
mbed_official 221:8276e3a4886f 470
bogdanm 20:4263a77256ae 471 heap = new_heap;
bogdanm 20:4263a77256ae 472 return (caddr_t) prev_heap;
bogdanm 20:4263a77256ae 473 }
bogdanm 20:4263a77256ae 474 #endif