Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lypinator 0:bb348c97df44 1 /* mbed Microcontroller Library
lypinator 0:bb348c97df44 2 * Copyright (c) 2006-2015 ARM Limited
lypinator 0:bb348c97df44 3 *
lypinator 0:bb348c97df44 4 * Licensed under the Apache License, Version 2.0 (the "License");
lypinator 0:bb348c97df44 5 * you may not use this file except in compliance with the License.
lypinator 0:bb348c97df44 6 * You may obtain a copy of the License at
lypinator 0:bb348c97df44 7 *
lypinator 0:bb348c97df44 8 * http://www.apache.org/licenses/LICENSE-2.0
lypinator 0:bb348c97df44 9 *
lypinator 0:bb348c97df44 10 * Unless required by applicable law or agreed to in writing, software
lypinator 0:bb348c97df44 11 * distributed under the License is distributed on an "AS IS" BASIS,
lypinator 0:bb348c97df44 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lypinator 0:bb348c97df44 13 * See the License for the specific language governing permissions and
lypinator 0:bb348c97df44 14 * limitations under the License.
lypinator 0:bb348c97df44 15 */
lypinator 0:bb348c97df44 16 #include <time.h>
lypinator 0:bb348c97df44 17 #include "platform/platform.h"
lypinator 0:bb348c97df44 18 #include "platform/FilePath.h"
lypinator 0:bb348c97df44 19 #include "hal/serial_api.h"
lypinator 0:bb348c97df44 20 #include "hal/us_ticker_api.h"
lypinator 0:bb348c97df44 21 #include "platform/mbed_toolchain.h"
lypinator 0:bb348c97df44 22 #include "platform/mbed_semihost_api.h"
lypinator 0:bb348c97df44 23 #include "platform/mbed_interface.h"
lypinator 0:bb348c97df44 24 #include "platform/SingletonPtr.h"
lypinator 0:bb348c97df44 25 #include "platform/PlatformMutex.h"
lypinator 0:bb348c97df44 26 #include "platform/mbed_error.h"
lypinator 0:bb348c97df44 27 #include "platform/mbed_stats.h"
lypinator 0:bb348c97df44 28 #include "platform/mbed_critical.h"
lypinator 0:bb348c97df44 29 #include "platform/mbed_poll.h"
lypinator 0:bb348c97df44 30 #include "platform/PlatformMutex.h"
lypinator 0:bb348c97df44 31 #include "drivers/UARTSerial.h"
lypinator 0:bb348c97df44 32 #include "us_ticker_api.h"
lypinator 0:bb348c97df44 33 #include "lp_ticker_api.h"
lypinator 0:bb348c97df44 34 #include <stdlib.h>
lypinator 0:bb348c97df44 35 #include <string.h>
lypinator 0:bb348c97df44 36 #include <limits.h>
lypinator 0:bb348c97df44 37 #ifndef SSIZE_MAX
lypinator 0:bb348c97df44 38 #define SSIZE_MAX INT_MAX
lypinator 0:bb348c97df44 39 #endif
lypinator 0:bb348c97df44 40 #include <stdio.h>
lypinator 0:bb348c97df44 41 #include <errno.h>
lypinator 0:bb348c97df44 42 #include "platform/mbed_retarget.h"
lypinator 0:bb348c97df44 43
lypinator 0:bb348c97df44 44 static SingletonPtr<PlatformMutex> _mutex;
lypinator 0:bb348c97df44 45
lypinator 0:bb348c97df44 46 #if defined(__ARMCC_VERSION)
lypinator 0:bb348c97df44 47 # if __ARMCC_VERSION >= 6010050
lypinator 0:bb348c97df44 48 # include <arm_compat.h>
lypinator 0:bb348c97df44 49 # endif
lypinator 0:bb348c97df44 50 # include <rt_sys.h>
lypinator 0:bb348c97df44 51 # include <rt_misc.h>
lypinator 0:bb348c97df44 52 # include <stdint.h>
lypinator 0:bb348c97df44 53 # define PREFIX(x) _sys##x
lypinator 0:bb348c97df44 54 # define OPEN_MAX _SYS_OPEN
lypinator 0:bb348c97df44 55 # ifdef __MICROLIB
lypinator 0:bb348c97df44 56 # pragma import(__use_full_stdio)
lypinator 0:bb348c97df44 57 # endif
lypinator 0:bb348c97df44 58
lypinator 0:bb348c97df44 59 #elif defined(__ICCARM__)
lypinator 0:bb348c97df44 60 # include <yfuns.h>
lypinator 0:bb348c97df44 61 # define PREFIX(x) _##x
lypinator 0:bb348c97df44 62 # define OPEN_MAX 16
lypinator 0:bb348c97df44 63
lypinator 0:bb348c97df44 64 # define STDIN_FILENO 0
lypinator 0:bb348c97df44 65 # define STDOUT_FILENO 1
lypinator 0:bb348c97df44 66 # define STDERR_FILENO 2
lypinator 0:bb348c97df44 67
lypinator 0:bb348c97df44 68 #else
lypinator 0:bb348c97df44 69 # include <sys/syslimits.h>
lypinator 0:bb348c97df44 70 # define PREFIX(x) x
lypinator 0:bb348c97df44 71 #endif
lypinator 0:bb348c97df44 72
lypinator 0:bb348c97df44 73 #define FILE_HANDLE_RESERVED ((FileHandle*)0xFFFFFFFF)
lypinator 0:bb348c97df44 74
lypinator 0:bb348c97df44 75 /**
lypinator 0:bb348c97df44 76 * Macros for setting console flow control.
lypinator 0:bb348c97df44 77 */
lypinator 0:bb348c97df44 78 #define CONSOLE_FLOWCONTROL_RTS 1
lypinator 0:bb348c97df44 79 #define CONSOLE_FLOWCONTROL_CTS 2
lypinator 0:bb348c97df44 80 #define CONSOLE_FLOWCONTROL_RTSCTS 3
lypinator 0:bb348c97df44 81 #define mbed_console_concat_(x) CONSOLE_FLOWCONTROL_##x
lypinator 0:bb348c97df44 82 #define mbed_console_concat(x) mbed_console_concat_(x)
lypinator 0:bb348c97df44 83 #define CONSOLE_FLOWCONTROL mbed_console_concat(MBED_CONF_TARGET_CONSOLE_UART_FLOW_CONTROL)
lypinator 0:bb348c97df44 84
lypinator 0:bb348c97df44 85 using namespace mbed;
lypinator 0:bb348c97df44 86
lypinator 0:bb348c97df44 87 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
lypinator 0:bb348c97df44 88 // Before version 5.03, we were using a patched version of microlib with proper names
lypinator 0:bb348c97df44 89 extern const char __stdin_name[] = ":tt";
lypinator 0:bb348c97df44 90 extern const char __stdout_name[] = ":tt";
lypinator 0:bb348c97df44 91 extern const char __stderr_name[] = ":tt";
lypinator 0:bb348c97df44 92
lypinator 0:bb348c97df44 93 #else
lypinator 0:bb348c97df44 94 extern const char __stdin_name[] = "/stdin";
lypinator 0:bb348c97df44 95 extern const char __stdout_name[] = "/stdout";
lypinator 0:bb348c97df44 96 extern const char __stderr_name[] = "/stderr";
lypinator 0:bb348c97df44 97 #endif
lypinator 0:bb348c97df44 98
lypinator 0:bb348c97df44 99 unsigned char *mbed_heap_start = 0;
lypinator 0:bb348c97df44 100 uint32_t mbed_heap_size = 0;
lypinator 0:bb348c97df44 101
lypinator 0:bb348c97df44 102 /* newlib has the filehandle field in the FILE struct as a short, so
lypinator 0:bb348c97df44 103 * we can't just return a Filehandle* from _open and instead have to
lypinator 0:bb348c97df44 104 * put it in a filehandles array and return the index into that array
lypinator 0:bb348c97df44 105 */
lypinator 0:bb348c97df44 106 static FileHandle *filehandles[OPEN_MAX] = { FILE_HANDLE_RESERVED, FILE_HANDLE_RESERVED, FILE_HANDLE_RESERVED };
lypinator 0:bb348c97df44 107 static char stdio_in_prev[OPEN_MAX];
lypinator 0:bb348c97df44 108 static char stdio_out_prev[OPEN_MAX];
lypinator 0:bb348c97df44 109 static SingletonPtr<PlatformMutex> filehandle_mutex;
lypinator 0:bb348c97df44 110
lypinator 0:bb348c97df44 111 namespace mbed {
lypinator 0:bb348c97df44 112 void mbed_set_unbuffered_stream(std::FILE *_file);
lypinator 0:bb348c97df44 113
lypinator 0:bb348c97df44 114 void remove_filehandle(FileHandle *file)
lypinator 0:bb348c97df44 115 {
lypinator 0:bb348c97df44 116 filehandle_mutex->lock();
lypinator 0:bb348c97df44 117 /* Remove all open filehandles for this */
lypinator 0:bb348c97df44 118 for (unsigned int fh_i = 0; fh_i < sizeof(filehandles) / sizeof(*filehandles); fh_i++) {
lypinator 0:bb348c97df44 119 if (filehandles[fh_i] == file) {
lypinator 0:bb348c97df44 120 filehandles[fh_i] = NULL;
lypinator 0:bb348c97df44 121 }
lypinator 0:bb348c97df44 122 }
lypinator 0:bb348c97df44 123 filehandle_mutex->unlock();
lypinator 0:bb348c97df44 124 }
lypinator 0:bb348c97df44 125 }
lypinator 0:bb348c97df44 126
lypinator 0:bb348c97df44 127 #if DEVICE_SERIAL
lypinator 0:bb348c97df44 128 extern int stdio_uart_inited;
lypinator 0:bb348c97df44 129 extern serial_t stdio_uart;
lypinator 0:bb348c97df44 130
lypinator 0:bb348c97df44 131 /* Private FileHandle to implement backwards-compatible functionality of
lypinator 0:bb348c97df44 132 * direct HAL serial access for default stdin/stdout/stderr.
lypinator 0:bb348c97df44 133 * This is not a particularly well-behaved FileHandle for a stream, which
lypinator 0:bb348c97df44 134 * is why it's not public. People should be using UARTSerial.
lypinator 0:bb348c97df44 135 */
lypinator 0:bb348c97df44 136 class DirectSerial : public FileHandle {
lypinator 0:bb348c97df44 137 public:
lypinator 0:bb348c97df44 138 DirectSerial(PinName tx, PinName rx, int baud);
lypinator 0:bb348c97df44 139 virtual ssize_t write(const void *buffer, size_t size);
lypinator 0:bb348c97df44 140 virtual ssize_t read(void *buffer, size_t size);
lypinator 0:bb348c97df44 141 virtual off_t seek(off_t offset, int whence = SEEK_SET)
lypinator 0:bb348c97df44 142 {
lypinator 0:bb348c97df44 143 return -ESPIPE;
lypinator 0:bb348c97df44 144 }
lypinator 0:bb348c97df44 145 virtual off_t size()
lypinator 0:bb348c97df44 146 {
lypinator 0:bb348c97df44 147 return -EINVAL;
lypinator 0:bb348c97df44 148 }
lypinator 0:bb348c97df44 149 virtual int isatty()
lypinator 0:bb348c97df44 150 {
lypinator 0:bb348c97df44 151 return true;
lypinator 0:bb348c97df44 152 }
lypinator 0:bb348c97df44 153 virtual int close()
lypinator 0:bb348c97df44 154 {
lypinator 0:bb348c97df44 155 return 0;
lypinator 0:bb348c97df44 156 }
lypinator 0:bb348c97df44 157 virtual short poll(short events) const;
lypinator 0:bb348c97df44 158 };
lypinator 0:bb348c97df44 159
lypinator 0:bb348c97df44 160 DirectSerial::DirectSerial(PinName tx, PinName rx, int baud)
lypinator 0:bb348c97df44 161 {
lypinator 0:bb348c97df44 162 if (stdio_uart_inited) {
lypinator 0:bb348c97df44 163 return;
lypinator 0:bb348c97df44 164 }
lypinator 0:bb348c97df44 165 serial_init(&stdio_uart, tx, rx);
lypinator 0:bb348c97df44 166 serial_baud(&stdio_uart, baud);
lypinator 0:bb348c97df44 167 #if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS
lypinator 0:bb348c97df44 168 serial_set_flow_control(&stdio_uart, FlowControlRTS, STDIO_UART_RTS, NC);
lypinator 0:bb348c97df44 169 #elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_CTS
lypinator 0:bb348c97df44 170 serial_set_flow_control(&stdio_uart, FlowControlCTS, NC, STDIO_UART_CTS);
lypinator 0:bb348c97df44 171 #elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTSCTS
lypinator 0:bb348c97df44 172 serial_set_flow_control(&stdio_uart, FlowControlRTSCTS, STDIO_UART_RTS, STDIO_UART_CTS);
lypinator 0:bb348c97df44 173 #endif
lypinator 0:bb348c97df44 174 }
lypinator 0:bb348c97df44 175
lypinator 0:bb348c97df44 176 ssize_t DirectSerial::write(const void *buffer, size_t size)
lypinator 0:bb348c97df44 177 {
lypinator 0:bb348c97df44 178 const unsigned char *buf = static_cast<const unsigned char *>(buffer);
lypinator 0:bb348c97df44 179 for (size_t i = 0; i < size; i++) {
lypinator 0:bb348c97df44 180 serial_putc(&stdio_uart, buf[i]);
lypinator 0:bb348c97df44 181 }
lypinator 0:bb348c97df44 182 return size;
lypinator 0:bb348c97df44 183 }
lypinator 0:bb348c97df44 184
lypinator 0:bb348c97df44 185 ssize_t DirectSerial::read(void *buffer, size_t size)
lypinator 0:bb348c97df44 186 {
lypinator 0:bb348c97df44 187 unsigned char *buf = static_cast<unsigned char *>(buffer);
lypinator 0:bb348c97df44 188 if (size == 0) {
lypinator 0:bb348c97df44 189 return 0;
lypinator 0:bb348c97df44 190 }
lypinator 0:bb348c97df44 191 buf[0] = serial_getc(&stdio_uart);
lypinator 0:bb348c97df44 192 return 1;
lypinator 0:bb348c97df44 193 }
lypinator 0:bb348c97df44 194
lypinator 0:bb348c97df44 195 short DirectSerial::poll(short events) const
lypinator 0:bb348c97df44 196 {
lypinator 0:bb348c97df44 197 short revents = 0;
lypinator 0:bb348c97df44 198 if ((events & POLLIN) && serial_readable(&stdio_uart)) {
lypinator 0:bb348c97df44 199 revents |= POLLIN;
lypinator 0:bb348c97df44 200 }
lypinator 0:bb348c97df44 201 if ((events & POLLOUT) && serial_writable(&stdio_uart)) {
lypinator 0:bb348c97df44 202 revents |= POLLOUT;
lypinator 0:bb348c97df44 203 }
lypinator 0:bb348c97df44 204 return revents;
lypinator 0:bb348c97df44 205 }
lypinator 0:bb348c97df44 206 #endif
lypinator 0:bb348c97df44 207
lypinator 0:bb348c97df44 208 class Sink : public FileHandle {
lypinator 0:bb348c97df44 209 public:
lypinator 0:bb348c97df44 210 virtual ssize_t write(const void *buffer, size_t size);
lypinator 0:bb348c97df44 211 virtual ssize_t read(void *buffer, size_t size);
lypinator 0:bb348c97df44 212 virtual off_t seek(off_t offset, int whence = SEEK_SET)
lypinator 0:bb348c97df44 213 {
lypinator 0:bb348c97df44 214 return ESPIPE;
lypinator 0:bb348c97df44 215 }
lypinator 0:bb348c97df44 216 virtual off_t size()
lypinator 0:bb348c97df44 217 {
lypinator 0:bb348c97df44 218 return -EINVAL;
lypinator 0:bb348c97df44 219 }
lypinator 0:bb348c97df44 220 virtual int isatty()
lypinator 0:bb348c97df44 221 {
lypinator 0:bb348c97df44 222 return true;
lypinator 0:bb348c97df44 223 }
lypinator 0:bb348c97df44 224 virtual int close()
lypinator 0:bb348c97df44 225 {
lypinator 0:bb348c97df44 226 return 0;
lypinator 0:bb348c97df44 227 }
lypinator 0:bb348c97df44 228 };
lypinator 0:bb348c97df44 229
lypinator 0:bb348c97df44 230 ssize_t Sink::write(const void *buffer, size_t size)
lypinator 0:bb348c97df44 231 {
lypinator 0:bb348c97df44 232 // Just swallow the data - this is historical non-DEVICE_SERIAL behaviour
lypinator 0:bb348c97df44 233 return size;
lypinator 0:bb348c97df44 234 }
lypinator 0:bb348c97df44 235
lypinator 0:bb348c97df44 236 ssize_t Sink::read(void *buffer, size_t size)
lypinator 0:bb348c97df44 237 {
lypinator 0:bb348c97df44 238 // Produce 1 zero byte - historical behaviour returned 1 without touching
lypinator 0:bb348c97df44 239 // the buffer
lypinator 0:bb348c97df44 240 unsigned char *buf = static_cast<unsigned char *>(buffer);
lypinator 0:bb348c97df44 241 buf[0] = 0;
lypinator 0:bb348c97df44 242 return 1;
lypinator 0:bb348c97df44 243 }
lypinator 0:bb348c97df44 244
lypinator 0:bb348c97df44 245
lypinator 0:bb348c97df44 246 MBED_WEAK FileHandle *mbed::mbed_target_override_console(int fd)
lypinator 0:bb348c97df44 247 {
lypinator 0:bb348c97df44 248 return NULL;
lypinator 0:bb348c97df44 249 }
lypinator 0:bb348c97df44 250
lypinator 0:bb348c97df44 251 MBED_WEAK FileHandle *mbed::mbed_override_console(int fd)
lypinator 0:bb348c97df44 252 {
lypinator 0:bb348c97df44 253 return NULL;
lypinator 0:bb348c97df44 254 }
lypinator 0:bb348c97df44 255
lypinator 0:bb348c97df44 256 static FileHandle *default_console()
lypinator 0:bb348c97df44 257 {
lypinator 0:bb348c97df44 258 #if DEVICE_SERIAL
lypinator 0:bb348c97df44 259 # if MBED_CONF_PLATFORM_STDIO_BUFFERED_SERIAL
lypinator 0:bb348c97df44 260 static UARTSerial console(STDIO_UART_TX, STDIO_UART_RX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
lypinator 0:bb348c97df44 261 # if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS
lypinator 0:bb348c97df44 262 console.set_flow_control(SerialBase::RTS, STDIO_UART_RTS, NC);
lypinator 0:bb348c97df44 263 # elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_CTS
lypinator 0:bb348c97df44 264 console.set_flow_control(SerialBase::CTS, NC, STDIO_UART_CTS);
lypinator 0:bb348c97df44 265 # elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTSCTS
lypinator 0:bb348c97df44 266 console.set_flow_control(SerialBase::RTSCTS, STDIO_UART_RTS, STDIO_UART_CTS);
lypinator 0:bb348c97df44 267 # endif
lypinator 0:bb348c97df44 268 # else
lypinator 0:bb348c97df44 269 static DirectSerial console(STDIO_UART_TX, STDIO_UART_RX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
lypinator 0:bb348c97df44 270 # endif
lypinator 0:bb348c97df44 271 #else // DEVICE_SERIAL
lypinator 0:bb348c97df44 272 static Sink console;
lypinator 0:bb348c97df44 273 #endif
lypinator 0:bb348c97df44 274 return &console;
lypinator 0:bb348c97df44 275 }
lypinator 0:bb348c97df44 276
lypinator 0:bb348c97df44 277 /* Locate the default console for stdout, stdin, stderr */
lypinator 0:bb348c97df44 278 static FileHandle *get_console(int fd)
lypinator 0:bb348c97df44 279 {
lypinator 0:bb348c97df44 280 FileHandle *fh = mbed_override_console(fd);
lypinator 0:bb348c97df44 281 if (fh) {
lypinator 0:bb348c97df44 282 return fh;
lypinator 0:bb348c97df44 283 }
lypinator 0:bb348c97df44 284 fh = mbed_target_override_console(fd);
lypinator 0:bb348c97df44 285 if (fh) {
lypinator 0:bb348c97df44 286 return fh;
lypinator 0:bb348c97df44 287 }
lypinator 0:bb348c97df44 288 return default_console();
lypinator 0:bb348c97df44 289 }
lypinator 0:bb348c97df44 290
lypinator 0:bb348c97df44 291 /* Deal with the fact C library may not _open descriptors 0, 1, 2 - auto bind */
lypinator 0:bb348c97df44 292 static FileHandle *get_fhc(int fd)
lypinator 0:bb348c97df44 293 {
lypinator 0:bb348c97df44 294 if (fd >= OPEN_MAX) {
lypinator 0:bb348c97df44 295 return NULL;
lypinator 0:bb348c97df44 296 }
lypinator 0:bb348c97df44 297 FileHandle *fh = filehandles[fd];
lypinator 0:bb348c97df44 298 if (fh == FILE_HANDLE_RESERVED && fd < 3) {
lypinator 0:bb348c97df44 299 filehandles[fd] = fh = get_console(fd);
lypinator 0:bb348c97df44 300 }
lypinator 0:bb348c97df44 301 return fh;
lypinator 0:bb348c97df44 302 }
lypinator 0:bb348c97df44 303
lypinator 0:bb348c97df44 304 /**
lypinator 0:bb348c97df44 305 * Sets errno when file opening fails.
lypinator 0:bb348c97df44 306 * Wipes out the filehandle too.
lypinator 0:bb348c97df44 307 *
lypinator 0:bb348c97df44 308 * @param error is a negative error code returned from an mbed function and
lypinator 0:bb348c97df44 309 * will be negated to store a positive error code in errno
lypinator 0:bb348c97df44 310 */
lypinator 0:bb348c97df44 311 static int handle_open_errors(int error, unsigned filehandle_idx)
lypinator 0:bb348c97df44 312 {
lypinator 0:bb348c97df44 313 errno = -error;
lypinator 0:bb348c97df44 314 // Free file handle
lypinator 0:bb348c97df44 315 filehandles[filehandle_idx] = NULL;
lypinator 0:bb348c97df44 316 return -1;
lypinator 0:bb348c97df44 317 }
lypinator 0:bb348c97df44 318
lypinator 0:bb348c97df44 319 static inline int openflags_to_posix(int openflags)
lypinator 0:bb348c97df44 320 {
lypinator 0:bb348c97df44 321 int posix = openflags;
lypinator 0:bb348c97df44 322 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 323 if (openflags & OPEN_PLUS) {
lypinator 0:bb348c97df44 324 posix = O_RDWR;
lypinator 0:bb348c97df44 325 } else if (openflags & OPEN_W) {
lypinator 0:bb348c97df44 326 posix = O_WRONLY;
lypinator 0:bb348c97df44 327 } else if (openflags & OPEN_A) {
lypinator 0:bb348c97df44 328 posix = O_WRONLY | O_APPEND;
lypinator 0:bb348c97df44 329 } else {
lypinator 0:bb348c97df44 330 posix = O_RDONLY;
lypinator 0:bb348c97df44 331 }
lypinator 0:bb348c97df44 332 /* a, w, a+, w+ all create if file does not already exist */
lypinator 0:bb348c97df44 333 if (openflags & (OPEN_A | OPEN_W)) {
lypinator 0:bb348c97df44 334 posix |= O_CREAT;
lypinator 0:bb348c97df44 335 }
lypinator 0:bb348c97df44 336 /* w and w+ truncate */
lypinator 0:bb348c97df44 337 if (openflags & OPEN_W) {
lypinator 0:bb348c97df44 338 posix |= O_TRUNC;
lypinator 0:bb348c97df44 339 }
lypinator 0:bb348c97df44 340 #elif defined(__ICCARM__)
lypinator 0:bb348c97df44 341 switch (openflags & _LLIO_RDWRMASK) {
lypinator 0:bb348c97df44 342 case _LLIO_RDONLY:
lypinator 0:bb348c97df44 343 posix = O_RDONLY;
lypinator 0:bb348c97df44 344 break;
lypinator 0:bb348c97df44 345 case _LLIO_WRONLY:
lypinator 0:bb348c97df44 346 posix = O_WRONLY;
lypinator 0:bb348c97df44 347 break;
lypinator 0:bb348c97df44 348 case _LLIO_RDWR :
lypinator 0:bb348c97df44 349 posix = O_RDWR ;
lypinator 0:bb348c97df44 350 break;
lypinator 0:bb348c97df44 351 }
lypinator 0:bb348c97df44 352 if (openflags & _LLIO_CREAT) {
lypinator 0:bb348c97df44 353 posix |= O_CREAT;
lypinator 0:bb348c97df44 354 }
lypinator 0:bb348c97df44 355 if (openflags & _LLIO_APPEND) {
lypinator 0:bb348c97df44 356 posix |= O_APPEND;
lypinator 0:bb348c97df44 357 }
lypinator 0:bb348c97df44 358 if (openflags & _LLIO_TRUNC) {
lypinator 0:bb348c97df44 359 posix |= O_TRUNC;
lypinator 0:bb348c97df44 360 }
lypinator 0:bb348c97df44 361 #elif defined(TOOLCHAIN_GCC)
lypinator 0:bb348c97df44 362 posix &= ~O_BINARY;
lypinator 0:bb348c97df44 363 #endif
lypinator 0:bb348c97df44 364 return posix;
lypinator 0:bb348c97df44 365 }
lypinator 0:bb348c97df44 366
lypinator 0:bb348c97df44 367 static int reserve_filehandle()
lypinator 0:bb348c97df44 368 {
lypinator 0:bb348c97df44 369 // find the first empty slot in filehandles, after the slots reserved for stdin/stdout/stderr
lypinator 0:bb348c97df44 370 filehandle_mutex->lock();
lypinator 0:bb348c97df44 371 int fh_i;
lypinator 0:bb348c97df44 372 for (fh_i = 3; fh_i < OPEN_MAX; fh_i++) {
lypinator 0:bb348c97df44 373 /* Take a next free filehandle slot available. */
lypinator 0:bb348c97df44 374 if (filehandles[fh_i] == NULL) {
lypinator 0:bb348c97df44 375 break;
lypinator 0:bb348c97df44 376 }
lypinator 0:bb348c97df44 377 }
lypinator 0:bb348c97df44 378 if (fh_i >= OPEN_MAX) {
lypinator 0:bb348c97df44 379 /* Too many file handles have been opened */
lypinator 0:bb348c97df44 380 errno = EMFILE;
lypinator 0:bb348c97df44 381 filehandle_mutex->unlock();
lypinator 0:bb348c97df44 382 return -1;
lypinator 0:bb348c97df44 383 }
lypinator 0:bb348c97df44 384 filehandles[fh_i] = FILE_HANDLE_RESERVED;
lypinator 0:bb348c97df44 385 filehandle_mutex->unlock();
lypinator 0:bb348c97df44 386
lypinator 0:bb348c97df44 387 return fh_i;
lypinator 0:bb348c97df44 388 }
lypinator 0:bb348c97df44 389
lypinator 0:bb348c97df44 390 int mbed::bind_to_fd(FileHandle *fh)
lypinator 0:bb348c97df44 391 {
lypinator 0:bb348c97df44 392 int fildes = reserve_filehandle();
lypinator 0:bb348c97df44 393 if (fildes < 0) {
lypinator 0:bb348c97df44 394 return fildes;
lypinator 0:bb348c97df44 395 }
lypinator 0:bb348c97df44 396
lypinator 0:bb348c97df44 397 filehandles[fildes] = fh;
lypinator 0:bb348c97df44 398 stdio_in_prev[fildes] = 0;
lypinator 0:bb348c97df44 399 stdio_out_prev[fildes] = 0;
lypinator 0:bb348c97df44 400
lypinator 0:bb348c97df44 401 return fildes;
lypinator 0:bb348c97df44 402 }
lypinator 0:bb348c97df44 403
lypinator 0:bb348c97df44 404 static int unbind_from_fd(int fd, FileHandle *fh)
lypinator 0:bb348c97df44 405 {
lypinator 0:bb348c97df44 406 if (filehandles[fd] == fh) {
lypinator 0:bb348c97df44 407 filehandles[fd] = NULL;
lypinator 0:bb348c97df44 408 return 0;
lypinator 0:bb348c97df44 409 } else {
lypinator 0:bb348c97df44 410 errno = EBADF;
lypinator 0:bb348c97df44 411 return -1;
lypinator 0:bb348c97df44 412 }
lypinator 0:bb348c97df44 413 }
lypinator 0:bb348c97df44 414
lypinator 0:bb348c97df44 415 #ifndef __IAR_SYSTEMS_ICC__
lypinator 0:bb348c97df44 416 /* IAR provides fdopen itself */
lypinator 0:bb348c97df44 417 extern "C" std::FILE *fdopen(int fildes, const char *mode)
lypinator 0:bb348c97df44 418 {
lypinator 0:bb348c97df44 419 // This is to avoid scanf and the bloat it brings.
lypinator 0:bb348c97df44 420 char buf[1 + sizeof fildes]; /* @(integer) */
lypinator 0:bb348c97df44 421 MBED_STATIC_ASSERT(sizeof buf == 5, "Integers should be 4 bytes.");
lypinator 0:bb348c97df44 422 buf[0] = '@';
lypinator 0:bb348c97df44 423 memcpy(buf + 1, &fildes, sizeof fildes);
lypinator 0:bb348c97df44 424
lypinator 0:bb348c97df44 425 std::FILE *stream = std::fopen(buf, mode);
lypinator 0:bb348c97df44 426 /* newlib-nano doesn't appear to ever call _isatty itself, so
lypinator 0:bb348c97df44 427 * happily fully buffers an interactive stream. Deal with that here.
lypinator 0:bb348c97df44 428 */
lypinator 0:bb348c97df44 429 if (stream && isatty(fildes)) {
lypinator 0:bb348c97df44 430 mbed_set_unbuffered_stream(stream);
lypinator 0:bb348c97df44 431 }
lypinator 0:bb348c97df44 432 return stream;
lypinator 0:bb348c97df44 433 }
lypinator 0:bb348c97df44 434 #endif
lypinator 0:bb348c97df44 435
lypinator 0:bb348c97df44 436 namespace mbed {
lypinator 0:bb348c97df44 437 std::FILE *fdopen(FileHandle *fh, const char *mode)
lypinator 0:bb348c97df44 438 {
lypinator 0:bb348c97df44 439 // First reserve the integer file descriptor
lypinator 0:bb348c97df44 440 int fd = bind_to_fd(fh);
lypinator 0:bb348c97df44 441 if (!fd) {
lypinator 0:bb348c97df44 442 return NULL;
lypinator 0:bb348c97df44 443 }
lypinator 0:bb348c97df44 444 // Then bind that to the C stream. If successful, C library
lypinator 0:bb348c97df44 445 // takes ownership and responsibility to close.
lypinator 0:bb348c97df44 446 std::FILE *stream = ::fdopen(fd, mode);
lypinator 0:bb348c97df44 447 if (!stream) {
lypinator 0:bb348c97df44 448 unbind_from_fd(fd, fh);
lypinator 0:bb348c97df44 449 }
lypinator 0:bb348c97df44 450 return stream;
lypinator 0:bb348c97df44 451 }
lypinator 0:bb348c97df44 452 }
lypinator 0:bb348c97df44 453
lypinator 0:bb348c97df44 454 /* @brief standard c library fopen() retargeting function.
lypinator 0:bb348c97df44 455 *
lypinator 0:bb348c97df44 456 * This function is invoked by the standard c library retargeting to handle fopen()
lypinator 0:bb348c97df44 457 *
lypinator 0:bb348c97df44 458 * @return
lypinator 0:bb348c97df44 459 * On success, a valid FILEHANDLE is returned.
lypinator 0:bb348c97df44 460 * On failure, -1 is returned and errno is set to an appropriate value e.g.
lypinator 0:bb348c97df44 461 * ENOENT file not found (default errno setting)
lypinator 0:bb348c97df44 462 * EMFILE the maximum number of open files was exceeded.
lypinator 0:bb348c97df44 463 *
lypinator 0:bb348c97df44 464 * */
lypinator 0:bb348c97df44 465 extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags)
lypinator 0:bb348c97df44 466 {
lypinator 0:bb348c97df44 467 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
lypinator 0:bb348c97df44 468 #if !defined(MBED_CONF_RTOS_PRESENT)
lypinator 0:bb348c97df44 469 // valid only for mbed 2
lypinator 0:bb348c97df44 470 // for ulib, this is invoked after RAM init, prior c++
lypinator 0:bb348c97df44 471 // used as hook, as post stack/heap is not active there
lypinator 0:bb348c97df44 472 extern void mbed_copy_nvic(void);
lypinator 0:bb348c97df44 473 extern void mbed_sdk_init(void);
lypinator 0:bb348c97df44 474
lypinator 0:bb348c97df44 475 static int mbed_sdk_inited = 0;
lypinator 0:bb348c97df44 476 if (!mbed_sdk_inited) {
lypinator 0:bb348c97df44 477 mbed_copy_nvic();
lypinator 0:bb348c97df44 478 mbed_sdk_init();
lypinator 0:bb348c97df44 479 mbed_sdk_inited = 1;
lypinator 0:bb348c97df44 480 }
lypinator 0:bb348c97df44 481 #endif
lypinator 0:bb348c97df44 482 // Before version 5.03, we were using a patched version of microlib with proper names
lypinator 0:bb348c97df44 483 // This is the workaround that the microlib author suggested us
lypinator 0:bb348c97df44 484 static int n = 0;
lypinator 0:bb348c97df44 485 if (std::strcmp(name, ":tt") == 0 && n < 3) {
lypinator 0:bb348c97df44 486 return n++;
lypinator 0:bb348c97df44 487 }
lypinator 0:bb348c97df44 488 #else
lypinator 0:bb348c97df44 489 /* Use the posix convention that stdin,out,err are filehandles 0,1,2.
lypinator 0:bb348c97df44 490 */
lypinator 0:bb348c97df44 491 if (std::strcmp(name, __stdin_name) == 0) {
lypinator 0:bb348c97df44 492 get_fhc(STDIN_FILENO);
lypinator 0:bb348c97df44 493 return STDIN_FILENO;
lypinator 0:bb348c97df44 494 } else if (std::strcmp(name, __stdout_name) == 0) {
lypinator 0:bb348c97df44 495 get_fhc(STDOUT_FILENO);
lypinator 0:bb348c97df44 496 return STDOUT_FILENO;
lypinator 0:bb348c97df44 497 } else if (std::strcmp(name, __stderr_name) == 0) {
lypinator 0:bb348c97df44 498 get_fhc(STDERR_FILENO);
lypinator 0:bb348c97df44 499 return STDERR_FILENO;
lypinator 0:bb348c97df44 500 }
lypinator 0:bb348c97df44 501 #endif
lypinator 0:bb348c97df44 502 #ifndef __IAR_SYSTEMS_ICC__
lypinator 0:bb348c97df44 503 /* FILENAME: "@(integer)" gives an already-allocated descriptor */
lypinator 0:bb348c97df44 504 if (name[0] == '@') {
lypinator 0:bb348c97df44 505 int fd;
lypinator 0:bb348c97df44 506 memcpy(&fd, name + 1, sizeof fd);
lypinator 0:bb348c97df44 507 return fd;
lypinator 0:bb348c97df44 508 }
lypinator 0:bb348c97df44 509 #endif
lypinator 0:bb348c97df44 510 return open(name, openflags_to_posix(openflags));
lypinator 0:bb348c97df44 511 }
lypinator 0:bb348c97df44 512
lypinator 0:bb348c97df44 513 extern "C" int open(const char *name, int oflag, ...)
lypinator 0:bb348c97df44 514 {
lypinator 0:bb348c97df44 515 int fildes = reserve_filehandle();
lypinator 0:bb348c97df44 516 if (fildes < 0) {
lypinator 0:bb348c97df44 517 return fildes;
lypinator 0:bb348c97df44 518 }
lypinator 0:bb348c97df44 519
lypinator 0:bb348c97df44 520 FileHandle *res = NULL;
lypinator 0:bb348c97df44 521 FilePath path(name);
lypinator 0:bb348c97df44 522
lypinator 0:bb348c97df44 523 if (!path.exists()) {
lypinator 0:bb348c97df44 524 /* The first part of the filename (between first 2 '/') is not a
lypinator 0:bb348c97df44 525 * registered mount point in the namespace.
lypinator 0:bb348c97df44 526 */
lypinator 0:bb348c97df44 527 return handle_open_errors(-ENODEV, fildes);
lypinator 0:bb348c97df44 528 }
lypinator 0:bb348c97df44 529
lypinator 0:bb348c97df44 530 if (path.isFile()) {
lypinator 0:bb348c97df44 531 res = path.file();
lypinator 0:bb348c97df44 532 } else {
lypinator 0:bb348c97df44 533 FileSystemHandle *fs = path.fileSystem();
lypinator 0:bb348c97df44 534 if (fs == NULL) {
lypinator 0:bb348c97df44 535 return handle_open_errors(-ENODEV, fildes);
lypinator 0:bb348c97df44 536 }
lypinator 0:bb348c97df44 537 int err = fs->open(&res, path.fileName(), oflag);
lypinator 0:bb348c97df44 538 if (err) {
lypinator 0:bb348c97df44 539 return handle_open_errors(err, fildes);
lypinator 0:bb348c97df44 540 }
lypinator 0:bb348c97df44 541 }
lypinator 0:bb348c97df44 542
lypinator 0:bb348c97df44 543 filehandles[fildes] = res;
lypinator 0:bb348c97df44 544 stdio_in_prev[fildes] = 0;
lypinator 0:bb348c97df44 545 stdio_out_prev[fildes] = 0;
lypinator 0:bb348c97df44 546
lypinator 0:bb348c97df44 547 return fildes;
lypinator 0:bb348c97df44 548 }
lypinator 0:bb348c97df44 549
lypinator 0:bb348c97df44 550 extern "C" int PREFIX(_close)(FILEHANDLE fh)
lypinator 0:bb348c97df44 551 {
lypinator 0:bb348c97df44 552 return close(fh);
lypinator 0:bb348c97df44 553 }
lypinator 0:bb348c97df44 554
lypinator 0:bb348c97df44 555 extern "C" int close(int fildes)
lypinator 0:bb348c97df44 556 {
lypinator 0:bb348c97df44 557 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 558 filehandles[fildes] = NULL;
lypinator 0:bb348c97df44 559 if (fhc == NULL) {
lypinator 0:bb348c97df44 560 errno = EBADF;
lypinator 0:bb348c97df44 561 return -1;
lypinator 0:bb348c97df44 562 }
lypinator 0:bb348c97df44 563
lypinator 0:bb348c97df44 564 int err = fhc->close();
lypinator 0:bb348c97df44 565 if (err < 0) {
lypinator 0:bb348c97df44 566 errno = -err;
lypinator 0:bb348c97df44 567 return -1;
lypinator 0:bb348c97df44 568 } else {
lypinator 0:bb348c97df44 569 return 0;
lypinator 0:bb348c97df44 570 }
lypinator 0:bb348c97df44 571 }
lypinator 0:bb348c97df44 572
lypinator 0:bb348c97df44 573 static bool convert_crlf(int fd)
lypinator 0:bb348c97df44 574 {
lypinator 0:bb348c97df44 575 #if MBED_CONF_PLATFORM_STDIO_CONVERT_TTY_NEWLINES
lypinator 0:bb348c97df44 576 return isatty(fd);
lypinator 0:bb348c97df44 577 #elif MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
lypinator 0:bb348c97df44 578 return fd < 3 && isatty(fd);
lypinator 0:bb348c97df44 579 #else
lypinator 0:bb348c97df44 580 return false;
lypinator 0:bb348c97df44 581 #endif
lypinator 0:bb348c97df44 582 }
lypinator 0:bb348c97df44 583
lypinator 0:bb348c97df44 584 #if defined(__ICCARM__)
lypinator 0:bb348c97df44 585 extern "C" size_t __write(int fh, const unsigned char *buffer, size_t length)
lypinator 0:bb348c97df44 586 {
lypinator 0:bb348c97df44 587 #else
lypinator 0:bb348c97df44 588 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode)
lypinator 0:bb348c97df44 589 {
lypinator 0:bb348c97df44 590 #endif
lypinator 0:bb348c97df44 591
lypinator 0:bb348c97df44 592 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT)
lypinator 0:bb348c97df44 593 if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
lypinator 0:bb348c97df44 594 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PROHIBITED_IN_ISR_CONTEXT), "Error - writing to a file in an ISR or critical section\r\n", fh);
lypinator 0:bb348c97df44 595 }
lypinator 0:bb348c97df44 596 #endif
lypinator 0:bb348c97df44 597
lypinator 0:bb348c97df44 598 if (length > SSIZE_MAX) {
lypinator 0:bb348c97df44 599 errno = EINVAL;
lypinator 0:bb348c97df44 600 return -1;
lypinator 0:bb348c97df44 601 }
lypinator 0:bb348c97df44 602
lypinator 0:bb348c97df44 603 ssize_t slength = length;
lypinator 0:bb348c97df44 604 ssize_t written = 0;
lypinator 0:bb348c97df44 605
lypinator 0:bb348c97df44 606 if (convert_crlf(fh)) {
lypinator 0:bb348c97df44 607 // local prev is previous in buffer during seek
lypinator 0:bb348c97df44 608 // stdio_out_prev[fh] is last thing actually written
lypinator 0:bb348c97df44 609 char prev = stdio_out_prev[fh];
lypinator 0:bb348c97df44 610 // Seek for '\n' without preceding '\r'; if found flush
lypinator 0:bb348c97df44 611 // preceding and insert '\r'. Continue until end of input.
lypinator 0:bb348c97df44 612 for (ssize_t cur = 0; cur < slength; cur++) {
lypinator 0:bb348c97df44 613 if (buffer[cur] == '\n' && prev != '\r') {
lypinator 0:bb348c97df44 614 ssize_t r;
lypinator 0:bb348c97df44 615 // flush stuff preceding the \n
lypinator 0:bb348c97df44 616 if (cur > written) {
lypinator 0:bb348c97df44 617 r = write(fh, buffer + written, cur - written);
lypinator 0:bb348c97df44 618 if (r < 0) {
lypinator 0:bb348c97df44 619 return -1;
lypinator 0:bb348c97df44 620 }
lypinator 0:bb348c97df44 621 written += r;
lypinator 0:bb348c97df44 622 if (written < cur) {
lypinator 0:bb348c97df44 623 // For some reason, didn't write all - give up now
lypinator 0:bb348c97df44 624 goto finish;
lypinator 0:bb348c97df44 625 }
lypinator 0:bb348c97df44 626 stdio_out_prev[fh] = prev;
lypinator 0:bb348c97df44 627 }
lypinator 0:bb348c97df44 628 // insert a \r now, leaving the \n still to be written
lypinator 0:bb348c97df44 629 r = write(fh, "\r", 1);
lypinator 0:bb348c97df44 630 if (r < 0) {
lypinator 0:bb348c97df44 631 return -1;
lypinator 0:bb348c97df44 632 }
lypinator 0:bb348c97df44 633 if (r < 1) {
lypinator 0:bb348c97df44 634 goto finish;
lypinator 0:bb348c97df44 635 }
lypinator 0:bb348c97df44 636 stdio_out_prev[fh] = '\r';
lypinator 0:bb348c97df44 637 }
lypinator 0:bb348c97df44 638 prev = buffer[cur];
lypinator 0:bb348c97df44 639 }
lypinator 0:bb348c97df44 640 }
lypinator 0:bb348c97df44 641
lypinator 0:bb348c97df44 642 // Flush remaining from conversion, or the whole thing if no conversion
lypinator 0:bb348c97df44 643 if (written < slength) {
lypinator 0:bb348c97df44 644 ssize_t r = write(fh, buffer + written, slength - written);
lypinator 0:bb348c97df44 645 if (r < 0) {
lypinator 0:bb348c97df44 646 return -1;
lypinator 0:bb348c97df44 647 }
lypinator 0:bb348c97df44 648 written += r;
lypinator 0:bb348c97df44 649 if (written > 0) {
lypinator 0:bb348c97df44 650 stdio_out_prev[fh] = buffer[written - 1];
lypinator 0:bb348c97df44 651 }
lypinator 0:bb348c97df44 652 }
lypinator 0:bb348c97df44 653
lypinator 0:bb348c97df44 654 finish:
lypinator 0:bb348c97df44 655 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 656 if (written >= 0) {
lypinator 0:bb348c97df44 657 return slength - written;
lypinator 0:bb348c97df44 658 } else {
lypinator 0:bb348c97df44 659 return written;
lypinator 0:bb348c97df44 660 }
lypinator 0:bb348c97df44 661 #else
lypinator 0:bb348c97df44 662 return written;
lypinator 0:bb348c97df44 663 #endif
lypinator 0:bb348c97df44 664 }
lypinator 0:bb348c97df44 665
lypinator 0:bb348c97df44 666 extern "C" ssize_t write(int fildes, const void *buf, size_t length)
lypinator 0:bb348c97df44 667 {
lypinator 0:bb348c97df44 668
lypinator 0:bb348c97df44 669 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 670 if (fhc == NULL) {
lypinator 0:bb348c97df44 671 errno = EBADF;
lypinator 0:bb348c97df44 672 return -1;
lypinator 0:bb348c97df44 673 }
lypinator 0:bb348c97df44 674
lypinator 0:bb348c97df44 675 ssize_t ret = fhc->write(buf, length);
lypinator 0:bb348c97df44 676 if (ret < 0) {
lypinator 0:bb348c97df44 677 errno = -ret;
lypinator 0:bb348c97df44 678 return -1;
lypinator 0:bb348c97df44 679 } else {
lypinator 0:bb348c97df44 680 return ret;
lypinator 0:bb348c97df44 681 }
lypinator 0:bb348c97df44 682 }
lypinator 0:bb348c97df44 683
lypinator 0:bb348c97df44 684 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
lypinator 0:bb348c97df44 685 extern "C" void PREFIX(_exit)(int return_code)
lypinator 0:bb348c97df44 686 {
lypinator 0:bb348c97df44 687 while (1) {}
lypinator 0:bb348c97df44 688 }
lypinator 0:bb348c97df44 689
lypinator 0:bb348c97df44 690 extern "C" void _ttywrch(int ch)
lypinator 0:bb348c97df44 691 {
lypinator 0:bb348c97df44 692 char c = ch;
lypinator 0:bb348c97df44 693 write(STDOUT_FILENO, &c, 1);
lypinator 0:bb348c97df44 694 }
lypinator 0:bb348c97df44 695 #endif
lypinator 0:bb348c97df44 696
lypinator 0:bb348c97df44 697 #if defined(__ICCARM__)
lypinator 0:bb348c97df44 698 extern "C" size_t __read(int fh, unsigned char *buffer, size_t length)
lypinator 0:bb348c97df44 699 {
lypinator 0:bb348c97df44 700 #else
lypinator 0:bb348c97df44 701 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode)
lypinator 0:bb348c97df44 702 {
lypinator 0:bb348c97df44 703 #endif
lypinator 0:bb348c97df44 704
lypinator 0:bb348c97df44 705 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT)
lypinator 0:bb348c97df44 706 if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
lypinator 0:bb348c97df44 707 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_PROHIBITED_IN_ISR_CONTEXT), "Error - reading from a file in an ISR or critical section\r\n", fh);
lypinator 0:bb348c97df44 708 }
lypinator 0:bb348c97df44 709 #endif
lypinator 0:bb348c97df44 710
lypinator 0:bb348c97df44 711 if (length > SSIZE_MAX) {
lypinator 0:bb348c97df44 712 errno = EINVAL;
lypinator 0:bb348c97df44 713 return -1;
lypinator 0:bb348c97df44 714 }
lypinator 0:bb348c97df44 715
lypinator 0:bb348c97df44 716 ssize_t bytes_read = 0;
lypinator 0:bb348c97df44 717
lypinator 0:bb348c97df44 718 if (convert_crlf(fh)) {
lypinator 0:bb348c97df44 719 while (true) {
lypinator 0:bb348c97df44 720 char c;
lypinator 0:bb348c97df44 721 ssize_t r = read(fh, &c, 1);
lypinator 0:bb348c97df44 722 if (r < 0) {
lypinator 0:bb348c97df44 723 return -1;
lypinator 0:bb348c97df44 724 }
lypinator 0:bb348c97df44 725 if (r == 0) {
lypinator 0:bb348c97df44 726 return bytes_read;
lypinator 0:bb348c97df44 727 }
lypinator 0:bb348c97df44 728 if ((c == '\r' && stdio_in_prev[fh] != '\n') ||
lypinator 0:bb348c97df44 729 (c == '\n' && stdio_in_prev[fh] != '\r')) {
lypinator 0:bb348c97df44 730 stdio_in_prev[fh] = c;
lypinator 0:bb348c97df44 731 *buffer = '\n';
lypinator 0:bb348c97df44 732 break;
lypinator 0:bb348c97df44 733 } else if ((c == '\r' && stdio_in_prev[fh] == '\n') ||
lypinator 0:bb348c97df44 734 (c == '\n' && stdio_in_prev[fh] == '\r')) {
lypinator 0:bb348c97df44 735 stdio_in_prev[fh] = c;
lypinator 0:bb348c97df44 736 continue;
lypinator 0:bb348c97df44 737 } else {
lypinator 0:bb348c97df44 738 stdio_in_prev[fh] = c;
lypinator 0:bb348c97df44 739 *buffer = c;
lypinator 0:bb348c97df44 740 break;
lypinator 0:bb348c97df44 741 }
lypinator 0:bb348c97df44 742 }
lypinator 0:bb348c97df44 743 bytes_read = 1;
lypinator 0:bb348c97df44 744 } else {
lypinator 0:bb348c97df44 745 bytes_read = read(fh, buffer, length);
lypinator 0:bb348c97df44 746 }
lypinator 0:bb348c97df44 747
lypinator 0:bb348c97df44 748 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 749 if (bytes_read < 0) {
lypinator 0:bb348c97df44 750 return -1;
lypinator 0:bb348c97df44 751 } else if (bytes_read == 0) {
lypinator 0:bb348c97df44 752 return 0x80000000 | length; // weird EOF indication
lypinator 0:bb348c97df44 753 } else {
lypinator 0:bb348c97df44 754 return (ssize_t)length - bytes_read;
lypinator 0:bb348c97df44 755 }
lypinator 0:bb348c97df44 756 #else
lypinator 0:bb348c97df44 757 return bytes_read;
lypinator 0:bb348c97df44 758 #endif
lypinator 0:bb348c97df44 759 }
lypinator 0:bb348c97df44 760
lypinator 0:bb348c97df44 761 extern "C" ssize_t read(int fildes, void *buf, size_t length)
lypinator 0:bb348c97df44 762 {
lypinator 0:bb348c97df44 763
lypinator 0:bb348c97df44 764 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 765 if (fhc == NULL) {
lypinator 0:bb348c97df44 766 errno = EBADF;
lypinator 0:bb348c97df44 767 return -1;
lypinator 0:bb348c97df44 768 }
lypinator 0:bb348c97df44 769
lypinator 0:bb348c97df44 770 ssize_t ret = fhc->read(buf, length);
lypinator 0:bb348c97df44 771 if (ret < 0) {
lypinator 0:bb348c97df44 772 errno = -ret;
lypinator 0:bb348c97df44 773 return -1;
lypinator 0:bb348c97df44 774 } else {
lypinator 0:bb348c97df44 775 return ret;
lypinator 0:bb348c97df44 776 }
lypinator 0:bb348c97df44 777 }
lypinator 0:bb348c97df44 778
lypinator 0:bb348c97df44 779
lypinator 0:bb348c97df44 780 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 781 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
lypinator 0:bb348c97df44 782 #else
lypinator 0:bb348c97df44 783 extern "C" int _isatty(FILEHANDLE fh)
lypinator 0:bb348c97df44 784 #endif
lypinator 0:bb348c97df44 785 {
lypinator 0:bb348c97df44 786 return isatty(fh);
lypinator 0:bb348c97df44 787 }
lypinator 0:bb348c97df44 788
lypinator 0:bb348c97df44 789 extern "C" int isatty(int fildes)
lypinator 0:bb348c97df44 790 {
lypinator 0:bb348c97df44 791 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 792 if (fhc == NULL) {
lypinator 0:bb348c97df44 793 errno = EBADF;
lypinator 0:bb348c97df44 794 return 0;
lypinator 0:bb348c97df44 795 }
lypinator 0:bb348c97df44 796
lypinator 0:bb348c97df44 797 int tty = fhc->isatty();
lypinator 0:bb348c97df44 798 if (tty < 0) {
lypinator 0:bb348c97df44 799 errno = -tty;
lypinator 0:bb348c97df44 800 return 0;
lypinator 0:bb348c97df44 801 } else {
lypinator 0:bb348c97df44 802 return tty;
lypinator 0:bb348c97df44 803 }
lypinator 0:bb348c97df44 804 }
lypinator 0:bb348c97df44 805
lypinator 0:bb348c97df44 806 extern "C"
lypinator 0:bb348c97df44 807 #if defined(__ARMCC_VERSION)
lypinator 0:bb348c97df44 808 int _sys_seek(FILEHANDLE fh, long offset)
lypinator 0:bb348c97df44 809 #elif defined(__ICCARM__)
lypinator 0:bb348c97df44 810 long __lseek(int fh, long offset, int whence)
lypinator 0:bb348c97df44 811 #else
lypinator 0:bb348c97df44 812 int _lseek(FILEHANDLE fh, int offset, int whence)
lypinator 0:bb348c97df44 813 #endif
lypinator 0:bb348c97df44 814 {
lypinator 0:bb348c97df44 815 #if defined(__ARMCC_VERSION)
lypinator 0:bb348c97df44 816 int whence = SEEK_SET;
lypinator 0:bb348c97df44 817 #endif
lypinator 0:bb348c97df44 818
lypinator 0:bb348c97df44 819 off_t off = lseek(fh, offset, whence);
lypinator 0:bb348c97df44 820 // Assuming INT_MAX = LONG_MAX, so we don't care about prototype difference
lypinator 0:bb348c97df44 821 if (off > INT_MAX) {
lypinator 0:bb348c97df44 822 errno = EOVERFLOW;
lypinator 0:bb348c97df44 823 return -1;
lypinator 0:bb348c97df44 824 }
lypinator 0:bb348c97df44 825 return off;
lypinator 0:bb348c97df44 826 }
lypinator 0:bb348c97df44 827
lypinator 0:bb348c97df44 828 extern "C" off_t lseek(int fildes, off_t offset, int whence)
lypinator 0:bb348c97df44 829 {
lypinator 0:bb348c97df44 830 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 831 if (fhc == NULL) {
lypinator 0:bb348c97df44 832 errno = EBADF;
lypinator 0:bb348c97df44 833 return -1;
lypinator 0:bb348c97df44 834 }
lypinator 0:bb348c97df44 835
lypinator 0:bb348c97df44 836 off_t off = fhc->seek(offset, whence);
lypinator 0:bb348c97df44 837 if (off < 0) {
lypinator 0:bb348c97df44 838 errno = -off;
lypinator 0:bb348c97df44 839 return -1;
lypinator 0:bb348c97df44 840 }
lypinator 0:bb348c97df44 841 return off;
lypinator 0:bb348c97df44 842 }
lypinator 0:bb348c97df44 843
lypinator 0:bb348c97df44 844 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 845 extern "C" int PREFIX(_ensure)(FILEHANDLE fh)
lypinator 0:bb348c97df44 846 {
lypinator 0:bb348c97df44 847 return fsync(fh);
lypinator 0:bb348c97df44 848 }
lypinator 0:bb348c97df44 849 #endif
lypinator 0:bb348c97df44 850
lypinator 0:bb348c97df44 851 extern "C" int fsync(int fildes)
lypinator 0:bb348c97df44 852 {
lypinator 0:bb348c97df44 853 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 854 if (fhc == NULL) {
lypinator 0:bb348c97df44 855 errno = EBADF;
lypinator 0:bb348c97df44 856 return -1;
lypinator 0:bb348c97df44 857 }
lypinator 0:bb348c97df44 858
lypinator 0:bb348c97df44 859 int err = fhc->sync();
lypinator 0:bb348c97df44 860 if (err < 0) {
lypinator 0:bb348c97df44 861 errno = -err;
lypinator 0:bb348c97df44 862 return -1;
lypinator 0:bb348c97df44 863 } else {
lypinator 0:bb348c97df44 864 return 0;
lypinator 0:bb348c97df44 865 }
lypinator 0:bb348c97df44 866 }
lypinator 0:bb348c97df44 867
lypinator 0:bb348c97df44 868 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 869 extern "C" long PREFIX(_flen)(FILEHANDLE fh)
lypinator 0:bb348c97df44 870 {
lypinator 0:bb348c97df44 871 FileHandle *fhc = get_fhc(fh);
lypinator 0:bb348c97df44 872 if (fhc == NULL) {
lypinator 0:bb348c97df44 873 errno = EBADF;
lypinator 0:bb348c97df44 874 return -1;
lypinator 0:bb348c97df44 875 }
lypinator 0:bb348c97df44 876
lypinator 0:bb348c97df44 877 off_t size = fhc->size();
lypinator 0:bb348c97df44 878 if (size < 0) {
lypinator 0:bb348c97df44 879 errno = -size;
lypinator 0:bb348c97df44 880 return -1;
lypinator 0:bb348c97df44 881 }
lypinator 0:bb348c97df44 882 if (size > LONG_MAX) {
lypinator 0:bb348c97df44 883 errno = EOVERFLOW;
lypinator 0:bb348c97df44 884 return -1;
lypinator 0:bb348c97df44 885 }
lypinator 0:bb348c97df44 886 return size;
lypinator 0:bb348c97df44 887 }
lypinator 0:bb348c97df44 888
lypinator 0:bb348c97df44 889 extern "C" char Image$$RW_IRAM1$$ZI$$Limit[];
lypinator 0:bb348c97df44 890
lypinator 0:bb348c97df44 891 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)
lypinator 0:bb348c97df44 892 {
lypinator 0:bb348c97df44 893 uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
lypinator 0:bb348c97df44 894 uint32_t sp_limit = __current_sp();
lypinator 0:bb348c97df44 895
lypinator 0:bb348c97df44 896 zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
lypinator 0:bb348c97df44 897
lypinator 0:bb348c97df44 898 struct __initial_stackheap r;
lypinator 0:bb348c97df44 899 r.heap_base = zi_limit;
lypinator 0:bb348c97df44 900 r.heap_limit = sp_limit;
lypinator 0:bb348c97df44 901 return r;
lypinator 0:bb348c97df44 902 }
lypinator 0:bb348c97df44 903
lypinator 0:bb348c97df44 904 extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
lypinator 0:bb348c97df44 905 {
lypinator 0:bb348c97df44 906 return _mbed_user_setup_stackheap(R0, R1, R2, R3);
lypinator 0:bb348c97df44 907 }
lypinator 0:bb348c97df44 908
lypinator 0:bb348c97df44 909 #endif
lypinator 0:bb348c97df44 910
lypinator 0:bb348c97df44 911
lypinator 0:bb348c97df44 912 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
lypinator 0:bb348c97df44 913 extern "C" int _fstat(int fh, struct stat *st)
lypinator 0:bb348c97df44 914 {
lypinator 0:bb348c97df44 915 return fstat(fh, st);
lypinator 0:bb348c97df44 916 }
lypinator 0:bb348c97df44 917 #endif
lypinator 0:bb348c97df44 918
lypinator 0:bb348c97df44 919 extern "C" int fstat(int fildes, struct stat *st)
lypinator 0:bb348c97df44 920 {
lypinator 0:bb348c97df44 921 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 922 if (fhc == NULL) {
lypinator 0:bb348c97df44 923 errno = EBADF;
lypinator 0:bb348c97df44 924 return -1;
lypinator 0:bb348c97df44 925 }
lypinator 0:bb348c97df44 926
lypinator 0:bb348c97df44 927 st->st_mode = fhc->isatty() ? S_IFCHR : S_IFREG;
lypinator 0:bb348c97df44 928 st->st_size = fhc->size();
lypinator 0:bb348c97df44 929 return 0;
lypinator 0:bb348c97df44 930 }
lypinator 0:bb348c97df44 931
lypinator 0:bb348c97df44 932 extern "C" int fcntl(int fildes, int cmd, ...)
lypinator 0:bb348c97df44 933 {
lypinator 0:bb348c97df44 934 FileHandle *fhc = get_fhc(fildes);
lypinator 0:bb348c97df44 935 if (fhc == NULL) {
lypinator 0:bb348c97df44 936 errno = EBADF;
lypinator 0:bb348c97df44 937 return -1;
lypinator 0:bb348c97df44 938 }
lypinator 0:bb348c97df44 939
lypinator 0:bb348c97df44 940 switch (cmd) {
lypinator 0:bb348c97df44 941 case F_GETFL: {
lypinator 0:bb348c97df44 942 int flags = 0;
lypinator 0:bb348c97df44 943 if (fhc->is_blocking()) {
lypinator 0:bb348c97df44 944 flags |= O_NONBLOCK;
lypinator 0:bb348c97df44 945 }
lypinator 0:bb348c97df44 946 return flags;
lypinator 0:bb348c97df44 947 }
lypinator 0:bb348c97df44 948 case F_SETFL: {
lypinator 0:bb348c97df44 949 va_list ap;
lypinator 0:bb348c97df44 950 va_start(ap, cmd);
lypinator 0:bb348c97df44 951 int flags = va_arg(ap, int);
lypinator 0:bb348c97df44 952 va_end(ap);
lypinator 0:bb348c97df44 953 int ret = fhc->set_blocking(flags & O_NONBLOCK);
lypinator 0:bb348c97df44 954 if (ret < 0) {
lypinator 0:bb348c97df44 955 errno = -ret;
lypinator 0:bb348c97df44 956 return -1;
lypinator 0:bb348c97df44 957 }
lypinator 0:bb348c97df44 958 return 0;
lypinator 0:bb348c97df44 959 }
lypinator 0:bb348c97df44 960
lypinator 0:bb348c97df44 961 default: {
lypinator 0:bb348c97df44 962 errno = EINVAL;
lypinator 0:bb348c97df44 963 return -1;
lypinator 0:bb348c97df44 964 }
lypinator 0:bb348c97df44 965 }
lypinator 0:bb348c97df44 966 }
lypinator 0:bb348c97df44 967
lypinator 0:bb348c97df44 968 extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout)
lypinator 0:bb348c97df44 969 {
lypinator 0:bb348c97df44 970 if (nfds > OPEN_MAX) {
lypinator 0:bb348c97df44 971 errno = EINVAL;
lypinator 0:bb348c97df44 972 return -1;
lypinator 0:bb348c97df44 973 }
lypinator 0:bb348c97df44 974
lypinator 0:bb348c97df44 975 struct mbed::pollfh fhs[OPEN_MAX];
lypinator 0:bb348c97df44 976 for (nfds_t n = 0; n < nfds; n++) {
lypinator 0:bb348c97df44 977 // Underlying FileHandle poll returns POLLNVAL if given NULL, so
lypinator 0:bb348c97df44 978 // we don't need to take special action.
lypinator 0:bb348c97df44 979 fhs[n].fh = get_fhc(fds[n].fd);
lypinator 0:bb348c97df44 980 fhs[n].events = fds[n].events;
lypinator 0:bb348c97df44 981 }
lypinator 0:bb348c97df44 982 int ret = poll(fhs, nfds, timeout);
lypinator 0:bb348c97df44 983 for (nfds_t n = 0; n < nfds; n++) {
lypinator 0:bb348c97df44 984 fds[n].revents = fhs[n].revents;
lypinator 0:bb348c97df44 985 }
lypinator 0:bb348c97df44 986 return ret;
lypinator 0:bb348c97df44 987 }
lypinator 0:bb348c97df44 988
lypinator 0:bb348c97df44 989 namespace std {
lypinator 0:bb348c97df44 990 extern "C" int remove(const char *path)
lypinator 0:bb348c97df44 991 {
lypinator 0:bb348c97df44 992 FilePath fp(path);
lypinator 0:bb348c97df44 993 FileSystemHandle *fs = fp.fileSystem();
lypinator 0:bb348c97df44 994 if (fs == NULL) {
lypinator 0:bb348c97df44 995 errno = ENODEV;
lypinator 0:bb348c97df44 996 return -1;
lypinator 0:bb348c97df44 997 }
lypinator 0:bb348c97df44 998
lypinator 0:bb348c97df44 999 int err = fs->remove(fp.fileName());
lypinator 0:bb348c97df44 1000 if (err < 0) {
lypinator 0:bb348c97df44 1001 errno = -err;
lypinator 0:bb348c97df44 1002 return -1;
lypinator 0:bb348c97df44 1003 } else {
lypinator 0:bb348c97df44 1004 return 0;
lypinator 0:bb348c97df44 1005 }
lypinator 0:bb348c97df44 1006 }
lypinator 0:bb348c97df44 1007
lypinator 0:bb348c97df44 1008 extern "C" int rename(const char *oldname, const char *newname)
lypinator 0:bb348c97df44 1009 {
lypinator 0:bb348c97df44 1010 FilePath fpOld(oldname);
lypinator 0:bb348c97df44 1011 FilePath fpNew(newname);
lypinator 0:bb348c97df44 1012 FileSystemHandle *fsOld = fpOld.fileSystem();
lypinator 0:bb348c97df44 1013 FileSystemHandle *fsNew = fpNew.fileSystem();
lypinator 0:bb348c97df44 1014
lypinator 0:bb348c97df44 1015 if (fsOld == NULL) {
lypinator 0:bb348c97df44 1016 errno = ENODEV;
lypinator 0:bb348c97df44 1017 return -1;
lypinator 0:bb348c97df44 1018 }
lypinator 0:bb348c97df44 1019
lypinator 0:bb348c97df44 1020 /* rename only if both files are on the same FS */
lypinator 0:bb348c97df44 1021 if (fsOld != fsNew) {
lypinator 0:bb348c97df44 1022 errno = EXDEV;
lypinator 0:bb348c97df44 1023 return -1;
lypinator 0:bb348c97df44 1024 }
lypinator 0:bb348c97df44 1025
lypinator 0:bb348c97df44 1026 int err = fsOld->rename(fpOld.fileName(), fpNew.fileName());
lypinator 0:bb348c97df44 1027 if (err < 0) {
lypinator 0:bb348c97df44 1028 errno = -err;
lypinator 0:bb348c97df44 1029 return -1;
lypinator 0:bb348c97df44 1030 } else {
lypinator 0:bb348c97df44 1031 return 0;
lypinator 0:bb348c97df44 1032 }
lypinator 0:bb348c97df44 1033 }
lypinator 0:bb348c97df44 1034
lypinator 0:bb348c97df44 1035 extern "C" char *tmpnam(char *s)
lypinator 0:bb348c97df44 1036 {
lypinator 0:bb348c97df44 1037 errno = EBADF;
lypinator 0:bb348c97df44 1038 return NULL;
lypinator 0:bb348c97df44 1039 }
lypinator 0:bb348c97df44 1040
lypinator 0:bb348c97df44 1041 extern "C" FILE *tmpfile()
lypinator 0:bb348c97df44 1042 {
lypinator 0:bb348c97df44 1043 errno = EBADF;
lypinator 0:bb348c97df44 1044 return NULL;
lypinator 0:bb348c97df44 1045 }
lypinator 0:bb348c97df44 1046 } // namespace std
lypinator 0:bb348c97df44 1047
lypinator 0:bb348c97df44 1048 #ifdef __ARMCC_VERSION
lypinator 0:bb348c97df44 1049 extern "C" char *_sys_command_string(char *cmd, int len)
lypinator 0:bb348c97df44 1050 {
lypinator 0:bb348c97df44 1051 return NULL;
lypinator 0:bb348c97df44 1052 }
lypinator 0:bb348c97df44 1053 #endif
lypinator 0:bb348c97df44 1054
lypinator 0:bb348c97df44 1055 extern "C" DIR *opendir(const char *path)
lypinator 0:bb348c97df44 1056 {
lypinator 0:bb348c97df44 1057 FilePath fp(path);
lypinator 0:bb348c97df44 1058 FileSystemHandle *fs = fp.fileSystem();
lypinator 0:bb348c97df44 1059 if (fs == NULL) {
lypinator 0:bb348c97df44 1060 errno = ENODEV;
lypinator 0:bb348c97df44 1061 return NULL;
lypinator 0:bb348c97df44 1062 }
lypinator 0:bb348c97df44 1063
lypinator 0:bb348c97df44 1064 DirHandle *dir;
lypinator 0:bb348c97df44 1065 int err = fs->open(&dir, fp.fileName());
lypinator 0:bb348c97df44 1066 if (err < 0) {
lypinator 0:bb348c97df44 1067 errno = -err;
lypinator 0:bb348c97df44 1068 return NULL;
lypinator 0:bb348c97df44 1069 }
lypinator 0:bb348c97df44 1070
lypinator 0:bb348c97df44 1071 return dir;
lypinator 0:bb348c97df44 1072 }
lypinator 0:bb348c97df44 1073
lypinator 0:bb348c97df44 1074 extern "C" struct dirent *readdir(DIR *dir)
lypinator 0:bb348c97df44 1075 {
lypinator 0:bb348c97df44 1076 static struct dirent ent;
lypinator 0:bb348c97df44 1077 int err = dir->read(&ent);
lypinator 0:bb348c97df44 1078 if (err < 1) {
lypinator 0:bb348c97df44 1079 if (err < 0) {
lypinator 0:bb348c97df44 1080 errno = -err;
lypinator 0:bb348c97df44 1081 }
lypinator 0:bb348c97df44 1082 return NULL;
lypinator 0:bb348c97df44 1083 }
lypinator 0:bb348c97df44 1084
lypinator 0:bb348c97df44 1085 return &ent;
lypinator 0:bb348c97df44 1086 }
lypinator 0:bb348c97df44 1087
lypinator 0:bb348c97df44 1088 extern "C" int closedir(DIR *dir)
lypinator 0:bb348c97df44 1089 {
lypinator 0:bb348c97df44 1090 int err = dir->close();
lypinator 0:bb348c97df44 1091 if (err < 0) {
lypinator 0:bb348c97df44 1092 errno = -err;
lypinator 0:bb348c97df44 1093 return -1;
lypinator 0:bb348c97df44 1094 } else {
lypinator 0:bb348c97df44 1095 return 0;
lypinator 0:bb348c97df44 1096 }
lypinator 0:bb348c97df44 1097 }
lypinator 0:bb348c97df44 1098
lypinator 0:bb348c97df44 1099 extern "C" void rewinddir(DIR *dir)
lypinator 0:bb348c97df44 1100 {
lypinator 0:bb348c97df44 1101 dir->rewind();
lypinator 0:bb348c97df44 1102 }
lypinator 0:bb348c97df44 1103
lypinator 0:bb348c97df44 1104 extern "C" off_t telldir(DIR *dir)
lypinator 0:bb348c97df44 1105 {
lypinator 0:bb348c97df44 1106 return dir->tell();
lypinator 0:bb348c97df44 1107 }
lypinator 0:bb348c97df44 1108
lypinator 0:bb348c97df44 1109 extern "C" void seekdir(DIR *dir, off_t off)
lypinator 0:bb348c97df44 1110 {
lypinator 0:bb348c97df44 1111 dir->seek(off);
lypinator 0:bb348c97df44 1112 }
lypinator 0:bb348c97df44 1113
lypinator 0:bb348c97df44 1114 extern "C" int mkdir(const char *path, mode_t mode)
lypinator 0:bb348c97df44 1115 {
lypinator 0:bb348c97df44 1116 FilePath fp(path);
lypinator 0:bb348c97df44 1117 FileSystemHandle *fs = fp.fileSystem();
lypinator 0:bb348c97df44 1118 if (fs == NULL) {
lypinator 0:bb348c97df44 1119 errno = ENODEV;
lypinator 0:bb348c97df44 1120 return -1;
lypinator 0:bb348c97df44 1121 }
lypinator 0:bb348c97df44 1122
lypinator 0:bb348c97df44 1123 int err = fs->mkdir(fp.fileName(), mode);
lypinator 0:bb348c97df44 1124 if (err < 0) {
lypinator 0:bb348c97df44 1125 errno = -err;
lypinator 0:bb348c97df44 1126 return -1;
lypinator 0:bb348c97df44 1127 } else {
lypinator 0:bb348c97df44 1128 return 0;
lypinator 0:bb348c97df44 1129 }
lypinator 0:bb348c97df44 1130 }
lypinator 0:bb348c97df44 1131
lypinator 0:bb348c97df44 1132 extern "C" int stat(const char *path, struct stat *st)
lypinator 0:bb348c97df44 1133 {
lypinator 0:bb348c97df44 1134 FilePath fp(path);
lypinator 0:bb348c97df44 1135 FileSystemHandle *fs = fp.fileSystem();
lypinator 0:bb348c97df44 1136 if (fs == NULL) {
lypinator 0:bb348c97df44 1137 errno = ENODEV;
lypinator 0:bb348c97df44 1138 return -1;
lypinator 0:bb348c97df44 1139 }
lypinator 0:bb348c97df44 1140
lypinator 0:bb348c97df44 1141 int err = fs->stat(fp.fileName(), st);
lypinator 0:bb348c97df44 1142 if (err < 0) {
lypinator 0:bb348c97df44 1143 errno = -err;
lypinator 0:bb348c97df44 1144 return -1;
lypinator 0:bb348c97df44 1145 } else {
lypinator 0:bb348c97df44 1146 return 0;
lypinator 0:bb348c97df44 1147 }
lypinator 0:bb348c97df44 1148 }
lypinator 0:bb348c97df44 1149
lypinator 0:bb348c97df44 1150 extern "C" int statvfs(const char *path, struct statvfs *buf)
lypinator 0:bb348c97df44 1151 {
lypinator 0:bb348c97df44 1152 FilePath fp(path);
lypinator 0:bb348c97df44 1153 FileSystemHandle *fs = fp.fileSystem();
lypinator 0:bb348c97df44 1154 if (fs == NULL) {
lypinator 0:bb348c97df44 1155 errno = ENODEV;
lypinator 0:bb348c97df44 1156 return -1;
lypinator 0:bb348c97df44 1157 }
lypinator 0:bb348c97df44 1158
lypinator 0:bb348c97df44 1159 int err = fs->statvfs(fp.fileName(), buf);
lypinator 0:bb348c97df44 1160 if (err < 0) {
lypinator 0:bb348c97df44 1161 errno = -err;
lypinator 0:bb348c97df44 1162 return -1;
lypinator 0:bb348c97df44 1163 } else {
lypinator 0:bb348c97df44 1164 return 0;
lypinator 0:bb348c97df44 1165 }
lypinator 0:bb348c97df44 1166 }
lypinator 0:bb348c97df44 1167
lypinator 0:bb348c97df44 1168 #if defined(TOOLCHAIN_GCC)
lypinator 0:bb348c97df44 1169 /* prevents the exception handling name demangling code getting pulled in */
lypinator 0:bb348c97df44 1170 #include "mbed_error.h"
lypinator 0:bb348c97df44 1171 namespace __gnu_cxx {
lypinator 0:bb348c97df44 1172 void __verbose_terminate_handler()
lypinator 0:bb348c97df44 1173 {
lypinator 0:bb348c97df44 1174 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_CLIB_EXCEPTION), "Exception", 0);
lypinator 0:bb348c97df44 1175 }
lypinator 0:bb348c97df44 1176 }
lypinator 0:bb348c97df44 1177 extern "C" WEAK void __cxa_pure_virtual(void);
lypinator 0:bb348c97df44 1178 extern "C" WEAK void __cxa_pure_virtual(void)
lypinator 0:bb348c97df44 1179 {
lypinator 0:bb348c97df44 1180 exit(1);
lypinator 0:bb348c97df44 1181 }
lypinator 0:bb348c97df44 1182
lypinator 0:bb348c97df44 1183 #endif
lypinator 0:bb348c97df44 1184
lypinator 0:bb348c97df44 1185 // Provide implementation of _sbrk (low-level dynamic memory allocation
lypinator 0:bb348c97df44 1186 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
lypinator 0:bb348c97df44 1187 // SP. This make it compatible with RTX RTOS thread stacks.
lypinator 0:bb348c97df44 1188 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
lypinator 0:bb348c97df44 1189
lypinator 0:bb348c97df44 1190 #if defined(TARGET_CORTEX_A)
lypinator 0:bb348c97df44 1191 extern "C" uint32_t __HeapLimit;
lypinator 0:bb348c97df44 1192 #endif
lypinator 0:bb348c97df44 1193
lypinator 0:bb348c97df44 1194 // Turn off the errno macro and use actual global variable instead.
lypinator 0:bb348c97df44 1195 #undef errno
lypinator 0:bb348c97df44 1196 extern "C" int errno;
lypinator 0:bb348c97df44 1197
lypinator 0:bb348c97df44 1198 // Dynamic memory allocation related syscall.
lypinator 0:bb348c97df44 1199 #if defined(TWO_RAM_REGIONS)
lypinator 0:bb348c97df44 1200
lypinator 0:bb348c97df44 1201 // Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
lypinator 0:bb348c97df44 1202 // __wrap__sbrk() is implemented in:
lypinator 0:bb348c97df44 1203 // TARGET_STM32L4 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4/l4_retarget.c
lypinator 0:bb348c97df44 1204 extern "C" void *__wrap__sbrk(int incr);
lypinator 0:bb348c97df44 1205 extern "C" caddr_t _sbrk(int incr)
lypinator 0:bb348c97df44 1206 {
lypinator 0:bb348c97df44 1207 return (caddr_t) __wrap__sbrk(incr);
lypinator 0:bb348c97df44 1208 }
lypinator 0:bb348c97df44 1209 #else
lypinator 0:bb348c97df44 1210 // Linker defined symbol used by _sbrk to indicate where heap should start.
lypinator 0:bb348c97df44 1211 extern "C" uint32_t __end__;
lypinator 0:bb348c97df44 1212 // Weak attribute allows user to override, e.g. to use external RAM for dynamic memory.
lypinator 0:bb348c97df44 1213 extern "C" WEAK caddr_t _sbrk(int incr)
lypinator 0:bb348c97df44 1214 {
lypinator 0:bb348c97df44 1215 static unsigned char *heap = (unsigned char *)&__end__;
lypinator 0:bb348c97df44 1216 unsigned char *prev_heap = heap;
lypinator 0:bb348c97df44 1217 unsigned char *new_heap = heap + incr;
lypinator 0:bb348c97df44 1218
lypinator 0:bb348c97df44 1219 #if defined(TARGET_CORTEX_A)
lypinator 0:bb348c97df44 1220 if (new_heap >= (unsigned char *)&__HeapLimit) { /* __HeapLimit is end of heap section */
lypinator 0:bb348c97df44 1221 #else
lypinator 0:bb348c97df44 1222 if (new_heap >= (unsigned char *)__get_MSP()) {
lypinator 0:bb348c97df44 1223 #endif
lypinator 0:bb348c97df44 1224 errno = ENOMEM;
lypinator 0:bb348c97df44 1225 return (caddr_t) -1;
lypinator 0:bb348c97df44 1226 }
lypinator 0:bb348c97df44 1227
lypinator 0:bb348c97df44 1228 // Additional heap checking if set
lypinator 0:bb348c97df44 1229 if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) {
lypinator 0:bb348c97df44 1230 errno = ENOMEM;
lypinator 0:bb348c97df44 1231 return (caddr_t) -1;
lypinator 0:bb348c97df44 1232 }
lypinator 0:bb348c97df44 1233
lypinator 0:bb348c97df44 1234 heap = new_heap;
lypinator 0:bb348c97df44 1235 return (caddr_t) prev_heap;
lypinator 0:bb348c97df44 1236 }
lypinator 0:bb348c97df44 1237 #endif
lypinator 0:bb348c97df44 1238 #endif
lypinator 0:bb348c97df44 1239
lypinator 0:bb348c97df44 1240 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
lypinator 0:bb348c97df44 1241 extern "C" void _exit(int return_code)
lypinator 0:bb348c97df44 1242 {
lypinator 0:bb348c97df44 1243 #else
lypinator 0:bb348c97df44 1244 namespace std {
lypinator 0:bb348c97df44 1245 extern "C" void exit(int return_code)
lypinator 0:bb348c97df44 1246 {
lypinator 0:bb348c97df44 1247 #endif
lypinator 0:bb348c97df44 1248
lypinator 0:bb348c97df44 1249 #if DEVICE_STDIO_MESSAGES
lypinator 0:bb348c97df44 1250 #if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
lypinator 0:bb348c97df44 1251 fflush(stdout);
lypinator 0:bb348c97df44 1252 fflush(stderr);
lypinator 0:bb348c97df44 1253 #endif
lypinator 0:bb348c97df44 1254 #endif
lypinator 0:bb348c97df44 1255
lypinator 0:bb348c97df44 1256 #if DEVICE_SEMIHOST
lypinator 0:bb348c97df44 1257 if (mbed_interface_connected()) {
lypinator 0:bb348c97df44 1258 semihost_exit();
lypinator 0:bb348c97df44 1259 }
lypinator 0:bb348c97df44 1260 #endif
lypinator 0:bb348c97df44 1261 if (return_code) {
lypinator 0:bb348c97df44 1262 mbed_die();
lypinator 0:bb348c97df44 1263 }
lypinator 0:bb348c97df44 1264
lypinator 0:bb348c97df44 1265 while (1);
lypinator 0:bb348c97df44 1266 }
lypinator 0:bb348c97df44 1267
lypinator 0:bb348c97df44 1268 #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR)
lypinator 0:bb348c97df44 1269 } //namespace std
lypinator 0:bb348c97df44 1270 #endif
lypinator 0:bb348c97df44 1271
lypinator 0:bb348c97df44 1272 #if defined(TOOLCHAIN_ARM) || defined(TOOLCHAIN_GCC)
lypinator 0:bb348c97df44 1273
lypinator 0:bb348c97df44 1274 // This series of function disable the registration of global destructors
lypinator 0:bb348c97df44 1275 // in a dynamic table which will be called when the application exit.
lypinator 0:bb348c97df44 1276 // In mbed, program never exit properly, it dies.
lypinator 0:bb348c97df44 1277 // More informations about this topic for ARMCC here:
lypinator 0:bb348c97df44 1278 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/6449.html
lypinator 0:bb348c97df44 1279 extern "C" {
lypinator 0:bb348c97df44 1280 int __aeabi_atexit(void *object, void (*dtor)(void * /*this*/), void *handle)
lypinator 0:bb348c97df44 1281 {
lypinator 0:bb348c97df44 1282 return 1;
lypinator 0:bb348c97df44 1283 }
lypinator 0:bb348c97df44 1284
lypinator 0:bb348c97df44 1285 int __cxa_atexit(void (*dtor)(void * /*this*/), void *object, void *handle)
lypinator 0:bb348c97df44 1286 {
lypinator 0:bb348c97df44 1287 return 1;
lypinator 0:bb348c97df44 1288 }
lypinator 0:bb348c97df44 1289
lypinator 0:bb348c97df44 1290 void __cxa_finalize(void *handle)
lypinator 0:bb348c97df44 1291 {
lypinator 0:bb348c97df44 1292 }
lypinator 0:bb348c97df44 1293
lypinator 0:bb348c97df44 1294 } // end of extern "C"
lypinator 0:bb348c97df44 1295
lypinator 0:bb348c97df44 1296 #endif
lypinator 0:bb348c97df44 1297
lypinator 0:bb348c97df44 1298
lypinator 0:bb348c97df44 1299 #if defined(TOOLCHAIN_GCC)
lypinator 0:bb348c97df44 1300
lypinator 0:bb348c97df44 1301 /*
lypinator 0:bb348c97df44 1302 * Depending on how newlib is configured, it is often not enough to define
lypinator 0:bb348c97df44 1303 * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the
lypinator 0:bb348c97df44 1304 * behavior regarding the registration of handlers with atexit.
lypinator 0:bb348c97df44 1305 *
lypinator 0:bb348c97df44 1306 * To overcome this limitation, exit and atexit are overriden here.
lypinator 0:bb348c97df44 1307 */
lypinator 0:bb348c97df44 1308 extern "C" {
lypinator 0:bb348c97df44 1309
lypinator 0:bb348c97df44 1310 /**
lypinator 0:bb348c97df44 1311 * @brief Retarget of exit for GCC.
lypinator 0:bb348c97df44 1312 * @details Unlike the standard version, this function doesn't call any function
lypinator 0:bb348c97df44 1313 * registered with atexit before calling _exit.
lypinator 0:bb348c97df44 1314 */
lypinator 0:bb348c97df44 1315 void __wrap_exit(int return_code)
lypinator 0:bb348c97df44 1316 {
lypinator 0:bb348c97df44 1317 _exit(return_code);
lypinator 0:bb348c97df44 1318 }
lypinator 0:bb348c97df44 1319
lypinator 0:bb348c97df44 1320 /**
lypinator 0:bb348c97df44 1321 * @brief Retarget atexit from GCC.
lypinator 0:bb348c97df44 1322 * @details This function will always fail and never register any handler to be
lypinator 0:bb348c97df44 1323 * called at exit.
lypinator 0:bb348c97df44 1324 */
lypinator 0:bb348c97df44 1325 int __wrap_atexit(void (*func)())
lypinator 0:bb348c97df44 1326 {
lypinator 0:bb348c97df44 1327 return 1;
lypinator 0:bb348c97df44 1328 }
lypinator 0:bb348c97df44 1329
lypinator 0:bb348c97df44 1330 }
lypinator 0:bb348c97df44 1331
lypinator 0:bb348c97df44 1332 #endif
lypinator 0:bb348c97df44 1333
lypinator 0:bb348c97df44 1334
lypinator 0:bb348c97df44 1335
lypinator 0:bb348c97df44 1336 namespace mbed {
lypinator 0:bb348c97df44 1337
lypinator 0:bb348c97df44 1338 void mbed_set_unbuffered_stream(std::FILE *_file)
lypinator 0:bb348c97df44 1339 {
lypinator 0:bb348c97df44 1340 #if defined (__ICCARM__)
lypinator 0:bb348c97df44 1341 char buf[2];
lypinator 0:bb348c97df44 1342 std::setvbuf(_file, buf, _IONBF, NULL);
lypinator 0:bb348c97df44 1343 #else
lypinator 0:bb348c97df44 1344 setbuf(_file, NULL);
lypinator 0:bb348c97df44 1345 #endif
lypinator 0:bb348c97df44 1346 }
lypinator 0:bb348c97df44 1347
lypinator 0:bb348c97df44 1348 int mbed_getc(std::FILE *_file)
lypinator 0:bb348c97df44 1349 {
lypinator 0:bb348c97df44 1350 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ < 8000000)
lypinator 0:bb348c97df44 1351 /*This is only valid for unbuffered streams*/
lypinator 0:bb348c97df44 1352 int res = std::fgetc(_file);
lypinator 0:bb348c97df44 1353 if (res >= 0) {
lypinator 0:bb348c97df44 1354 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
lypinator 0:bb348c97df44 1355 _file->_Rend = _file->_Wend;
lypinator 0:bb348c97df44 1356 _file->_Next = _file->_Wend;
lypinator 0:bb348c97df44 1357 }
lypinator 0:bb348c97df44 1358 return res;
lypinator 0:bb348c97df44 1359 #else
lypinator 0:bb348c97df44 1360 return std::fgetc(_file);
lypinator 0:bb348c97df44 1361 #endif
lypinator 0:bb348c97df44 1362 }
lypinator 0:bb348c97df44 1363
lypinator 0:bb348c97df44 1364 char *mbed_gets(char *s, int size, std::FILE *_file)
lypinator 0:bb348c97df44 1365 {
lypinator 0:bb348c97df44 1366 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ < 8000000)
lypinator 0:bb348c97df44 1367 /*This is only valid for unbuffered streams*/
lypinator 0:bb348c97df44 1368 char *str = fgets(s, size, _file);
lypinator 0:bb348c97df44 1369 if (str != NULL) {
lypinator 0:bb348c97df44 1370 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
lypinator 0:bb348c97df44 1371 _file->_Rend = _file->_Wend;
lypinator 0:bb348c97df44 1372 _file->_Next = _file->_Wend;
lypinator 0:bb348c97df44 1373 }
lypinator 0:bb348c97df44 1374 return str;
lypinator 0:bb348c97df44 1375 #else
lypinator 0:bb348c97df44 1376 return std::fgets(s, size, _file);
lypinator 0:bb348c97df44 1377 #endif
lypinator 0:bb348c97df44 1378 }
lypinator 0:bb348c97df44 1379
lypinator 0:bb348c97df44 1380 } // namespace mbed
lypinator 0:bb348c97df44 1381
lypinator 0:bb348c97df44 1382 #if defined (__ICCARM__)
lypinator 0:bb348c97df44 1383 // Stub out locks when an rtos is not present
lypinator 0:bb348c97df44 1384 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1385 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1386 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1387 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1388 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1389 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1390 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1391 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {}
lypinator 0:bb348c97df44 1392 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000)
lypinator 0:bb348c97df44 1393 #pragma section="__iar_tls$$DATA"
lypinator 0:bb348c97df44 1394 extern "C" WEAK void *__aeabi_read_tp(void)
lypinator 0:bb348c97df44 1395 {
lypinator 0:bb348c97df44 1396 // Thread Local storage is not supported, using main thread memory for errno
lypinator 0:bb348c97df44 1397 return __section_begin("__iar_tls$$DATA");
lypinator 0:bb348c97df44 1398 }
lypinator 0:bb348c97df44 1399 #endif
lypinator 0:bb348c97df44 1400 #elif defined(__CC_ARM)
lypinator 0:bb348c97df44 1401 // Do nothing
lypinator 0:bb348c97df44 1402 #elif defined (__GNUC__)
lypinator 0:bb348c97df44 1403 struct _reent;
lypinator 0:bb348c97df44 1404 // Stub out locks when an rtos is not present
lypinator 0:bb348c97df44 1405 extern "C" WEAK void __rtos_malloc_lock(struct _reent *_r) {}
lypinator 0:bb348c97df44 1406 extern "C" WEAK void __rtos_malloc_unlock(struct _reent *_r) {}
lypinator 0:bb348c97df44 1407 extern "C" WEAK void __rtos_env_lock(struct _reent *_r) {}
lypinator 0:bb348c97df44 1408 extern "C" WEAK void __rtos_env_unlock(struct _reent *_r) {}
lypinator 0:bb348c97df44 1409
lypinator 0:bb348c97df44 1410 extern "C" void __malloc_lock(struct _reent *_r)
lypinator 0:bb348c97df44 1411 {
lypinator 0:bb348c97df44 1412 __rtos_malloc_lock(_r);
lypinator 0:bb348c97df44 1413 }
lypinator 0:bb348c97df44 1414
lypinator 0:bb348c97df44 1415 extern "C" void __malloc_unlock(struct _reent *_r)
lypinator 0:bb348c97df44 1416 {
lypinator 0:bb348c97df44 1417 __rtos_malloc_unlock(_r);
lypinator 0:bb348c97df44 1418 }
lypinator 0:bb348c97df44 1419
lypinator 0:bb348c97df44 1420 extern "C" void __env_lock(struct _reent *_r)
lypinator 0:bb348c97df44 1421 {
lypinator 0:bb348c97df44 1422 __rtos_env_lock(_r);
lypinator 0:bb348c97df44 1423 }
lypinator 0:bb348c97df44 1424
lypinator 0:bb348c97df44 1425 extern "C" void __env_unlock(struct _reent *_r)
lypinator 0:bb348c97df44 1426 {
lypinator 0:bb348c97df44 1427 __rtos_env_unlock(_r);
lypinator 0:bb348c97df44 1428 }
lypinator 0:bb348c97df44 1429
lypinator 0:bb348c97df44 1430 #endif
lypinator 0:bb348c97df44 1431
lypinator 0:bb348c97df44 1432 #if defined (__GNUC__) || defined(__CC_ARM) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
lypinator 0:bb348c97df44 1433
lypinator 0:bb348c97df44 1434 #define CXA_GUARD_INIT_DONE (1 << 0)
lypinator 0:bb348c97df44 1435 #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1)
lypinator 0:bb348c97df44 1436 #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS)
lypinator 0:bb348c97df44 1437
lypinator 0:bb348c97df44 1438 extern "C" int __cxa_guard_acquire(int *guard_object_p)
lypinator 0:bb348c97df44 1439 {
lypinator 0:bb348c97df44 1440 uint8_t *guard_object = (uint8_t *)guard_object_p;
lypinator 0:bb348c97df44 1441 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
lypinator 0:bb348c97df44 1442 return 0;
lypinator 0:bb348c97df44 1443 }
lypinator 0:bb348c97df44 1444 singleton_lock();
lypinator 0:bb348c97df44 1445 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
lypinator 0:bb348c97df44 1446 singleton_unlock();
lypinator 0:bb348c97df44 1447 return 0;
lypinator 0:bb348c97df44 1448 }
lypinator 0:bb348c97df44 1449 MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK));
lypinator 0:bb348c97df44 1450 *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS;
lypinator 0:bb348c97df44 1451 return 1;
lypinator 0:bb348c97df44 1452 }
lypinator 0:bb348c97df44 1453
lypinator 0:bb348c97df44 1454 extern "C" void __cxa_guard_release(int *guard_object_p)
lypinator 0:bb348c97df44 1455 {
lypinator 0:bb348c97df44 1456 uint8_t *guard_object = (uint8_t *)guard_object_p;
lypinator 0:bb348c97df44 1457 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
lypinator 0:bb348c97df44 1458 *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE;
lypinator 0:bb348c97df44 1459 singleton_unlock();
lypinator 0:bb348c97df44 1460 }
lypinator 0:bb348c97df44 1461
lypinator 0:bb348c97df44 1462 extern "C" void __cxa_guard_abort(int *guard_object_p)
lypinator 0:bb348c97df44 1463 {
lypinator 0:bb348c97df44 1464 uint8_t *guard_object = (uint8_t *)guard_object_p;
lypinator 0:bb348c97df44 1465 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
lypinator 0:bb348c97df44 1466 *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS;
lypinator 0:bb348c97df44 1467 singleton_unlock();
lypinator 0:bb348c97df44 1468 }
lypinator 0:bb348c97df44 1469
lypinator 0:bb348c97df44 1470 #endif
lypinator 0:bb348c97df44 1471
lypinator 0:bb348c97df44 1472 #if defined(MBED_MEM_TRACING_ENABLED) && (defined(__CC_ARM) || defined(__ICCARM__) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)))
lypinator 0:bb348c97df44 1473
lypinator 0:bb348c97df44 1474 // If the memory tracing is enabled, the wrappers in mbed_alloc_wrappers.cpp
lypinator 0:bb348c97df44 1475 // provide the implementation for these. Note: this needs to use the wrappers
lypinator 0:bb348c97df44 1476 // instead of malloc()/free() as the caller address would point to wrappers,
lypinator 0:bb348c97df44 1477 // not the caller of "new" or "delete".
lypinator 0:bb348c97df44 1478 extern "C" void *malloc_wrapper(size_t size, const void *caller);
lypinator 0:bb348c97df44 1479 extern "C" void free_wrapper(void *ptr, const void *caller);
lypinator 0:bb348c97df44 1480
lypinator 0:bb348c97df44 1481 void *operator new (std::size_t count)
lypinator 0:bb348c97df44 1482 {
lypinator 0:bb348c97df44 1483 void *buffer = malloc_wrapper(count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1484 if (NULL == buffer) {
lypinator 0:bb348c97df44 1485 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_MEMORY), "Operator new out of memory\r\n", count);
lypinator 0:bb348c97df44 1486 }
lypinator 0:bb348c97df44 1487 return buffer;
lypinator 0:bb348c97df44 1488 }
lypinator 0:bb348c97df44 1489
lypinator 0:bb348c97df44 1490 void *operator new[](std::size_t count)
lypinator 0:bb348c97df44 1491 {
lypinator 0:bb348c97df44 1492 void *buffer = malloc_wrapper(count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1493 if (NULL == buffer) {
lypinator 0:bb348c97df44 1494 error("Operator new[] out of memory\r\n");
lypinator 0:bb348c97df44 1495 }
lypinator 0:bb348c97df44 1496 return buffer;
lypinator 0:bb348c97df44 1497 }
lypinator 0:bb348c97df44 1498
lypinator 0:bb348c97df44 1499 void *operator new (std::size_t count, const std::nothrow_t &tag)
lypinator 0:bb348c97df44 1500 {
lypinator 0:bb348c97df44 1501 return malloc_wrapper(count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1502 }
lypinator 0:bb348c97df44 1503
lypinator 0:bb348c97df44 1504 void *operator new[](std::size_t count, const std::nothrow_t &tag)
lypinator 0:bb348c97df44 1505 {
lypinator 0:bb348c97df44 1506 return malloc_wrapper(count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1507 }
lypinator 0:bb348c97df44 1508
lypinator 0:bb348c97df44 1509 void operator delete (void *ptr)
lypinator 0:bb348c97df44 1510 {
lypinator 0:bb348c97df44 1511 free_wrapper(ptr, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1512 }
lypinator 0:bb348c97df44 1513 void operator delete[](void *ptr)
lypinator 0:bb348c97df44 1514 {
lypinator 0:bb348c97df44 1515 free_wrapper(ptr, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1516 }
lypinator 0:bb348c97df44 1517
lypinator 0:bb348c97df44 1518 #elif defined(MBED_MEM_TRACING_ENABLED) && defined(__GNUC__)
lypinator 0:bb348c97df44 1519
lypinator 0:bb348c97df44 1520 #include <reent.h>
lypinator 0:bb348c97df44 1521
lypinator 0:bb348c97df44 1522 extern "C" void *malloc_wrapper(struct _reent *r, size_t size, void *caller);
lypinator 0:bb348c97df44 1523 extern "C" void free_wrapper(struct _reent *r, void *ptr, void *caller);
lypinator 0:bb348c97df44 1524
lypinator 0:bb348c97df44 1525 void *operator new (std::size_t count)
lypinator 0:bb348c97df44 1526 {
lypinator 0:bb348c97df44 1527 void *buffer = malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1528 if (NULL == buffer) {
lypinator 0:bb348c97df44 1529 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_MEMORY), "Operator new out of memory\r\n", count);
lypinator 0:bb348c97df44 1530 }
lypinator 0:bb348c97df44 1531 return buffer;
lypinator 0:bb348c97df44 1532 }
lypinator 0:bb348c97df44 1533
lypinator 0:bb348c97df44 1534 void *operator new[](std::size_t count)
lypinator 0:bb348c97df44 1535 {
lypinator 0:bb348c97df44 1536 void *buffer = malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1537 if (NULL == buffer) {
lypinator 0:bb348c97df44 1538 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_MEMORY), "Operator new out of memory\r\n", count);
lypinator 0:bb348c97df44 1539 }
lypinator 0:bb348c97df44 1540 return buffer;
lypinator 0:bb348c97df44 1541 }
lypinator 0:bb348c97df44 1542
lypinator 0:bb348c97df44 1543 void *operator new (std::size_t count, const std::nothrow_t &tag)
lypinator 0:bb348c97df44 1544 {
lypinator 0:bb348c97df44 1545 return malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1546 }
lypinator 0:bb348c97df44 1547
lypinator 0:bb348c97df44 1548 void *operator new[](std::size_t count, const std::nothrow_t &tag)
lypinator 0:bb348c97df44 1549 {
lypinator 0:bb348c97df44 1550 return malloc_wrapper(_REENT, count, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1551 }
lypinator 0:bb348c97df44 1552
lypinator 0:bb348c97df44 1553 void operator delete (void *ptr)
lypinator 0:bb348c97df44 1554 {
lypinator 0:bb348c97df44 1555 free_wrapper(_REENT, ptr, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1556 }
lypinator 0:bb348c97df44 1557
lypinator 0:bb348c97df44 1558 void operator delete[](void *ptr)
lypinator 0:bb348c97df44 1559 {
lypinator 0:bb348c97df44 1560 free_wrapper(_REENT, ptr, MBED_CALLER_ADDR());
lypinator 0:bb348c97df44 1561 }
lypinator 0:bb348c97df44 1562
lypinator 0:bb348c97df44 1563 #else
lypinator 0:bb348c97df44 1564
lypinator 0:bb348c97df44 1565 void *operator new (std::size_t count)
lypinator 0:bb348c97df44 1566 {
lypinator 0:bb348c97df44 1567 void *buffer = malloc(count);
lypinator 0:bb348c97df44 1568 if (NULL == buffer) {
lypinator 0:bb348c97df44 1569 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_MEMORY), "Operator new out of memory\r\n", count);
lypinator 0:bb348c97df44 1570 }
lypinator 0:bb348c97df44 1571 return buffer;
lypinator 0:bb348c97df44 1572 }
lypinator 0:bb348c97df44 1573
lypinator 0:bb348c97df44 1574 void *operator new[](std::size_t count)
lypinator 0:bb348c97df44 1575 {
lypinator 0:bb348c97df44 1576 void *buffer = malloc(count);
lypinator 0:bb348c97df44 1577 if (NULL == buffer) {
lypinator 0:bb348c97df44 1578 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_MEMORY), "Operator new[] out of memory\r\n", count);
lypinator 0:bb348c97df44 1579 }
lypinator 0:bb348c97df44 1580 return buffer;
lypinator 0:bb348c97df44 1581 }
lypinator 0:bb348c97df44 1582
lypinator 0:bb348c97df44 1583 void *operator new (std::size_t count, const std::nothrow_t &tag)
lypinator 0:bb348c97df44 1584 {
lypinator 0:bb348c97df44 1585 return malloc(count);
lypinator 0:bb348c97df44 1586 }
lypinator 0:bb348c97df44 1587
lypinator 0:bb348c97df44 1588 void *operator new[](std::size_t count, const std::nothrow_t &tag)
lypinator 0:bb348c97df44 1589 {
lypinator 0:bb348c97df44 1590 return malloc(count);
lypinator 0:bb348c97df44 1591 }
lypinator 0:bb348c97df44 1592
lypinator 0:bb348c97df44 1593 void operator delete (void *ptr)
lypinator 0:bb348c97df44 1594 {
lypinator 0:bb348c97df44 1595 free(ptr);
lypinator 0:bb348c97df44 1596 }
lypinator 0:bb348c97df44 1597 void operator delete[](void *ptr)
lypinator 0:bb348c97df44 1598 {
lypinator 0:bb348c97df44 1599 free(ptr);
lypinator 0:bb348c97df44 1600 }
lypinator 0:bb348c97df44 1601
lypinator 0:bb348c97df44 1602 #endif
lypinator 0:bb348c97df44 1603
lypinator 0:bb348c97df44 1604 /* @brief standard c library clock() function.
lypinator 0:bb348c97df44 1605 *
lypinator 0:bb348c97df44 1606 * This function returns the number of clock ticks elapsed since the start of the program.
lypinator 0:bb348c97df44 1607 *
lypinator 0:bb348c97df44 1608 * @note Synchronization level: Thread safe
lypinator 0:bb348c97df44 1609 *
lypinator 0:bb348c97df44 1610 * @return
lypinator 0:bb348c97df44 1611 * the number of clock ticks elapsed since the start of the program.
lypinator 0:bb348c97df44 1612 *
lypinator 0:bb348c97df44 1613 * */
lypinator 0:bb348c97df44 1614 extern "C" clock_t clock()
lypinator 0:bb348c97df44 1615 {
lypinator 0:bb348c97df44 1616 _mutex->lock();
lypinator 0:bb348c97df44 1617 clock_t t = ticker_read(get_us_ticker_data());
lypinator 0:bb348c97df44 1618 t /= 1000000 / CLOCKS_PER_SEC; // convert to processor time
lypinator 0:bb348c97df44 1619 _mutex->unlock();
lypinator 0:bb348c97df44 1620 return t;
lypinator 0:bb348c97df44 1621 }
lypinator 0:bb348c97df44 1622
lypinator 0:bb348c97df44 1623 // temporary - Default to 1MHz at 32 bits if target does not have us_ticker_get_info
lypinator 0:bb348c97df44 1624 MBED_WEAK const ticker_info_t *us_ticker_get_info()
lypinator 0:bb348c97df44 1625 {
lypinator 0:bb348c97df44 1626 static const ticker_info_t info = {
lypinator 0:bb348c97df44 1627 1000000,
lypinator 0:bb348c97df44 1628 32
lypinator 0:bb348c97df44 1629 };
lypinator 0:bb348c97df44 1630 return &info;
lypinator 0:bb348c97df44 1631 }
lypinator 0:bb348c97df44 1632
lypinator 0:bb348c97df44 1633 // temporary - Default to 1MHz at 32 bits if target does not have lp_ticker_get_info
lypinator 0:bb348c97df44 1634 MBED_WEAK const ticker_info_t *lp_ticker_get_info()
lypinator 0:bb348c97df44 1635 {
lypinator 0:bb348c97df44 1636 static const ticker_info_t info = {
lypinator 0:bb348c97df44 1637 1000000,
lypinator 0:bb348c97df44 1638 32
lypinator 0:bb348c97df44 1639 };
lypinator 0:bb348c97df44 1640 return &info;
lypinator 0:bb348c97df44 1641 }