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:
Fri Jul 29 15:29:56 2016 -0500
Revision:
7395:79e8c79e165c
Parent:
7338:b24a223c149b
Child:
7397:7448008aec84
Fix heap limit checking and make memory explicit

Set well defined limits for the heap and configure GCC and ARMCC to
correctly check these. IAR already correctly checked its heap.

This also statically declares the main thread stack so the
linker is responsible for its placement.

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