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:
Tue Jun 03 11:30:07 2014 +0100
Revision:
221:8276e3a4886f
Parent:
83:5a6f638110fe
Child:
250:a49055e7a707
Synchronized with git revision bcacbb9fbf3432829227430830cca4315b57c1b9

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

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
bogdanm 13:0645d8841f51 230 *buffer = serial_getc(&stdio_uart);
bogdanm 13:0645d8841f51 231 #endif
bogdanm 13:0645d8841f51 232 n = 1;
bogdanm 13:0645d8841f51 233 } else {
bogdanm 13:0645d8841f51 234 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 235 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 236
bogdanm 13:0645d8841f51 237 n = fhc->read(buffer, length);
bogdanm 13:0645d8841f51 238 }
bogdanm 13:0645d8841f51 239 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 240 return length-n;
bogdanm 13:0645d8841f51 241 #else
bogdanm 13:0645d8841f51 242 return n;
bogdanm 13:0645d8841f51 243 #endif
bogdanm 13:0645d8841f51 244 }
bogdanm 13:0645d8841f51 245
bogdanm 13:0645d8841f51 246 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 247 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
bogdanm 13:0645d8841f51 248 #else
bogdanm 13:0645d8841f51 249 extern "C" int _isatty(FILEHANDLE fh)
bogdanm 13:0645d8841f51 250 #endif
bogdanm 13:0645d8841f51 251 {
bogdanm 13:0645d8841f51 252 /* stdin, stdout and stderr should be tty */
bogdanm 13:0645d8841f51 253 if (fh < 3) return 1;
bogdanm 13:0645d8841f51 254
bogdanm 13:0645d8841f51 255 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 256 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 257
bogdanm 13:0645d8841f51 258 return fhc->isatty();
bogdanm 13:0645d8841f51 259 }
bogdanm 13:0645d8841f51 260
bogdanm 13:0645d8841f51 261 extern "C"
bogdanm 13:0645d8841f51 262 #if defined(__ARMCC_VERSION)
bogdanm 13:0645d8841f51 263 int _sys_seek(FILEHANDLE fh, long position)
bogdanm 13:0645d8841f51 264 #elif defined(__ICCARM__)
bogdanm 13:0645d8841f51 265 long __lseek(int fh, long offset, int whence)
bogdanm 13:0645d8841f51 266 #else
bogdanm 13:0645d8841f51 267 int _lseek(FILEHANDLE fh, int offset, int whence)
bogdanm 13:0645d8841f51 268 #endif
bogdanm 13:0645d8841f51 269 {
bogdanm 13:0645d8841f51 270 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 271
bogdanm 13:0645d8841f51 272 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 273 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 274
bogdanm 13:0645d8841f51 275 #if defined(__ARMCC_VERSION)
bogdanm 13:0645d8841f51 276 return fhc->lseek(position, SEEK_SET);
bogdanm 13:0645d8841f51 277 #else
bogdanm 13:0645d8841f51 278 return fhc->lseek(offset, whence);
bogdanm 13:0645d8841f51 279 #endif
bogdanm 13:0645d8841f51 280 }
bogdanm 13:0645d8841f51 281
bogdanm 13:0645d8841f51 282 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 283 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
bogdanm 13:0645d8841f51 284 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 285
bogdanm 13:0645d8841f51 286 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 287 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 288
bogdanm 13:0645d8841f51 289 return fhc->fsync();
bogdanm 13:0645d8841f51 290 }
bogdanm 13:0645d8841f51 291
bogdanm 13:0645d8841f51 292 extern "C" long PREFIX(_flen)(FILEHANDLE fh) {
bogdanm 13:0645d8841f51 293 if (fh < 3) return 0;
bogdanm 13:0645d8841f51 294
bogdanm 13:0645d8841f51 295 FileHandle* fhc = filehandles[fh-3];
bogdanm 13:0645d8841f51 296 if (fhc == NULL) return -1;
bogdanm 13:0645d8841f51 297
bogdanm 13:0645d8841f51 298 return fhc->flen();
bogdanm 13:0645d8841f51 299 }
bogdanm 13:0645d8841f51 300 #endif
bogdanm 13:0645d8841f51 301
bogdanm 13:0645d8841f51 302
bogdanm 13:0645d8841f51 303 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
bogdanm 13:0645d8841f51 304 extern "C" int _fstat(int fd, struct stat *st) {
bogdanm 13:0645d8841f51 305 if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) {
bogdanm 13:0645d8841f51 306 st->st_mode = S_IFCHR;
bogdanm 13:0645d8841f51 307 return 0;
bogdanm 13:0645d8841f51 308 }
bogdanm 13:0645d8841f51 309
bogdanm 13:0645d8841f51 310 errno = EBADF;
bogdanm 13:0645d8841f51 311 return -1;
bogdanm 13:0645d8841f51 312 }
bogdanm 13:0645d8841f51 313 #endif
bogdanm 13:0645d8841f51 314
bogdanm 13:0645d8841f51 315 namespace std {
bogdanm 13:0645d8841f51 316 extern "C" int remove(const char *path) {
bogdanm 13:0645d8841f51 317 FilePath fp(path);
bogdanm 13:0645d8841f51 318 FileSystemLike *fs = fp.fileSystem();
bogdanm 13:0645d8841f51 319 if (fs == NULL) return -1;
bogdanm 13:0645d8841f51 320
bogdanm 13:0645d8841f51 321 return fs->remove(fp.fileName());
bogdanm 13:0645d8841f51 322 }
bogdanm 13:0645d8841f51 323
bogdanm 13:0645d8841f51 324 extern "C" int rename(const char *oldname, const char *newname) {
bogdanm 13:0645d8841f51 325 return -1;
bogdanm 13:0645d8841f51 326 }
bogdanm 13:0645d8841f51 327
bogdanm 13:0645d8841f51 328 extern "C" char *tmpnam(char *s) {
bogdanm 13:0645d8841f51 329 return NULL;
bogdanm 13:0645d8841f51 330 }
bogdanm 13:0645d8841f51 331
bogdanm 13:0645d8841f51 332 extern "C" FILE *tmpfile() {
bogdanm 13:0645d8841f51 333 return NULL;
bogdanm 13:0645d8841f51 334 }
bogdanm 13:0645d8841f51 335 } // namespace std
bogdanm 13:0645d8841f51 336
bogdanm 13:0645d8841f51 337 #ifdef __ARMCC_VERSION
bogdanm 13:0645d8841f51 338 extern "C" char *_sys_command_string(char *cmd, int len) {
bogdanm 13:0645d8841f51 339 return NULL;
bogdanm 13:0645d8841f51 340 }
bogdanm 13:0645d8841f51 341 #endif
bogdanm 13:0645d8841f51 342
bogdanm 13:0645d8841f51 343 extern "C" DIR *opendir(const char *path) {
bogdanm 13:0645d8841f51 344 /* root dir is FileSystemLike */
bogdanm 13:0645d8841f51 345 if (path[0] == '/' && path[1] == 0) {
bogdanm 13:0645d8841f51 346 return FileSystemLike::opendir();
bogdanm 13:0645d8841f51 347 }
bogdanm 13:0645d8841f51 348
bogdanm 13:0645d8841f51 349 FilePath fp(path);
bogdanm 13:0645d8841f51 350 FileSystemLike* fs = fp.fileSystem();
bogdanm 13:0645d8841f51 351 if (fs == NULL) return NULL;
bogdanm 13:0645d8841f51 352
bogdanm 13:0645d8841f51 353 return fs->opendir(fp.fileName());
bogdanm 13:0645d8841f51 354 }
bogdanm 13:0645d8841f51 355
bogdanm 13:0645d8841f51 356 extern "C" struct dirent *readdir(DIR *dir) {
bogdanm 13:0645d8841f51 357 return dir->readdir();
bogdanm 13:0645d8841f51 358 }
bogdanm 13:0645d8841f51 359
bogdanm 13:0645d8841f51 360 extern "C" int closedir(DIR *dir) {
bogdanm 13:0645d8841f51 361 return dir->closedir();
bogdanm 13:0645d8841f51 362 }
bogdanm 13:0645d8841f51 363
bogdanm 13:0645d8841f51 364 extern "C" void rewinddir(DIR *dir) {
bogdanm 13:0645d8841f51 365 dir->rewinddir();
bogdanm 13:0645d8841f51 366 }
bogdanm 13:0645d8841f51 367
bogdanm 13:0645d8841f51 368 extern "C" off_t telldir(DIR *dir) {
bogdanm 13:0645d8841f51 369 return dir->telldir();
bogdanm 13:0645d8841f51 370 }
bogdanm 13:0645d8841f51 371
bogdanm 13:0645d8841f51 372 extern "C" void seekdir(DIR *dir, off_t off) {
bogdanm 13:0645d8841f51 373 dir->seekdir(off);
bogdanm 13:0645d8841f51 374 }
bogdanm 13:0645d8841f51 375
bogdanm 13:0645d8841f51 376 extern "C" int mkdir(const char *path, mode_t mode) {
bogdanm 13:0645d8841f51 377 FilePath fp(path);
bogdanm 13:0645d8841f51 378 FileSystemLike *fs = fp.fileSystem();
bogdanm 13:0645d8841f51 379 if (fs == NULL) return -1;
bogdanm 13:0645d8841f51 380
bogdanm 13:0645d8841f51 381 return fs->mkdir(fp.fileName(), mode);
bogdanm 13:0645d8841f51 382 }
bogdanm 13:0645d8841f51 383
bogdanm 13:0645d8841f51 384 #if defined(TOOLCHAIN_GCC)
bogdanm 13:0645d8841f51 385 /* prevents the exception handling name demangling code getting pulled in */
bogdanm 13:0645d8841f51 386 #include "error.h"
bogdanm 13:0645d8841f51 387 namespace __gnu_cxx {
bogdanm 13:0645d8841f51 388 void __verbose_terminate_handler() {
bogdanm 13:0645d8841f51 389 error("Exception");
bogdanm 13:0645d8841f51 390 }
bogdanm 13:0645d8841f51 391 }
bogdanm 13:0645d8841f51 392 extern "C" WEAK void __cxa_pure_virtual(void);
bogdanm 13:0645d8841f51 393 extern "C" WEAK void __cxa_pure_virtual(void) {
bogdanm 13:0645d8841f51 394 exit(1);
bogdanm 13:0645d8841f51 395 }
bogdanm 13:0645d8841f51 396
bogdanm 13:0645d8841f51 397 #endif
bogdanm 13:0645d8841f51 398
bogdanm 13:0645d8841f51 399 // ****************************************************************************
bogdanm 13:0645d8841f51 400 // mbed_main is a function that is called before main()
mbed_official 83:5a6f638110fe 401 // mbed_sdk_init() is also a function that is called before main(), but unlike
mbed_official 83:5a6f638110fe 402 // mbed_main(), it is not meant for user code, but for the SDK itself to perform
mbed_official 83:5a6f638110fe 403 // initializations before main() is called.
bogdanm 13:0645d8841f51 404
bogdanm 13:0645d8841f51 405 extern "C" WEAK void mbed_main(void);
bogdanm 13:0645d8841f51 406 extern "C" WEAK void mbed_main(void) {
bogdanm 13:0645d8841f51 407 }
bogdanm 13:0645d8841f51 408
mbed_official 83:5a6f638110fe 409 extern "C" WEAK void mbed_sdk_init(void);
mbed_official 83:5a6f638110fe 410 extern "C" WEAK void mbed_sdk_init(void) {
mbed_official 83:5a6f638110fe 411 }
mbed_official 83:5a6f638110fe 412
bogdanm 13:0645d8841f51 413 #if defined(TOOLCHAIN_ARM)
bogdanm 13:0645d8841f51 414 extern "C" int $Super$$main(void);
bogdanm 13:0645d8841f51 415
bogdanm 13:0645d8841f51 416 extern "C" int $Sub$$main(void) {
mbed_official 83:5a6f638110fe 417 mbed_sdk_init();
bogdanm 13:0645d8841f51 418 mbed_main();
bogdanm 13:0645d8841f51 419 return $Super$$main();
bogdanm 13:0645d8841f51 420 }
bogdanm 13:0645d8841f51 421 #elif defined(TOOLCHAIN_GCC)
bogdanm 13:0645d8841f51 422 extern "C" int __real_main(void);
bogdanm 13:0645d8841f51 423
bogdanm 13:0645d8841f51 424 extern "C" int __wrap_main(void) {
mbed_official 83:5a6f638110fe 425 mbed_sdk_init();
bogdanm 13:0645d8841f51 426 mbed_main();
bogdanm 13:0645d8841f51 427 return __real_main();
bogdanm 13:0645d8841f51 428 }
bogdanm 13:0645d8841f51 429 #elif defined(TOOLCHAIN_IAR)
bogdanm 13:0645d8841f51 430 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
bogdanm 13:0645d8841f51 431 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
bogdanm 13:0645d8841f51 432 // 'main' to another symbol looses the original 'main' symbol. However, its startup
bogdanm 13:0645d8841f51 433 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
bogdanm 13:0645d8841f51 434 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
bogdanm 13:0645d8841f51 435 extern "C" void __iar_argc_argv() {
mbed_official 83:5a6f638110fe 436 mbed_sdk_init();
bogdanm 13:0645d8841f51 437 mbed_main();
bogdanm 13:0645d8841f51 438 }
bogdanm 13:0645d8841f51 439 #endif
bogdanm 20:4263a77256ae 440
bogdanm 20:4263a77256ae 441 // Provide implementation of _sbrk (low-level dynamic memory allocation
bogdanm 20:4263a77256ae 442 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
bogdanm 20:4263a77256ae 443 // SP. This make it compatible with RTX RTOS thread stacks.
bogdanm 20:4263a77256ae 444 #if defined(TOOLCHAIN_GCC_ARM)
bogdanm 20:4263a77256ae 445 // Linker defined symbol used by _sbrk to indicate where heap should start.
bogdanm 20:4263a77256ae 446 extern "C" int __end__;
bogdanm 20:4263a77256ae 447
bogdanm 20:4263a77256ae 448 // Turn off the errno macro and use actual global variable instead.
bogdanm 20:4263a77256ae 449 #undef errno
bogdanm 20:4263a77256ae 450 extern "C" int errno;
bogdanm 20:4263a77256ae 451
mbed_official 23:8d50de55f208 452 // For ARM7 only
mbed_official 23:8d50de55f208 453 register unsigned char * stack_ptr __asm ("sp");
mbed_official 23:8d50de55f208 454
bogdanm 20:4263a77256ae 455 // Dynamic memory allocation related syscall.
bogdanm 20:4263a77256ae 456 extern "C" caddr_t _sbrk(int incr) {
bogdanm 20:4263a77256ae 457 static unsigned char* heap = (unsigned char*)&__end__;
bogdanm 20:4263a77256ae 458 unsigned char* prev_heap = heap;
bogdanm 20:4263a77256ae 459 unsigned char* new_heap = heap + incr;
bogdanm 20:4263a77256ae 460
mbed_official 24:75304dd5f5fb 461 #if defined(TARGET_ARM7)
mbed_official 24:75304dd5f5fb 462 if (new_heap >= stack_ptr) {
mbed_official 24:75304dd5f5fb 463 #else
bogdanm 20:4263a77256ae 464 if (new_heap >= (unsigned char*)__get_MSP()) {
mbed_official 23:8d50de55f208 465 #endif
bogdanm 20:4263a77256ae 466 errno = ENOMEM;
bogdanm 20:4263a77256ae 467 return (caddr_t)-1;
bogdanm 20:4263a77256ae 468 }
mbed_official 221:8276e3a4886f 469
bogdanm 20:4263a77256ae 470 heap = new_heap;
bogdanm 20:4263a77256ae 471 return (caddr_t) prev_heap;
bogdanm 20:4263a77256ae 472 }
bogdanm 20:4263a77256ae 473 #endif