PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Wed Dec 25 23:59:52 2019 +0000
Revision:
71:531419862202
Parent:
69:f9f49ff29720
Changed Mode2 C++ refresh code (graphical errors)

Who changed what in which revision?

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