mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Parent:
187:0387e8f68319
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

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