mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
updated based on mbed-os5.15.0

Who changed what in which revision?

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