Committer:
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4
Date:
Tue Jun 14 09:21:18 2022 +0000
Revision:
0:bdf663c61a82
lib

Who changed what in which revision?

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