mbed library sources with internal temperature sensor for nucleo f401

Committer:
elessair
Date:
Sat Jan 17 18:03:58 2015 +0000
Revision:
0:7e2bd16f80af
nucleo f401re internal temperature added

Who changed what in which revision?

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