MCU driver/HAL for the Picocell Gateway concentrator board. The firmware implements either a USB CDC protocol or a UART protocol to bridge commands coming from host to the SX1308 SPI interface.

Committer:
dgabino
Date:
Wed Apr 11 14:42:47 2018 +0000
Revision:
0:c76361bd82e8
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgabino 0:c76361bd82e8 1 /* mbed Microcontroller Library
dgabino 0:c76361bd82e8 2 * Copyright (c) 2006-2015 ARM Limited
dgabino 0:c76361bd82e8 3 *
dgabino 0:c76361bd82e8 4 * Licensed under the Apache License, Version 2.0 (the "License");
dgabino 0:c76361bd82e8 5 * you may not use this file except in compliance with the License.
dgabino 0:c76361bd82e8 6 * You may obtain a copy of the License at
dgabino 0:c76361bd82e8 7 *
dgabino 0:c76361bd82e8 8 * http://www.apache.org/licenses/LICENSE-2.0
dgabino 0:c76361bd82e8 9 *
dgabino 0:c76361bd82e8 10 * Unless required by applicable law or agreed to in writing, software
dgabino 0:c76361bd82e8 11 * distributed under the License is distributed on an "AS IS" BASIS,
dgabino 0:c76361bd82e8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dgabino 0:c76361bd82e8 13 * See the License for the specific language governing permissions and
dgabino 0:c76361bd82e8 14 * limitations under the License.
dgabino 0:c76361bd82e8 15 */
dgabino 0:c76361bd82e8 16 #include "platform.h"
dgabino 0:c76361bd82e8 17 #include "FileHandle.h"
dgabino 0:c76361bd82e8 18 #include "FileSystemLike.h"
dgabino 0:c76361bd82e8 19 #include "FilePath.h"
dgabino 0:c76361bd82e8 20 #include "serial_api.h"
dgabino 0:c76361bd82e8 21 #include "toolchain.h"
dgabino 0:c76361bd82e8 22 #include "semihost_api.h"
dgabino 0:c76361bd82e8 23 #include "mbed_interface.h"
dgabino 0:c76361bd82e8 24 #include "SingletonPtr.h"
dgabino 0:c76361bd82e8 25 #include "PlatformMutex.h"
dgabino 0:c76361bd82e8 26 #include "mbed_error.h"
dgabino 0:c76361bd82e8 27 #include "mbed_stats.h"
dgabino 0:c76361bd82e8 28 #include <stdlib.h>
dgabino 0:c76361bd82e8 29 #include <string.h>
dgabino 0:c76361bd82e8 30 #if DEVICE_STDIO_MESSAGES
dgabino 0:c76361bd82e8 31 #include <stdio.h>
dgabino 0:c76361bd82e8 32 #endif
dgabino 0:c76361bd82e8 33 #include <errno.h>
dgabino 0:c76361bd82e8 34
dgabino 0:c76361bd82e8 35 #if defined(__ARMCC_VERSION)
dgabino 0:c76361bd82e8 36 # include <rt_sys.h>
dgabino 0:c76361bd82e8 37 # define PREFIX(x) _sys##x
dgabino 0:c76361bd82e8 38 # define OPEN_MAX _SYS_OPEN
dgabino 0:c76361bd82e8 39 # ifdef __MICROLIB
dgabino 0:c76361bd82e8 40 # pragma import(__use_full_stdio)
dgabino 0:c76361bd82e8 41 # endif
dgabino 0:c76361bd82e8 42
dgabino 0:c76361bd82e8 43 #elif defined(__ICCARM__)
dgabino 0:c76361bd82e8 44 # include <yfuns.h>
dgabino 0:c76361bd82e8 45 # define PREFIX(x) _##x
dgabino 0:c76361bd82e8 46 # define OPEN_MAX 16
dgabino 0:c76361bd82e8 47
dgabino 0:c76361bd82e8 48 # define STDIN_FILENO 0
dgabino 0:c76361bd82e8 49 # define STDOUT_FILENO 1
dgabino 0:c76361bd82e8 50 # define STDERR_FILENO 2
dgabino 0:c76361bd82e8 51
dgabino 0:c76361bd82e8 52 #else
dgabino 0:c76361bd82e8 53 # include <sys/stat.h>
dgabino 0:c76361bd82e8 54 # include <sys/unistd.h>
dgabino 0:c76361bd82e8 55 # include <sys/syslimits.h>
dgabino 0:c76361bd82e8 56 # define PREFIX(x) x
dgabino 0:c76361bd82e8 57 #endif
dgabino 0:c76361bd82e8 58
dgabino 0:c76361bd82e8 59 #define FILE_HANDLE_RESERVED 0xFFFFFFFF
dgabino 0:c76361bd82e8 60
dgabino 0:c76361bd82e8 61 using namespace mbed;
dgabino 0:c76361bd82e8 62
dgabino 0:c76361bd82e8 63 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
dgabino 0:c76361bd82e8 64 // Before version 5.03, we were using a patched version of microlib with proper names
dgabino 0:c76361bd82e8 65 extern const char __stdin_name[] = ":tt";
dgabino 0:c76361bd82e8 66 extern const char __stdout_name[] = ":tt";
dgabino 0:c76361bd82e8 67 extern const char __stderr_name[] = ":tt";
dgabino 0:c76361bd82e8 68
dgabino 0:c76361bd82e8 69 #else
dgabino 0:c76361bd82e8 70 extern const char __stdin_name[] = "/stdin";
dgabino 0:c76361bd82e8 71 extern const char __stdout_name[] = "/stdout";
dgabino 0:c76361bd82e8 72 extern const char __stderr_name[] = "/stderr";
dgabino 0:c76361bd82e8 73 #endif
dgabino 0:c76361bd82e8 74
dgabino 0:c76361bd82e8 75 // Heap limits - only used if set
dgabino 0:c76361bd82e8 76 unsigned char *mbed_heap_start = 0;
dgabino 0:c76361bd82e8 77 uint32_t mbed_heap_size = 0;
dgabino 0:c76361bd82e8 78
dgabino 0:c76361bd82e8 79 /* newlib has the filehandle field in the FILE struct as a short, so
dgabino 0:c76361bd82e8 80 * we can't just return a Filehandle* from _open and instead have to
dgabino 0:c76361bd82e8 81 * put it in a filehandles array and return the index into that array
dgabino 0:c76361bd82e8 82 * (or rather index+3, as filehandles 0-2 are stdin/out/err).
dgabino 0:c76361bd82e8 83 */
dgabino 0:c76361bd82e8 84 static FileHandle *filehandles[OPEN_MAX];
dgabino 0:c76361bd82e8 85 static SingletonPtr<PlatformMutex> filehandle_mutex;
dgabino 0:c76361bd82e8 86
dgabino 0:c76361bd82e8 87 FileHandle::~FileHandle() {
dgabino 0:c76361bd82e8 88 filehandle_mutex->lock();
dgabino 0:c76361bd82e8 89 /* Remove all open filehandles for this */
dgabino 0:c76361bd82e8 90 for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
dgabino 0:c76361bd82e8 91 if (filehandles[fh_i] == this) {
dgabino 0:c76361bd82e8 92 filehandles[fh_i] = NULL;
dgabino 0:c76361bd82e8 93 }
dgabino 0:c76361bd82e8 94 }
dgabino 0:c76361bd82e8 95 filehandle_mutex->unlock();
dgabino 0:c76361bd82e8 96 }
dgabino 0:c76361bd82e8 97
dgabino 0:c76361bd82e8 98 #if DEVICE_SERIAL
dgabino 0:c76361bd82e8 99 extern int stdio_uart_inited;
dgabino 0:c76361bd82e8 100 extern serial_t stdio_uart;
dgabino 0:c76361bd82e8 101 #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES
dgabino 0:c76361bd82e8 102 static char stdio_in_prev;
dgabino 0:c76361bd82e8 103 static char stdio_out_prev;
dgabino 0:c76361bd82e8 104 #endif
dgabino 0:c76361bd82e8 105 #endif
dgabino 0:c76361bd82e8 106
dgabino 0:c76361bd82e8 107 static void init_serial() {
dgabino 0:c76361bd82e8 108 #if DEVICE_SERIAL
dgabino 0:c76361bd82e8 109 if (stdio_uart_inited) return;
dgabino 0:c76361bd82e8 110 serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
dgabino 0:c76361bd82e8 111 #if MBED_CONF_CORE_STDIO_BAUD_RATE
dgabino 0:c76361bd82e8 112 serial_baud(&stdio_uart, MBED_CONF_CORE_STDIO_BAUD_RATE);
dgabino 0:c76361bd82e8 113 #endif
dgabino 0:c76361bd82e8 114 #endif
dgabino 0:c76361bd82e8 115 }
dgabino 0:c76361bd82e8 116
dgabino 0:c76361bd82e8 117 static inline int openmode_to_posix(int openmode) {
dgabino 0:c76361bd82e8 118 int posix = openmode;
dgabino 0:c76361bd82e8 119 #ifdef __ARMCC_VERSION
dgabino 0:c76361bd82e8 120 if (openmode & OPEN_PLUS) {
dgabino 0:c76361bd82e8 121 posix = O_RDWR;
dgabino 0:c76361bd82e8 122 } else if(openmode & OPEN_W) {
dgabino 0:c76361bd82e8 123 posix = O_WRONLY;
dgabino 0:c76361bd82e8 124 } else if(openmode & OPEN_A) {
dgabino 0:c76361bd82e8 125 posix = O_WRONLY|O_APPEND;
dgabino 0:c76361bd82e8 126 } else {
dgabino 0:c76361bd82e8 127 posix = O_RDONLY;
dgabino 0:c76361bd82e8 128 }
dgabino 0:c76361bd82e8 129 /* a, w, a+, w+ all create if file does not already exist */
dgabino 0:c76361bd82e8 130 if (openmode & (OPEN_A|OPEN_W)) {
dgabino 0:c76361bd82e8 131 posix |= O_CREAT;
dgabino 0:c76361bd82e8 132 }
dgabino 0:c76361bd82e8 133 /* w and w+ truncate */
dgabino 0:c76361bd82e8 134 if (openmode & OPEN_W) {
dgabino 0:c76361bd82e8 135 posix |= O_TRUNC;
dgabino 0:c76361bd82e8 136 }
dgabino 0:c76361bd82e8 137 #elif defined(__ICCARM__)
dgabino 0:c76361bd82e8 138 switch (openmode & _LLIO_RDWRMASK) {
dgabino 0:c76361bd82e8 139 case _LLIO_RDONLY: posix = O_RDONLY; break;
dgabino 0:c76361bd82e8 140 case _LLIO_WRONLY: posix = O_WRONLY; break;
dgabino 0:c76361bd82e8 141 case _LLIO_RDWR : posix = O_RDWR ; break;
dgabino 0:c76361bd82e8 142 }
dgabino 0:c76361bd82e8 143 if (openmode & _LLIO_CREAT ) posix |= O_CREAT;
dgabino 0:c76361bd82e8 144 if (openmode & _LLIO_APPEND) posix |= O_APPEND;
dgabino 0:c76361bd82e8 145 if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC;
dgabino 0:c76361bd82e8 146 #elif defined(TOOLCHAIN_GCC)
dgabino 0:c76361bd82e8 147 posix &= ~O_BINARY;
dgabino 0:c76361bd82e8 148 #endif
dgabino 0:c76361bd82e8 149 return posix;
dgabino 0:c76361bd82e8 150 }
dgabino 0:c76361bd82e8 151
dgabino 0:c76361bd82e8 152 extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
dgabino 0:c76361bd82e8 153 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
dgabino 0:c76361bd82e8 154 // Before version 5.03, we were using a patched version of microlib with proper names
dgabino 0:c76361bd82e8 155 // This is the workaround that the microlib author suggested us
dgabino 0:c76361bd82e8 156 static int n = 0;
dgabino 0:c76361bd82e8 157 if (!std::strcmp(name, ":tt")) return n++;
dgabino 0:c76361bd82e8 158
dgabino 0:c76361bd82e8 159 #else
dgabino 0:c76361bd82e8 160 /* Use the posix convention that stdin,out,err are filehandles 0,1,2.
dgabino 0:c76361bd82e8 161 */
dgabino 0:c76361bd82e8 162 if (std::strcmp(name, __stdin_name) == 0) {
dgabino 0:c76361bd82e8 163 init_serial();
dgabino 0:c76361bd82e8 164 return 0;
dgabino 0:c76361bd82e8 165 } else if (std::strcmp(name, __stdout_name) == 0) {
dgabino 0:c76361bd82e8 166 init_serial();
dgabino 0:c76361bd82e8 167 return 1;
dgabino 0:c76361bd82e8 168 } else if (std::strcmp(name, __stderr_name) == 0) {
dgabino 0:c76361bd82e8 169 init_serial();
dgabino 0:c76361bd82e8 170 return 2;
dgabino 0:c76361bd82e8 171 }
dgabino 0:c76361bd82e8 172 #endif
dgabino 0:c76361bd82e8 173
dgabino 0:c76361bd82e8 174 // find the first empty slot in filehandles
dgabino 0:c76361bd82e8 175 filehandle_mutex->lock();
dgabino 0:c76361bd82e8 176 unsigned int fh_i;
dgabino 0:c76361bd82e8 177 for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
dgabino 0:c76361bd82e8 178 if (filehandles[fh_i] == NULL) break;
dgabino 0:c76361bd82e8 179 }
dgabino 0:c76361bd82e8 180 if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) {
dgabino 0:c76361bd82e8 181 filehandle_mutex->unlock();
dgabino 0:c76361bd82e8 182 return -1;
dgabino 0:c76361bd82e8 183 }
dgabino 0:c76361bd82e8 184 filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED;
dgabino 0:c76361bd82e8 185 filehandle_mutex->unlock();
dgabino 0:c76361bd82e8 186
dgabino 0:c76361bd82e8 187 FileHandle *res;
dgabino 0:c76361bd82e8 188
dgabino 0:c76361bd82e8 189 /* FILENAME: ":0x12345678" describes a FileLike* */
dgabino 0:c76361bd82e8 190 if (name[0] == ':') {
dgabino 0:c76361bd82e8 191 void *p;
dgabino 0:c76361bd82e8 192 sscanf(name, ":%p", &p);
dgabino 0:c76361bd82e8 193 res = (FileHandle*)p;
dgabino 0:c76361bd82e8 194
dgabino 0:c76361bd82e8 195 /* FILENAME: "/file_system/file_name" */
dgabino 0:c76361bd82e8 196 } else {
dgabino 0:c76361bd82e8 197 FilePath path(name);
dgabino 0:c76361bd82e8 198
dgabino 0:c76361bd82e8 199 if (!path.exists()) {
dgabino 0:c76361bd82e8 200 // Free file handle
dgabino 0:c76361bd82e8 201 filehandles[fh_i] = NULL;
dgabino 0:c76361bd82e8 202 return -1;
dgabino 0:c76361bd82e8 203 } else if (path.isFile()) {
dgabino 0:c76361bd82e8 204 res = path.file();
dgabino 0:c76361bd82e8 205 } else {
dgabino 0:c76361bd82e8 206 FileSystemLike *fs = path.fileSystem();
dgabino 0:c76361bd82e8 207 if (fs == NULL) {
dgabino 0:c76361bd82e8 208 // Free file handle
dgabino 0:c76361bd82e8 209 filehandles[fh_i] = NULL;
dgabino 0:c76361bd82e8 210 return -1;
dgabino 0:c76361bd82e8 211 }
dgabino 0:c76361bd82e8 212 int posix_mode = openmode_to_posix(openmode);
dgabino 0:c76361bd82e8 213 res = fs->open(path.fileName(), posix_mode); /* NULL if fails */
dgabino 0:c76361bd82e8 214 }
dgabino 0:c76361bd82e8 215 }
dgabino 0:c76361bd82e8 216
dgabino 0:c76361bd82e8 217 if (res == NULL) {
dgabino 0:c76361bd82e8 218 // Free file handle
dgabino 0:c76361bd82e8 219 filehandles[fh_i] = NULL;
dgabino 0:c76361bd82e8 220 return -1;
dgabino 0:c76361bd82e8 221 }
dgabino 0:c76361bd82e8 222 filehandles[fh_i] = res;
dgabino 0:c76361bd82e8 223
dgabino 0:c76361bd82e8 224 return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err
dgabino 0:c76361bd82e8 225 }
dgabino 0:c76361bd82e8 226
dgabino 0:c76361bd82e8 227 extern "C" int PREFIX(_close)(FILEHANDLE fh) {
dgabino 0:c76361bd82e8 228 if (fh < 3) return 0;
dgabino 0:c76361bd82e8 229
dgabino 0:c76361bd82e8 230 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 231 filehandles[fh-3] = NULL;
dgabino 0:c76361bd82e8 232 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 233
dgabino 0:c76361bd82e8 234 return fhc->close();
dgabino 0:c76361bd82e8 235 }
dgabino 0:c76361bd82e8 236
dgabino 0:c76361bd82e8 237 #if defined(__ICCARM__)
dgabino 0:c76361bd82e8 238 extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) {
dgabino 0:c76361bd82e8 239 #else
dgabino 0:c76361bd82e8 240 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) {
dgabino 0:c76361bd82e8 241 #endif
dgabino 0:c76361bd82e8 242 int n; // n is the number of bytes written
dgabino 0:c76361bd82e8 243 if (fh < 3) {
dgabino 0:c76361bd82e8 244 #if DEVICE_SERIAL
dgabino 0:c76361bd82e8 245 if (!stdio_uart_inited) init_serial();
dgabino 0:c76361bd82e8 246 #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES
dgabino 0:c76361bd82e8 247 for (unsigned int i = 0; i < length; i++) {
dgabino 0:c76361bd82e8 248 if (buffer[i] == '\n' && stdio_out_prev != '\r') {
dgabino 0:c76361bd82e8 249 serial_putc(&stdio_uart, '\r');
dgabino 0:c76361bd82e8 250 }
dgabino 0:c76361bd82e8 251 serial_putc(&stdio_uart, buffer[i]);
dgabino 0:c76361bd82e8 252 stdio_out_prev = buffer[i];
dgabino 0:c76361bd82e8 253 }
dgabino 0:c76361bd82e8 254 #else
dgabino 0:c76361bd82e8 255 for (unsigned int i = 0; i < length; i++) {
dgabino 0:c76361bd82e8 256 serial_putc(&stdio_uart, buffer[i]);
dgabino 0:c76361bd82e8 257 }
dgabino 0:c76361bd82e8 258 #endif
dgabino 0:c76361bd82e8 259 #endif
dgabino 0:c76361bd82e8 260 n = length;
dgabino 0:c76361bd82e8 261 } else {
dgabino 0:c76361bd82e8 262 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 263 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 264
dgabino 0:c76361bd82e8 265 n = fhc->write(buffer, length);
dgabino 0:c76361bd82e8 266 }
dgabino 0:c76361bd82e8 267 #ifdef __ARMCC_VERSION
dgabino 0:c76361bd82e8 268 return length-n;
dgabino 0:c76361bd82e8 269 #else
dgabino 0:c76361bd82e8 270 return n;
dgabino 0:c76361bd82e8 271 #endif
dgabino 0:c76361bd82e8 272 }
dgabino 0:c76361bd82e8 273
dgabino 0:c76361bd82e8 274 #if defined(__ICCARM__)
dgabino 0:c76361bd82e8 275 extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) {
dgabino 0:c76361bd82e8 276 #else
dgabino 0:c76361bd82e8 277 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) {
dgabino 0:c76361bd82e8 278 #endif
dgabino 0:c76361bd82e8 279 int n; // n is the number of bytes read
dgabino 0:c76361bd82e8 280 if (fh < 3) {
dgabino 0:c76361bd82e8 281 // only read a character at a time from stdin
dgabino 0:c76361bd82e8 282 #if DEVICE_SERIAL
dgabino 0:c76361bd82e8 283 if (!stdio_uart_inited) init_serial();
dgabino 0:c76361bd82e8 284 #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES
dgabino 0:c76361bd82e8 285 while (true) {
dgabino 0:c76361bd82e8 286 char c = serial_getc(&stdio_uart);
dgabino 0:c76361bd82e8 287 if ((c == '\r' && stdio_in_prev != '\n') ||
dgabino 0:c76361bd82e8 288 (c == '\n' && stdio_in_prev != '\r')) {
dgabino 0:c76361bd82e8 289 stdio_in_prev = c;
dgabino 0:c76361bd82e8 290 *buffer = '\n';
dgabino 0:c76361bd82e8 291 break;
dgabino 0:c76361bd82e8 292 } else if ((c == '\r' && stdio_in_prev == '\n') ||
dgabino 0:c76361bd82e8 293 (c == '\n' && stdio_in_prev == '\r')) {
dgabino 0:c76361bd82e8 294 stdio_in_prev = c;
dgabino 0:c76361bd82e8 295 // onto next character
dgabino 0:c76361bd82e8 296 continue;
dgabino 0:c76361bd82e8 297 } else {
dgabino 0:c76361bd82e8 298 stdio_in_prev = c;
dgabino 0:c76361bd82e8 299 *buffer = c;
dgabino 0:c76361bd82e8 300 break;
dgabino 0:c76361bd82e8 301 }
dgabino 0:c76361bd82e8 302 }
dgabino 0:c76361bd82e8 303 #else
dgabino 0:c76361bd82e8 304 *buffer = serial_getc(&stdio_uart);
dgabino 0:c76361bd82e8 305 #endif
dgabino 0:c76361bd82e8 306 #endif
dgabino 0:c76361bd82e8 307 n = 1;
dgabino 0:c76361bd82e8 308 } else {
dgabino 0:c76361bd82e8 309 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 310 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 311
dgabino 0:c76361bd82e8 312 n = fhc->read(buffer, length);
dgabino 0:c76361bd82e8 313 }
dgabino 0:c76361bd82e8 314 #ifdef __ARMCC_VERSION
dgabino 0:c76361bd82e8 315 return length-n;
dgabino 0:c76361bd82e8 316 #else
dgabino 0:c76361bd82e8 317 return n;
dgabino 0:c76361bd82e8 318 #endif
dgabino 0:c76361bd82e8 319 }
dgabino 0:c76361bd82e8 320
dgabino 0:c76361bd82e8 321 #ifdef __ARMCC_VERSION
dgabino 0:c76361bd82e8 322 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
dgabino 0:c76361bd82e8 323 #else
dgabino 0:c76361bd82e8 324 extern "C" int _isatty(FILEHANDLE fh)
dgabino 0:c76361bd82e8 325 #endif
dgabino 0:c76361bd82e8 326 {
dgabino 0:c76361bd82e8 327 /* stdin, stdout and stderr should be tty */
dgabino 0:c76361bd82e8 328 if (fh < 3) return 1;
dgabino 0:c76361bd82e8 329
dgabino 0:c76361bd82e8 330 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 331 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 332
dgabino 0:c76361bd82e8 333 return fhc->isatty();
dgabino 0:c76361bd82e8 334 }
dgabino 0:c76361bd82e8 335
dgabino 0:c76361bd82e8 336 extern "C"
dgabino 0:c76361bd82e8 337 #if defined(__ARMCC_VERSION)
dgabino 0:c76361bd82e8 338 int _sys_seek(FILEHANDLE fh, long position)
dgabino 0:c76361bd82e8 339 #elif defined(__ICCARM__)
dgabino 0:c76361bd82e8 340 long __lseek(int fh, long offset, int whence)
dgabino 0:c76361bd82e8 341 #else
dgabino 0:c76361bd82e8 342 int _lseek(FILEHANDLE fh, int offset, int whence)
dgabino 0:c76361bd82e8 343 #endif
dgabino 0:c76361bd82e8 344 {
dgabino 0:c76361bd82e8 345 if (fh < 3) return 0;
dgabino 0:c76361bd82e8 346
dgabino 0:c76361bd82e8 347 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 348 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 349
dgabino 0:c76361bd82e8 350 #if defined(__ARMCC_VERSION)
dgabino 0:c76361bd82e8 351 return fhc->lseek(position, SEEK_SET);
dgabino 0:c76361bd82e8 352 #else
dgabino 0:c76361bd82e8 353 return fhc->lseek(offset, whence);
dgabino 0:c76361bd82e8 354 #endif
dgabino 0:c76361bd82e8 355 }
dgabino 0:c76361bd82e8 356
dgabino 0:c76361bd82e8 357 #ifdef __ARMCC_VERSION
dgabino 0:c76361bd82e8 358 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
dgabino 0:c76361bd82e8 359 if (fh < 3) return 0;
dgabino 0:c76361bd82e8 360
dgabino 0:c76361bd82e8 361 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 362 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 363
dgabino 0:c76361bd82e8 364 return fhc->fsync();
dgabino 0:c76361bd82e8 365 }
dgabino 0:c76361bd82e8 366
dgabino 0:c76361bd82e8 367 extern "C" long PREFIX(_flen)(FILEHANDLE fh) {
dgabino 0:c76361bd82e8 368 if (fh < 3) return 0;
dgabino 0:c76361bd82e8 369
dgabino 0:c76361bd82e8 370 FileHandle* fhc = filehandles[fh-3];
dgabino 0:c76361bd82e8 371 if (fhc == NULL) return -1;
dgabino 0:c76361bd82e8 372
dgabino 0:c76361bd82e8 373 return fhc->flen();
dgabino 0:c76361bd82e8 374 }
dgabino 0:c76361bd82e8 375 #endif
dgabino 0:c76361bd82e8 376
dgabino 0:c76361bd82e8 377
dgabino 0:c76361bd82e8 378 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
dgabino 0:c76361bd82e8 379 extern "C" int _fstat(int fd, struct stat *st) {
dgabino 0:c76361bd82e8 380 if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) {
dgabino 0:c76361bd82e8 381 st->st_mode = S_IFCHR;
dgabino 0:c76361bd82e8 382 return 0;
dgabino 0:c76361bd82e8 383 }
dgabino 0:c76361bd82e8 384
dgabino 0:c76361bd82e8 385 errno = EBADF;
dgabino 0:c76361bd82e8 386 return -1;
dgabino 0:c76361bd82e8 387 }
dgabino 0:c76361bd82e8 388 #endif
dgabino 0:c76361bd82e8 389
dgabino 0:c76361bd82e8 390 namespace std {
dgabino 0:c76361bd82e8 391 extern "C" int remove(const char *path) {
dgabino 0:c76361bd82e8 392 FilePath fp(path);
dgabino 0:c76361bd82e8 393 FileSystemLike *fs = fp.fileSystem();
dgabino 0:c76361bd82e8 394 if (fs == NULL) return -1;
dgabino 0:c76361bd82e8 395
dgabino 0:c76361bd82e8 396 return fs->remove(fp.fileName());
dgabino 0:c76361bd82e8 397 }
dgabino 0:c76361bd82e8 398
dgabino 0:c76361bd82e8 399 extern "C" int rename(const char *oldname, const char *newname) {
dgabino 0:c76361bd82e8 400 FilePath fpOld(oldname);
dgabino 0:c76361bd82e8 401 FilePath fpNew(newname);
dgabino 0:c76361bd82e8 402 FileSystemLike *fsOld = fpOld.fileSystem();
dgabino 0:c76361bd82e8 403 FileSystemLike *fsNew = fpNew.fileSystem();
dgabino 0:c76361bd82e8 404
dgabino 0:c76361bd82e8 405 /* rename only if both files are on the same FS */
dgabino 0:c76361bd82e8 406 if (fsOld != fsNew || fsOld == NULL) return -1;
dgabino 0:c76361bd82e8 407
dgabino 0:c76361bd82e8 408 return fsOld->rename(fpOld.fileName(), fpNew.fileName());
dgabino 0:c76361bd82e8 409 }
dgabino 0:c76361bd82e8 410
dgabino 0:c76361bd82e8 411 extern "C" char *tmpnam(char *s) {
dgabino 0:c76361bd82e8 412 return NULL;
dgabino 0:c76361bd82e8 413 }
dgabino 0:c76361bd82e8 414
dgabino 0:c76361bd82e8 415 extern "C" FILE *tmpfile() {
dgabino 0:c76361bd82e8 416 return NULL;
dgabino 0:c76361bd82e8 417 }
dgabino 0:c76361bd82e8 418 } // namespace std
dgabino 0:c76361bd82e8 419
dgabino 0:c76361bd82e8 420 #ifdef __ARMCC_VERSION
dgabino 0:c76361bd82e8 421 extern "C" char *_sys_command_string(char *cmd, int len) {
dgabino 0:c76361bd82e8 422 return NULL;
dgabino 0:c76361bd82e8 423 }
dgabino 0:c76361bd82e8 424 #endif
dgabino 0:c76361bd82e8 425
dgabino 0:c76361bd82e8 426 extern "C" DIR *opendir(const char *path) {
dgabino 0:c76361bd82e8 427 /* root dir is FileSystemLike */
dgabino 0:c76361bd82e8 428 if (path[0] == '/' && path[1] == 0) {
dgabino 0:c76361bd82e8 429 return FileSystemLike::opendir();
dgabino 0:c76361bd82e8 430 }
dgabino 0:c76361bd82e8 431
dgabino 0:c76361bd82e8 432 FilePath fp(path);
dgabino 0:c76361bd82e8 433 FileSystemLike* fs = fp.fileSystem();
dgabino 0:c76361bd82e8 434 if (fs == NULL) return NULL;
dgabino 0:c76361bd82e8 435
dgabino 0:c76361bd82e8 436 return fs->opendir(fp.fileName());
dgabino 0:c76361bd82e8 437 }
dgabino 0:c76361bd82e8 438
dgabino 0:c76361bd82e8 439 extern "C" struct dirent *readdir(DIR *dir) {
dgabino 0:c76361bd82e8 440 return dir->readdir();
dgabino 0:c76361bd82e8 441 }
dgabino 0:c76361bd82e8 442
dgabino 0:c76361bd82e8 443 extern "C" int closedir(DIR *dir) {
dgabino 0:c76361bd82e8 444 return dir->closedir();
dgabino 0:c76361bd82e8 445 }
dgabino 0:c76361bd82e8 446
dgabino 0:c76361bd82e8 447 extern "C" void rewinddir(DIR *dir) {
dgabino 0:c76361bd82e8 448 dir->rewinddir();
dgabino 0:c76361bd82e8 449 }
dgabino 0:c76361bd82e8 450
dgabino 0:c76361bd82e8 451 extern "C" off_t telldir(DIR *dir) {
dgabino 0:c76361bd82e8 452 return dir->telldir();
dgabino 0:c76361bd82e8 453 }
dgabino 0:c76361bd82e8 454
dgabino 0:c76361bd82e8 455 extern "C" void seekdir(DIR *dir, off_t off) {
dgabino 0:c76361bd82e8 456 dir->seekdir(off);
dgabino 0:c76361bd82e8 457 }
dgabino 0:c76361bd82e8 458
dgabino 0:c76361bd82e8 459 extern "C" int mkdir(const char *path, mode_t mode) {
dgabino 0:c76361bd82e8 460 FilePath fp(path);
dgabino 0:c76361bd82e8 461 FileSystemLike *fs = fp.fileSystem();
dgabino 0:c76361bd82e8 462 if (fs == NULL) return -1;
dgabino 0:c76361bd82e8 463
dgabino 0:c76361bd82e8 464 return fs->mkdir(fp.fileName(), mode);
dgabino 0:c76361bd82e8 465 }
dgabino 0:c76361bd82e8 466
dgabino 0:c76361bd82e8 467 #if defined(TOOLCHAIN_GCC)
dgabino 0:c76361bd82e8 468 /* prevents the exception handling name demangling code getting pulled in */
dgabino 0:c76361bd82e8 469 #include "mbed_error.h"
dgabino 0:c76361bd82e8 470 namespace __gnu_cxx {
dgabino 0:c76361bd82e8 471 void __verbose_terminate_handler() {
dgabino 0:c76361bd82e8 472 error("Exception");
dgabino 0:c76361bd82e8 473 }
dgabino 0:c76361bd82e8 474 }
dgabino 0:c76361bd82e8 475 extern "C" WEAK void __cxa_pure_virtual(void);
dgabino 0:c76361bd82e8 476 extern "C" WEAK void __cxa_pure_virtual(void) {
dgabino 0:c76361bd82e8 477 exit(1);
dgabino 0:c76361bd82e8 478 }
dgabino 0:c76361bd82e8 479
dgabino 0:c76361bd82e8 480 #endif
dgabino 0:c76361bd82e8 481
dgabino 0:c76361bd82e8 482 #if defined(TOOLCHAIN_GCC)
dgabino 0:c76361bd82e8 483
dgabino 0:c76361bd82e8 484 #ifdef FEATURE_UVISOR
dgabino 0:c76361bd82e8 485 #include "uvisor-lib/uvisor-lib.h"
dgabino 0:c76361bd82e8 486 #endif/* FEATURE_UVISOR */
dgabino 0:c76361bd82e8 487
dgabino 0:c76361bd82e8 488
dgabino 0:c76361bd82e8 489 extern "C" WEAK void software_init_hook_rtos(void)
dgabino 0:c76361bd82e8 490 {
dgabino 0:c76361bd82e8 491 // Do nothing by default.
dgabino 0:c76361bd82e8 492 }
dgabino 0:c76361bd82e8 493
dgabino 0:c76361bd82e8 494 extern "C" void software_init_hook(void)
dgabino 0:c76361bd82e8 495 {
dgabino 0:c76361bd82e8 496 #ifdef FEATURE_UVISOR
dgabino 0:c76361bd82e8 497 int return_code;
dgabino 0:c76361bd82e8 498
dgabino 0:c76361bd82e8 499 return_code = uvisor_lib_init();
dgabino 0:c76361bd82e8 500 if (return_code) {
dgabino 0:c76361bd82e8 501 mbed_die();
dgabino 0:c76361bd82e8 502 }
dgabino 0:c76361bd82e8 503 #endif/* FEATURE_UVISOR */
dgabino 0:c76361bd82e8 504
dgabino 0:c76361bd82e8 505 software_init_hook_rtos();
dgabino 0:c76361bd82e8 506 }
dgabino 0:c76361bd82e8 507 #endif
dgabino 0:c76361bd82e8 508
dgabino 0:c76361bd82e8 509 // ****************************************************************************
dgabino 0:c76361bd82e8 510 // mbed_main is a function that is called before main()
dgabino 0:c76361bd82e8 511 // mbed_sdk_init() is also a function that is called before main(), but unlike
dgabino 0:c76361bd82e8 512 // mbed_main(), it is not meant for user code, but for the SDK itself to perform
dgabino 0:c76361bd82e8 513 // initializations before main() is called.
dgabino 0:c76361bd82e8 514
dgabino 0:c76361bd82e8 515 extern "C" WEAK void mbed_main(void);
dgabino 0:c76361bd82e8 516 extern "C" WEAK void mbed_main(void) {
dgabino 0:c76361bd82e8 517 }
dgabino 0:c76361bd82e8 518
dgabino 0:c76361bd82e8 519 extern "C" WEAK void mbed_sdk_init(void);
dgabino 0:c76361bd82e8 520 extern "C" WEAK void mbed_sdk_init(void) {
dgabino 0:c76361bd82e8 521 }
dgabino 0:c76361bd82e8 522
dgabino 0:c76361bd82e8 523 #if defined(TOOLCHAIN_ARM)
dgabino 0:c76361bd82e8 524 extern "C" int $Super$$main(void);
dgabino 0:c76361bd82e8 525
dgabino 0:c76361bd82e8 526 extern "C" int $Sub$$main(void) {
dgabino 0:c76361bd82e8 527 mbed_sdk_init();
dgabino 0:c76361bd82e8 528 mbed_main();
dgabino 0:c76361bd82e8 529 return $Super$$main();
dgabino 0:c76361bd82e8 530 }
dgabino 0:c76361bd82e8 531 #elif defined(TOOLCHAIN_GCC)
dgabino 0:c76361bd82e8 532 extern "C" int __real_main(void);
dgabino 0:c76361bd82e8 533
dgabino 0:c76361bd82e8 534 extern "C" int __wrap_main(void) {
dgabino 0:c76361bd82e8 535 mbed_sdk_init();
dgabino 0:c76361bd82e8 536 mbed_main();
dgabino 0:c76361bd82e8 537 return __real_main();
dgabino 0:c76361bd82e8 538 }
dgabino 0:c76361bd82e8 539 #elif defined(TOOLCHAIN_IAR)
dgabino 0:c76361bd82e8 540 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
dgabino 0:c76361bd82e8 541 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
dgabino 0:c76361bd82e8 542 // 'main' to another symbol looses the original 'main' symbol. However, its startup
dgabino 0:c76361bd82e8 543 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
dgabino 0:c76361bd82e8 544 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
dgabino 0:c76361bd82e8 545 extern "C" void __iar_argc_argv() {
dgabino 0:c76361bd82e8 546 mbed_main();
dgabino 0:c76361bd82e8 547 }
dgabino 0:c76361bd82e8 548 #endif
dgabino 0:c76361bd82e8 549
dgabino 0:c76361bd82e8 550 // Provide implementation of _sbrk (low-level dynamic memory allocation
dgabino 0:c76361bd82e8 551 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
dgabino 0:c76361bd82e8 552 // SP. This make it compatible with RTX RTOS thread stacks.
dgabino 0:c76361bd82e8 553 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
dgabino 0:c76361bd82e8 554 // Linker defined symbol used by _sbrk to indicate where heap should start.
dgabino 0:c76361bd82e8 555 extern "C" int __end__;
dgabino 0:c76361bd82e8 556
dgabino 0:c76361bd82e8 557 #if defined(TARGET_CORTEX_A)
dgabino 0:c76361bd82e8 558 extern "C" uint32_t __HeapLimit;
dgabino 0:c76361bd82e8 559 #endif
dgabino 0:c76361bd82e8 560
dgabino 0:c76361bd82e8 561 // Turn off the errno macro and use actual global variable instead.
dgabino 0:c76361bd82e8 562 #undef errno
dgabino 0:c76361bd82e8 563 extern "C" int errno;
dgabino 0:c76361bd82e8 564
dgabino 0:c76361bd82e8 565 // For ARM7 only
dgabino 0:c76361bd82e8 566 register unsigned char * stack_ptr __asm ("sp");
dgabino 0:c76361bd82e8 567
dgabino 0:c76361bd82e8 568 // Dynamic memory allocation related syscall.
dgabino 0:c76361bd82e8 569 #if defined(TARGET_NUMAKER_PFM_NUC472)
dgabino 0:c76361bd82e8 570 // Overwrite _sbrk() to support two region model.
dgabino 0:c76361bd82e8 571 extern "C" void *__wrap__sbrk(int incr);
dgabino 0:c76361bd82e8 572 extern "C" caddr_t _sbrk(int incr) {
dgabino 0:c76361bd82e8 573 return (caddr_t) __wrap__sbrk(incr);
dgabino 0:c76361bd82e8 574 }
dgabino 0:c76361bd82e8 575 #else
dgabino 0:c76361bd82e8 576 extern "C" caddr_t _sbrk(int incr) {
dgabino 0:c76361bd82e8 577 static unsigned char* heap = (unsigned char*)&__end__;
dgabino 0:c76361bd82e8 578 unsigned char* prev_heap = heap;
dgabino 0:c76361bd82e8 579 unsigned char* new_heap = heap + incr;
dgabino 0:c76361bd82e8 580
dgabino 0:c76361bd82e8 581 #if defined(TARGET_ARM7)
dgabino 0:c76361bd82e8 582 if (new_heap >= stack_ptr) {
dgabino 0:c76361bd82e8 583 #elif defined(TARGET_CORTEX_A)
dgabino 0:c76361bd82e8 584 if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */
dgabino 0:c76361bd82e8 585 #else
dgabino 0:c76361bd82e8 586 if (new_heap >= (unsigned char*)__get_MSP()) {
dgabino 0:c76361bd82e8 587 #endif
dgabino 0:c76361bd82e8 588 errno = ENOMEM;
dgabino 0:c76361bd82e8 589 return (caddr_t)-1;
dgabino 0:c76361bd82e8 590 }
dgabino 0:c76361bd82e8 591
dgabino 0:c76361bd82e8 592 // Additional heap checking if set
dgabino 0:c76361bd82e8 593 if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) {
dgabino 0:c76361bd82e8 594 errno = ENOMEM;
dgabino 0:c76361bd82e8 595 return (caddr_t)-1;
dgabino 0:c76361bd82e8 596 }
dgabino 0:c76361bd82e8 597
dgabino 0:c76361bd82e8 598 heap = new_heap;
dgabino 0:c76361bd82e8 599 return (caddr_t) prev_heap;
dgabino 0:c76361bd82e8 600 }
dgabino 0:c76361bd82e8 601 #endif
dgabino 0:c76361bd82e8 602 #endif
dgabino 0:c76361bd82e8 603
dgabino 0:c76361bd82e8 604 #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
dgabino 0:c76361bd82e8 605 extern "C" void _exit(int return_code) {
dgabino 0:c76361bd82e8 606 #else
dgabino 0:c76361bd82e8 607 namespace std {
dgabino 0:c76361bd82e8 608 extern "C" void exit(int return_code) {
dgabino 0:c76361bd82e8 609 #endif
dgabino 0:c76361bd82e8 610
dgabino 0:c76361bd82e8 611 #if DEVICE_STDIO_MESSAGES
dgabino 0:c76361bd82e8 612 fflush(stdout);
dgabino 0:c76361bd82e8 613 fflush(stderr);
dgabino 0:c76361bd82e8 614 #endif
dgabino 0:c76361bd82e8 615
dgabino 0:c76361bd82e8 616 #if DEVICE_SEMIHOST
dgabino 0:c76361bd82e8 617 if (mbed_interface_connected()) {
dgabino 0:c76361bd82e8 618 semihost_exit();
dgabino 0:c76361bd82e8 619 }
dgabino 0:c76361bd82e8 620 #endif
dgabino 0:c76361bd82e8 621 if (return_code) {
dgabino 0:c76361bd82e8 622 mbed_die();
dgabino 0:c76361bd82e8 623 }
dgabino 0:c76361bd82e8 624
dgabino 0:c76361bd82e8 625 while (1);
dgabino 0:c76361bd82e8 626 }
dgabino 0:c76361bd82e8 627
dgabino 0:c76361bd82e8 628 #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR)
dgabino 0:c76361bd82e8 629 } //namespace std
dgabino 0:c76361bd82e8 630 #endif
dgabino 0:c76361bd82e8 631
dgabino 0:c76361bd82e8 632
dgabino 0:c76361bd82e8 633 namespace mbed {
dgabino 0:c76361bd82e8 634
dgabino 0:c76361bd82e8 635 void mbed_set_unbuffered_stream(FILE *_file) {
dgabino 0:c76361bd82e8 636 #if defined (__ICCARM__)
dgabino 0:c76361bd82e8 637 char buf[2];
dgabino 0:c76361bd82e8 638 std::setvbuf(_file,buf,_IONBF,NULL);
dgabino 0:c76361bd82e8 639 #else
dgabino 0:c76361bd82e8 640 setbuf(_file, NULL);
dgabino 0:c76361bd82e8 641 #endif
dgabino 0:c76361bd82e8 642 }
dgabino 0:c76361bd82e8 643
dgabino 0:c76361bd82e8 644 int mbed_getc(FILE *_file){
dgabino 0:c76361bd82e8 645 #if defined (__ICCARM__)
dgabino 0:c76361bd82e8 646 /*This is only valid for unbuffered streams*/
dgabino 0:c76361bd82e8 647 int res = std::fgetc(_file);
dgabino 0:c76361bd82e8 648 if (res>=0){
dgabino 0:c76361bd82e8 649 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
dgabino 0:c76361bd82e8 650 _file->_Rend = _file->_Wend;
dgabino 0:c76361bd82e8 651 _file->_Next = _file->_Wend;
dgabino 0:c76361bd82e8 652 }
dgabino 0:c76361bd82e8 653 return res;
dgabino 0:c76361bd82e8 654 #else
dgabino 0:c76361bd82e8 655 return std::fgetc(_file);
dgabino 0:c76361bd82e8 656 #endif
dgabino 0:c76361bd82e8 657 }
dgabino 0:c76361bd82e8 658
dgabino 0:c76361bd82e8 659 char* mbed_gets(char*s, int size, FILE *_file){
dgabino 0:c76361bd82e8 660 #if defined (__ICCARM__)
dgabino 0:c76361bd82e8 661 /*This is only valid for unbuffered streams*/
dgabino 0:c76361bd82e8 662 char *str = fgets(s,size,_file);
dgabino 0:c76361bd82e8 663 if (str!=NULL){
dgabino 0:c76361bd82e8 664 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
dgabino 0:c76361bd82e8 665 _file->_Rend = _file->_Wend;
dgabino 0:c76361bd82e8 666 _file->_Next = _file->_Wend;
dgabino 0:c76361bd82e8 667 }
dgabino 0:c76361bd82e8 668 return str;
dgabino 0:c76361bd82e8 669 #else
dgabino 0:c76361bd82e8 670 return std::fgets(s,size,_file);
dgabino 0:c76361bd82e8 671 #endif
dgabino 0:c76361bd82e8 672 }
dgabino 0:c76361bd82e8 673
dgabino 0:c76361bd82e8 674 } // namespace mbed
dgabino 0:c76361bd82e8 675
dgabino 0:c76361bd82e8 676 #if defined (__ICCARM__)
dgabino 0:c76361bd82e8 677 // Stub out locks when an rtos is not present
dgabino 0:c76361bd82e8 678 extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 679 extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 680 extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 681 extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 682 extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 683 extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 684 extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 685 extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {}
dgabino 0:c76361bd82e8 686 #elif defined(__CC_ARM)
dgabino 0:c76361bd82e8 687 // Do nothing
dgabino 0:c76361bd82e8 688 #elif defined (__GNUC__)
dgabino 0:c76361bd82e8 689 struct _reent;
dgabino 0:c76361bd82e8 690 // Stub out locks when an rtos is not present
dgabino 0:c76361bd82e8 691 extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {}
dgabino 0:c76361bd82e8 692 extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {}
dgabino 0:c76361bd82e8 693 extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {}
dgabino 0:c76361bd82e8 694 extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {}
dgabino 0:c76361bd82e8 695
dgabino 0:c76361bd82e8 696 extern "C" void __malloc_lock( struct _reent *_r )
dgabino 0:c76361bd82e8 697 {
dgabino 0:c76361bd82e8 698 __rtos_malloc_lock(_r);
dgabino 0:c76361bd82e8 699 }
dgabino 0:c76361bd82e8 700
dgabino 0:c76361bd82e8 701 extern "C" void __malloc_unlock( struct _reent *_r )
dgabino 0:c76361bd82e8 702 {
dgabino 0:c76361bd82e8 703 __rtos_malloc_unlock(_r);
dgabino 0:c76361bd82e8 704 }
dgabino 0:c76361bd82e8 705
dgabino 0:c76361bd82e8 706 extern "C" void __env_lock( struct _reent *_r )
dgabino 0:c76361bd82e8 707 {
dgabino 0:c76361bd82e8 708 __rtos_env_lock(_r);
dgabino 0:c76361bd82e8 709 }
dgabino 0:c76361bd82e8 710
dgabino 0:c76361bd82e8 711 extern "C" void __env_unlock( struct _reent *_r )
dgabino 0:c76361bd82e8 712 {
dgabino 0:c76361bd82e8 713 __rtos_env_unlock(_r);
dgabino 0:c76361bd82e8 714 }
dgabino 0:c76361bd82e8 715
dgabino 0:c76361bd82e8 716 #define CXA_GUARD_INIT_DONE (1 << 0)
dgabino 0:c76361bd82e8 717 #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1)
dgabino 0:c76361bd82e8 718 #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS)
dgabino 0:c76361bd82e8 719
dgabino 0:c76361bd82e8 720 extern "C" int __cxa_guard_acquire(int *guard_object_p)
dgabino 0:c76361bd82e8 721 {
dgabino 0:c76361bd82e8 722 uint8_t *guard_object = (uint8_t *)guard_object_p;
dgabino 0:c76361bd82e8 723 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
dgabino 0:c76361bd82e8 724 return 0;
dgabino 0:c76361bd82e8 725 }
dgabino 0:c76361bd82e8 726 singleton_lock();
dgabino 0:c76361bd82e8 727 if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
dgabino 0:c76361bd82e8 728 singleton_unlock();
dgabino 0:c76361bd82e8 729 return 0;
dgabino 0:c76361bd82e8 730 }
dgabino 0:c76361bd82e8 731 MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK));
dgabino 0:c76361bd82e8 732 *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS;
dgabino 0:c76361bd82e8 733 return 1;
dgabino 0:c76361bd82e8 734 }
dgabino 0:c76361bd82e8 735
dgabino 0:c76361bd82e8 736 extern "C" void __cxa_guard_release(int *guard_object_p)
dgabino 0:c76361bd82e8 737 {
dgabino 0:c76361bd82e8 738 uint8_t *guard_object = (uint8_t *)guard_object_p;
dgabino 0:c76361bd82e8 739 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
dgabino 0:c76361bd82e8 740 *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE;
dgabino 0:c76361bd82e8 741 singleton_unlock();
dgabino 0:c76361bd82e8 742 }
dgabino 0:c76361bd82e8 743
dgabino 0:c76361bd82e8 744 extern "C" void __cxa_guard_abort(int *guard_object_p)
dgabino 0:c76361bd82e8 745 {
dgabino 0:c76361bd82e8 746 uint8_t *guard_object = (uint8_t *)guard_object_p;
dgabino 0:c76361bd82e8 747 MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
dgabino 0:c76361bd82e8 748 *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS;
dgabino 0:c76361bd82e8 749 singleton_unlock();
dgabino 0:c76361bd82e8 750 }
dgabino 0:c76361bd82e8 751
dgabino 0:c76361bd82e8 752 #endif
dgabino 0:c76361bd82e8 753
dgabino 0:c76361bd82e8 754 void *operator new(std::size_t count)
dgabino 0:c76361bd82e8 755 {
dgabino 0:c76361bd82e8 756 void *buffer = malloc(count);
dgabino 0:c76361bd82e8 757 if (NULL == buffer) {
dgabino 0:c76361bd82e8 758 error("Operator new out of memory\r\n");
dgabino 0:c76361bd82e8 759 }
dgabino 0:c76361bd82e8 760 return buffer;
dgabino 0:c76361bd82e8 761 }
dgabino 0:c76361bd82e8 762
dgabino 0:c76361bd82e8 763 void *operator new[](std::size_t count)
dgabino 0:c76361bd82e8 764 {
dgabino 0:c76361bd82e8 765 void *buffer = malloc(count);
dgabino 0:c76361bd82e8 766 if (NULL == buffer) {
dgabino 0:c76361bd82e8 767 error("Operator new[] out of memory\r\n");
dgabino 0:c76361bd82e8 768 }
dgabino 0:c76361bd82e8 769 return buffer;
dgabino 0:c76361bd82e8 770 }
dgabino 0:c76361bd82e8 771
dgabino 0:c76361bd82e8 772 void operator delete(void *ptr)
dgabino 0:c76361bd82e8 773 {
dgabino 0:c76361bd82e8 774 if (ptr != NULL) {
dgabino 0:c76361bd82e8 775 free(ptr);
dgabino 0:c76361bd82e8 776 }
dgabino 0:c76361bd82e8 777 }
dgabino 0:c76361bd82e8 778 void operator delete[](void *ptr)
dgabino 0:c76361bd82e8 779 {
dgabino 0:c76361bd82e8 780 if (ptr != NULL) {
dgabino 0:c76361bd82e8 781 free(ptr);
dgabino 0:c76361bd82e8 782 }
dgabino 0:c76361bd82e8 783 }