mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

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