ST / ST_Events-old

Dependents:   HelloWorld_CCA01M1 HelloWorld_CCA02M1 CI-data-logger-server HelloWorld_CCA02M1 ... more

This is a fork of the events subdirectory of https://github.com/ARMmbed/mbed-os.

Note, you must import this library with import name: events!!!

Committer:
Russ Butler
Date:
Mon Jun 27 18:55:07 2016 -0500
Revision:
6984:94fc5d678e5f
Parent:
6939:3866e967d1f2
Child:
7328:33c1e9a22f71
Child:
7262:f469aee29594
Create singleton class and update code to use it

Create the wrapper class SingletonPtr. This provides a safe way to
declare and use singletons. This class allows both the lazy
initialization of a singleton, and allows the singleton to be
garbage collected by the linker if it is never referenced.

This patch also updates the HAL to use SingletonPtr when declaring
singleton mutexes.

Who changed what in which revision?

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