Opencv 3.1 project on GR-PEACH board

Fork of gr-peach-opencv-project by the do

Committer:
thedo
Date:
Thu Jun 29 11:01:39 2017 +0000
Revision:
167:1657b442184c
Opencv 3.1 project on GR-PEACH board, 4 apps

Who changed what in which revision?

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