Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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!!!
hal/common/retarget.cpp@7514:a0c71f3f3d2f, 2016-08-13 (annotated)
- Committer:
- Russ Butler
- Date:
- Sat Aug 13 17:12:03 2016 -0500
- Revision:
- 7514:a0c71f3f3d2f
- Parent:
- 7397:7448008aec84
- Child:
- 7539:b568b913d7a4
Heap statistics
Keep track of the current size allocated, maximum size allocated,
number of allocations, failed allocations and total size allocated for
both GCC and ARM. Report the maximum size allocated at the end of
testing.
Also, add a test to verify heap metrics are working as expected.
Who changed what in which revision?
| User | Revision | Line number | New 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" |
| Russ Butler |
7397:7448008aec84 | 26 | #include "mbed_error.h" |
| Russ Butler |
7514:a0c71f3f3d2f | 27 | #include "mbed_stats.h" |
| Russ Butler |
7397:7448008aec84 | 28 | #include <stdlib.h> |
| Russ Butler |
7514:a0c71f3f3d2f | 29 | #include <string.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 30 | #if DEVICE_STDIO_MESSAGES |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 31 | #include <stdio.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 32 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 33 | #include <errno.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 34 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 35 | #if defined(__ARMCC_VERSION) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 36 | # include <rt_sys.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 37 | # define PREFIX(x) _sys##x |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 38 | # define OPEN_MAX _SYS_OPEN |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 39 | # ifdef __MICROLIB |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 40 | # pragma import(__use_full_stdio) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 41 | # endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 42 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 43 | #elif defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 44 | # include <yfuns.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 45 | # define PREFIX(x) _##x |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 46 | # define OPEN_MAX 16 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 47 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 48 | # define STDIN_FILENO 0 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 49 | # define STDOUT_FILENO 1 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 50 | # define STDERR_FILENO 2 |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 51 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 52 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 53 | # include <sys/stat.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 54 | # include <sys/unistd.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 55 | # include <sys/syslimits.h> |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 56 | # define PREFIX(x) x |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 57 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 58 | |
| Russ Butler |
6361:7b5bd40de905 | 59 | #define FILE_HANDLE_RESERVED 0xFFFFFFFF |
| Russ Butler |
6361:7b5bd40de905 | 60 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 61 | using namespace mbed; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 62 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 63 | #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 64 | // Before version 5.03, we were using a patched version of microlib with proper names |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 65 | extern const char __stdin_name[] = ":tt"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 66 | extern const char __stdout_name[] = ":tt"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 67 | extern const char __stderr_name[] = ":tt"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 68 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 69 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 70 | extern const char __stdin_name[] = "/stdin"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 71 | extern const char __stdout_name[] = "/stdout"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 72 | extern const char __stderr_name[] = "/stderr"; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 73 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 74 | |
| Russ Butler |
7395:79e8c79e165c | 75 | // Heap limits - only used if set |
| Russ Butler |
7395:79e8c79e165c | 76 | unsigned char *mbed_heap_start = 0; |
| Russ Butler |
7395:79e8c79e165c | 77 | uint32_t mbed_heap_size = 0; |
| Russ Butler |
7395:79e8c79e165c | 78 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 79 | /* newlib has the filehandle field in the FILE struct as a short, so |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 80 | * we can't just return a Filehandle* from _open and instead have to |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 81 | * put it in a filehandles array and return the index into that array |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 82 | * (or rather index+3, as filehandles 0-2 are stdin/out/err). |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 83 | */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 84 | static FileHandle *filehandles[OPEN_MAX]; |
| Russ Butler |
6984:94fc5d678e5f | 85 | static SingletonPtr<PlatformMutex> filehandle_mutex; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 86 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 87 | FileHandle::~FileHandle() { |
| Russ Butler |
6984:94fc5d678e5f | 88 | filehandle_mutex->lock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 89 | /* Remove all open filehandles for this */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 90 | for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 91 | if (filehandles[fh_i] == this) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 92 | filehandles[fh_i] = NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 93 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 94 | } |
| Russ Butler |
6984:94fc5d678e5f | 95 | filehandle_mutex->unlock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 96 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 97 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 98 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 99 | extern int stdio_uart_inited; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 100 | extern serial_t stdio_uart; |
| Christopher Haster |
6549:723eda4f0297 | 101 | #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES |
| Christopher Haster |
6547:5f2779e36035 | 102 | static char stdio_in_prev; |
| Christopher Haster |
6547:5f2779e36035 | 103 | static char stdio_out_prev; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 104 | #endif |
| Christopher Haster |
6548:c08cb6087b0a | 105 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 106 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 107 | static void init_serial() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 108 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 109 | if (stdio_uart_inited) return; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 110 | serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX); |
| Christopher Haster |
6892:5bf317924ef4 | 111 | #if MBED_CONF_CORE_STDIO_BAUD_RATE |
| Christopher Haster |
6892:5bf317924ef4 | 112 | serial_baud(&stdio_uart, MBED_CONF_CORE_STDIO_BAUD_RATE); |
| Christopher Haster |
6892:5bf317924ef4 | 113 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 114 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 115 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 116 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 117 | static inline int openmode_to_posix(int openmode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 118 | int posix = openmode; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 119 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 120 | if (openmode & OPEN_PLUS) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 121 | posix = O_RDWR; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 122 | } else if(openmode & OPEN_W) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 123 | posix = O_WRONLY; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 124 | } else if(openmode & OPEN_A) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 125 | posix = O_WRONLY|O_APPEND; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 126 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 127 | posix = O_RDONLY; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 128 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 129 | /* a, w, a+, w+ all create if file does not already exist */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 130 | if (openmode & (OPEN_A|OPEN_W)) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 131 | posix |= O_CREAT; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 132 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 133 | /* w and w+ truncate */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 134 | if (openmode & OPEN_W) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 135 | posix |= O_TRUNC; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 136 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 137 | #elif defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 138 | switch (openmode & _LLIO_RDWRMASK) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 139 | case _LLIO_RDONLY: posix = O_RDONLY; break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 140 | case _LLIO_WRONLY: posix = O_WRONLY; break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 141 | case _LLIO_RDWR : posix = O_RDWR ; break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 142 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 143 | if (openmode & _LLIO_CREAT ) posix |= O_CREAT; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 144 | if (openmode & _LLIO_APPEND) posix |= O_APPEND; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 145 | if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 146 | #elif defined(TOOLCHAIN_GCC) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 147 | posix &= ~O_BINARY; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 148 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 149 | return posix; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 150 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 151 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 152 | extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 153 | #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 154 | // Before version 5.03, we were using a patched version of microlib with proper names |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 155 | // This is the workaround that the microlib author suggested us |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 156 | static int n = 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 157 | if (!std::strcmp(name, ":tt")) return n++; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 158 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 159 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 160 | /* Use the posix convention that stdin,out,err are filehandles 0,1,2. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 161 | */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 162 | if (std::strcmp(name, __stdin_name) == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 163 | init_serial(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 164 | return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 165 | } else if (std::strcmp(name, __stdout_name) == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 166 | init_serial(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 167 | return 1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 168 | } else if (std::strcmp(name, __stderr_name) == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 169 | init_serial(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 170 | return 2; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 171 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 172 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 173 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 174 | // find the first empty slot in filehandles |
| Russ Butler |
6984:94fc5d678e5f | 175 | filehandle_mutex->lock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 176 | unsigned int fh_i; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 177 | for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 178 | if (filehandles[fh_i] == NULL) break; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 179 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 180 | if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { |
| Russ Butler |
6984:94fc5d678e5f | 181 | filehandle_mutex->unlock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 182 | return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 183 | } |
| Russ Butler |
6361:7b5bd40de905 | 184 | filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED; |
| Russ Butler |
6984:94fc5d678e5f | 185 | filehandle_mutex->unlock(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 186 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 187 | FileHandle *res; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 188 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 189 | /* FILENAME: ":0x12345678" describes a FileLike* */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 190 | if (name[0] == ':') { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 191 | void *p; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 192 | sscanf(name, ":%p", &p); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 193 | res = (FileHandle*)p; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 194 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 195 | /* FILENAME: "/file_system/file_name" */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 196 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 197 | FilePath path(name); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 198 | |
| Russ Butler |
6361:7b5bd40de905 | 199 | if (!path.exists()) { |
| Russ Butler |
6361:7b5bd40de905 | 200 | // Free file handle |
| Russ Butler |
6361:7b5bd40de905 | 201 | filehandles[fh_i] = NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 202 | return -1; |
| Russ Butler |
6361:7b5bd40de905 | 203 | } else if (path.isFile()) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 204 | res = path.file(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 205 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 206 | FileSystemLike *fs = path.fileSystem(); |
| Russ Butler |
6361:7b5bd40de905 | 207 | if (fs == NULL) { |
| Russ Butler |
6361:7b5bd40de905 | 208 | // Free file handle |
| Russ Butler |
6361:7b5bd40de905 | 209 | filehandles[fh_i] = NULL; |
| Russ Butler |
6361:7b5bd40de905 | 210 | return -1; |
| Russ Butler |
6361:7b5bd40de905 | 211 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 212 | int posix_mode = openmode_to_posix(openmode); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 213 | res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 214 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 215 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 216 | |
| Russ Butler |
6361:7b5bd40de905 | 217 | if (res == NULL) { |
| Russ Butler |
6361:7b5bd40de905 | 218 | // Free file handle |
| Russ Butler |
6361:7b5bd40de905 | 219 | filehandles[fh_i] = NULL; |
| Russ Butler |
6361:7b5bd40de905 | 220 | return -1; |
| Russ Butler |
6361:7b5bd40de905 | 221 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 222 | filehandles[fh_i] = res; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 223 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 224 | return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 225 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 226 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 227 | extern "C" int PREFIX(_close)(FILEHANDLE fh) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 228 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 229 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 230 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 231 | filehandles[fh-3] = NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 232 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 233 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 234 | return fhc->close(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 235 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 236 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 237 | #if defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 238 | extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 239 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 240 | extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 241 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 242 | int n; // n is the number of bytes written |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 243 | if (fh < 3) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 244 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 245 | if (!stdio_uart_inited) init_serial(); |
| Christopher Haster |
6549:723eda4f0297 | 246 | #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 247 | for (unsigned int i = 0; i < length; i++) { |
| Christopher Haster |
6547:5f2779e36035 | 248 | if (buffer[i] == '\n' && stdio_out_prev != '\r') { |
| Christopher Haster |
6546:b7f6a8e13048 | 249 | serial_putc(&stdio_uart, '\r'); |
| Christopher Haster |
6546:b7f6a8e13048 | 250 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 251 | serial_putc(&stdio_uart, buffer[i]); |
| Christopher Haster |
6547:5f2779e36035 | 252 | stdio_out_prev = buffer[i]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 253 | } |
| Christopher Haster |
6548:c08cb6087b0a | 254 | #else |
| Christopher Haster |
6548:c08cb6087b0a | 255 | for (unsigned int i = 0; i < length; i++) { |
| Christopher Haster |
6548:c08cb6087b0a | 256 | serial_putc(&stdio_uart, buffer[i]); |
| Christopher Haster |
6548:c08cb6087b0a | 257 | } |
| Christopher Haster |
6548:c08cb6087b0a | 258 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 259 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 260 | n = length; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 261 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 262 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 263 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 264 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 265 | n = fhc->write(buffer, length); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 266 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 267 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 268 | return length-n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 269 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 270 | return n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 271 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 272 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 273 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 274 | #if defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 275 | extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 276 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 277 | extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 278 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 279 | int n; // n is the number of bytes read |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 280 | if (fh < 3) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 281 | // only read a character at a time from stdin |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 282 | #if DEVICE_SERIAL |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 283 | if (!stdio_uart_inited) init_serial(); |
| Christopher Haster |
6549:723eda4f0297 | 284 | #if MBED_CONF_CORE_STDIO_CONVERT_NEWLINES |
| Christopher Haster |
6547:5f2779e36035 | 285 | while (true) { |
| Christopher Haster |
6547:5f2779e36035 | 286 | char c = serial_getc(&stdio_uart); |
| Christopher Haster |
6547:5f2779e36035 | 287 | if ((c == '\r' && stdio_in_prev != '\n') || |
| Christopher Haster |
6547:5f2779e36035 | 288 | (c == '\n' && stdio_in_prev != '\r')) { |
| Christopher Haster |
6547:5f2779e36035 | 289 | stdio_in_prev = c; |
| Christopher Haster |
6547:5f2779e36035 | 290 | *buffer = '\n'; |
| Christopher Haster |
6547:5f2779e36035 | 291 | break; |
| Christopher Haster |
6547:5f2779e36035 | 292 | } else if ((c == '\r' && stdio_in_prev == '\n') || |
| Christopher Haster |
6547:5f2779e36035 | 293 | (c == '\n' && stdio_in_prev == '\r')) { |
| Christopher Haster |
6547:5f2779e36035 | 294 | stdio_in_prev = c; |
| Christopher Haster |
6547:5f2779e36035 | 295 | // onto next character |
| Christopher Haster |
6547:5f2779e36035 | 296 | continue; |
| Christopher Haster |
6547:5f2779e36035 | 297 | } else { |
| Christopher Haster |
6547:5f2779e36035 | 298 | stdio_in_prev = c; |
| Christopher Haster |
6547:5f2779e36035 | 299 | *buffer = c; |
| Christopher Haster |
6547:5f2779e36035 | 300 | break; |
| Christopher Haster |
6547:5f2779e36035 | 301 | } |
| Christopher Haster |
6547:5f2779e36035 | 302 | } |
| Christopher Haster |
6548:c08cb6087b0a | 303 | #else |
| Christopher Haster |
6548:c08cb6087b0a | 304 | *buffer = serial_getc(&stdio_uart); |
| Christopher Haster |
6548:c08cb6087b0a | 305 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 306 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 307 | n = 1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 308 | } else { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 309 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 310 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 311 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 312 | n = fhc->read(buffer, length); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 313 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 314 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 315 | return length-n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 316 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 317 | return n; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 318 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 319 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 320 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 321 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 322 | extern "C" int PREFIX(_istty)(FILEHANDLE fh) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 323 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 324 | extern "C" int _isatty(FILEHANDLE fh) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 325 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 326 | { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 327 | /* stdin, stdout and stderr should be tty */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 328 | if (fh < 3) return 1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 329 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 330 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 331 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 332 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 333 | return fhc->isatty(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 334 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 335 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 336 | extern "C" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 337 | #if defined(__ARMCC_VERSION) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 338 | int _sys_seek(FILEHANDLE fh, long position) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 339 | #elif defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 340 | long __lseek(int fh, long offset, int whence) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 341 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 342 | int _lseek(FILEHANDLE fh, int offset, int whence) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 343 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 344 | { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 345 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 346 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 347 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 348 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 349 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 350 | #if defined(__ARMCC_VERSION) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 351 | return fhc->lseek(position, SEEK_SET); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 352 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 353 | return fhc->lseek(offset, whence); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 354 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 355 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 356 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 357 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 358 | extern "C" int PREFIX(_ensure)(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->fsync(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 365 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 366 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 367 | extern "C" long PREFIX(_flen)(FILEHANDLE fh) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 368 | if (fh < 3) return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 369 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 370 | FileHandle* fhc = filehandles[fh-3]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 371 | if (fhc == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 372 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 373 | return fhc->flen(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 374 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 375 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 376 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 377 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 378 | #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 379 | extern "C" int _fstat(int fd, struct stat *st) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 380 | if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 381 | st->st_mode = S_IFCHR; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 382 | return 0; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 383 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 384 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 385 | errno = EBADF; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 386 | return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 387 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 388 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 389 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 390 | namespace std { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 391 | extern "C" int remove(const char *path) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 392 | FilePath fp(path); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 393 | FileSystemLike *fs = fp.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 394 | if (fs == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 395 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 396 | return fs->remove(fp.fileName()); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 397 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 398 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 399 | extern "C" int rename(const char *oldname, const char *newname) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 400 | FilePath fpOld(oldname); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 401 | FilePath fpNew(newname); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 402 | FileSystemLike *fsOld = fpOld.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 403 | FileSystemLike *fsNew = fpNew.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 404 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 405 | /* rename only if both files are on the same FS */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 406 | if (fsOld != fsNew || fsOld == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 407 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 408 | return fsOld->rename(fpOld.fileName(), fpNew.fileName()); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 409 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 410 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 411 | extern "C" char *tmpnam(char *s) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 412 | return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 413 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 414 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 415 | extern "C" FILE *tmpfile() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 416 | return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 417 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 418 | } // namespace std |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 419 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 420 | #ifdef __ARMCC_VERSION |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 421 | extern "C" char *_sys_command_string(char *cmd, int len) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 422 | return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 423 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 424 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 425 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 426 | extern "C" DIR *opendir(const char *path) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 427 | /* root dir is FileSystemLike */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 428 | if (path[0] == '/' && path[1] == 0) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 429 | return FileSystemLike::opendir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 430 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 431 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 432 | FilePath fp(path); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 433 | FileSystemLike* fs = fp.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 434 | if (fs == NULL) return NULL; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 435 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 436 | return fs->opendir(fp.fileName()); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 437 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 438 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 439 | extern "C" struct dirent *readdir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 440 | return dir->readdir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 441 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 442 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 443 | extern "C" int closedir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 444 | return dir->closedir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 445 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 446 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 447 | extern "C" void rewinddir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 448 | dir->rewinddir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 449 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 450 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 451 | extern "C" off_t telldir(DIR *dir) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 452 | return dir->telldir(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 453 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 454 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 455 | extern "C" void seekdir(DIR *dir, off_t off) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 456 | dir->seekdir(off); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 457 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 458 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 459 | extern "C" int mkdir(const char *path, mode_t mode) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 460 | FilePath fp(path); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 461 | FileSystemLike *fs = fp.fileSystem(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 462 | if (fs == NULL) return -1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 463 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 464 | return fs->mkdir(fp.fileName(), mode); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 465 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 466 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 467 | #if defined(TOOLCHAIN_GCC) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 468 | /* prevents the exception handling name demangling code getting pulled in */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 469 | #include "mbed_error.h" |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 470 | namespace __gnu_cxx { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 471 | void __verbose_terminate_handler() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 472 | error("Exception"); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 473 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 474 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 475 | extern "C" WEAK void __cxa_pure_virtual(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 476 | extern "C" WEAK void __cxa_pure_virtual(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 477 | exit(1); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 478 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 479 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 480 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 481 | |
| Russ Butler |
7514:a0c71f3f3d2f | 482 | /* Size must be a multiple of 8 to keep alignment */ |
| Russ Butler |
7514:a0c71f3f3d2f | 483 | typedef struct { |
| Russ Butler |
7514:a0c71f3f3d2f | 484 | uint32_t size; |
| Russ Butler |
7514:a0c71f3f3d2f | 485 | uint32_t pad; |
| Russ Butler |
7514:a0c71f3f3d2f | 486 | } alloc_info_t; |
| Russ Butler |
7514:a0c71f3f3d2f | 487 | |
| Russ Butler |
7514:a0c71f3f3d2f | 488 | static SingletonPtr<PlatformMutex> malloc_stats_mutex; |
| Russ Butler |
7514:a0c71f3f3d2f | 489 | static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0}; |
| Russ Butler |
7514:a0c71f3f3d2f | 490 | |
| Russ Butler |
7514:a0c71f3f3d2f | 491 | void mbed_stats_heap_get(mbed_stats_heap_t *stats) |
| Russ Butler |
7514:a0c71f3f3d2f | 492 | { |
| Russ Butler |
7514:a0c71f3f3d2f | 493 | malloc_stats_mutex->lock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 494 | memcpy(stats, &heap_stats, sizeof(mbed_stats_heap_t)); |
| Russ Butler |
7514:a0c71f3f3d2f | 495 | malloc_stats_mutex->unlock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 496 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 497 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 498 | #if defined(TOOLCHAIN_GCC) |
| Jaeden Amero |
6336:a0ee59c4aa27 | 499 | #ifdef FEATURE_UVISOR |
| Jaeden Amero |
6336:a0ee59c4aa27 | 500 | #include "uvisor-lib/uvisor-lib.h" |
| Jaeden Amero |
6336:a0ee59c4aa27 | 501 | #endif/* FEATURE_UVISOR */ |
| Jaeden Amero |
6336:a0ee59c4aa27 | 502 | |
| Niklas Hauser |
6337:760e146953ef | 503 | #ifndef FEATURE_UVISOR |
| Niklas Hauser |
6337:760e146953ef | 504 | extern "C" { |
| Russ Butler |
7514:a0c71f3f3d2f | 505 | |
| Russ Butler |
7514:a0c71f3f3d2f | 506 | extern "C" void __malloc_lock( struct _reent *_r ); |
| Russ Butler |
7514:a0c71f3f3d2f | 507 | extern "C" void __malloc_unlock( struct _reent *_r ); |
| Russ Butler |
7514:a0c71f3f3d2f | 508 | |
| Niklas Hauser |
6337:760e146953ef | 509 | void * __wrap__malloc_r(struct _reent * r, size_t size) { |
| Niklas Hauser |
6337:760e146953ef | 510 | extern void * __real__malloc_r(struct _reent * r, size_t size); |
| Russ Butler |
7514:a0c71f3f3d2f | 511 | #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED |
| Niklas Hauser |
6337:760e146953ef | 512 | return __real__malloc_r(r, size); |
| Russ Butler |
7514:a0c71f3f3d2f | 513 | #else |
| Russ Butler |
7514:a0c71f3f3d2f | 514 | |
| Russ Butler |
7514:a0c71f3f3d2f | 515 | malloc_stats_mutex->lock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 516 | alloc_info_t *alloc_info = (alloc_info_t*)__real__malloc_r(r, size + sizeof(alloc_info_t)); |
| Russ Butler |
7514:a0c71f3f3d2f | 517 | void *ptr = NULL; |
| Russ Butler |
7514:a0c71f3f3d2f | 518 | if (alloc_info != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 519 | alloc_info->size = size; |
| Russ Butler |
7514:a0c71f3f3d2f | 520 | ptr = (void*)(alloc_info + 1); |
| Russ Butler |
7514:a0c71f3f3d2f | 521 | heap_stats.current_size += size; |
| Russ Butler |
7514:a0c71f3f3d2f | 522 | heap_stats.total_size += size; |
| Russ Butler |
7514:a0c71f3f3d2f | 523 | heap_stats.alloc_cnt += 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 524 | if (heap_stats.current_size > heap_stats.max_size) { |
| Russ Butler |
7514:a0c71f3f3d2f | 525 | heap_stats.max_size = heap_stats.current_size; |
| Russ Butler |
7514:a0c71f3f3d2f | 526 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 527 | } else { |
| Russ Butler |
7514:a0c71f3f3d2f | 528 | heap_stats.alloc_fail_cnt += 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 529 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 530 | malloc_stats_mutex->unlock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 531 | |
| Russ Butler |
7514:a0c71f3f3d2f | 532 | return ptr; |
| Russ Butler |
7514:a0c71f3f3d2f | 533 | #endif |
| Niklas Hauser |
6337:760e146953ef | 534 | } |
| Niklas Hauser |
6337:760e146953ef | 535 | void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size) { |
| Russ Butler |
7514:a0c71f3f3d2f | 536 | #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED |
| Niklas Hauser |
6337:760e146953ef | 537 | extern void * __real__realloc_r(struct _reent * r, void * ptr, size_t size); |
| Niklas Hauser |
6337:760e146953ef | 538 | return __real__realloc_r(r, ptr, size); |
| Russ Butler |
7514:a0c71f3f3d2f | 539 | #else |
| Russ Butler |
7514:a0c71f3f3d2f | 540 | |
| Russ Butler |
7514:a0c71f3f3d2f | 541 | // Implement realloc_r with malloc and free. |
| Russ Butler |
7514:a0c71f3f3d2f | 542 | // The function realloc_r can't be used here directly since |
| Russ Butler |
7514:a0c71f3f3d2f | 543 | // it can call into __wrap__malloc_r (returns ptr + 4) or |
| Russ Butler |
7514:a0c71f3f3d2f | 544 | // resize memory directly (returns ptr + 0). |
| Russ Butler |
7514:a0c71f3f3d2f | 545 | |
| Russ Butler |
7514:a0c71f3f3d2f | 546 | // Note - no lock needed since malloc and free are thread safe |
| Russ Butler |
7514:a0c71f3f3d2f | 547 | |
| Russ Butler |
7514:a0c71f3f3d2f | 548 | // Get old size |
| Russ Butler |
7514:a0c71f3f3d2f | 549 | uint32_t old_size = 0; |
| Russ Butler |
7514:a0c71f3f3d2f | 550 | if (ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 551 | alloc_info_t *alloc_info = ((alloc_info_t*)ptr) - 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 552 | old_size = alloc_info->size; |
| Russ Butler |
7514:a0c71f3f3d2f | 553 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 554 | |
| Russ Butler |
7514:a0c71f3f3d2f | 555 | // Allocate space |
| Russ Butler |
7514:a0c71f3f3d2f | 556 | void *new_ptr = NULL; |
| Russ Butler |
7514:a0c71f3f3d2f | 557 | if (size != 0) { |
| Russ Butler |
7514:a0c71f3f3d2f | 558 | new_ptr = malloc(size); |
| Russ Butler |
7514:a0c71f3f3d2f | 559 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 560 | |
| Russ Butler |
7514:a0c71f3f3d2f | 561 | // If the new buffer has been allocated copy the data to it |
| Russ Butler |
7514:a0c71f3f3d2f | 562 | // and free the old buffer |
| Russ Butler |
7514:a0c71f3f3d2f | 563 | if (new_ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 564 | uint32_t copy_size = (old_size < size) ? old_size : size; |
| Russ Butler |
7514:a0c71f3f3d2f | 565 | memcpy(new_ptr, (void*)ptr, copy_size); |
| Russ Butler |
7514:a0c71f3f3d2f | 566 | free(ptr); |
| Russ Butler |
7514:a0c71f3f3d2f | 567 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 568 | |
| Russ Butler |
7514:a0c71f3f3d2f | 569 | return new_ptr; |
| Russ Butler |
7514:a0c71f3f3d2f | 570 | #endif |
| Niklas Hauser |
6337:760e146953ef | 571 | } |
| Niklas Hauser |
6337:760e146953ef | 572 | void __wrap__free_r(struct _reent * r, void * ptr) { |
| Niklas Hauser |
6337:760e146953ef | 573 | extern void __real__free_r(struct _reent * r, void * ptr); |
| Russ Butler |
7514:a0c71f3f3d2f | 574 | #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED |
| Niklas Hauser |
6337:760e146953ef | 575 | __real__free_r(r, ptr); |
| Russ Butler |
7514:a0c71f3f3d2f | 576 | #else |
| Russ Butler |
7514:a0c71f3f3d2f | 577 | |
| Russ Butler |
7514:a0c71f3f3d2f | 578 | malloc_stats_mutex->lock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 579 | alloc_info_t *alloc_info = NULL; |
| Russ Butler |
7514:a0c71f3f3d2f | 580 | if (ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 581 | alloc_info = ((alloc_info_t*)ptr) - 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 582 | heap_stats.current_size -= alloc_info->size; |
| Russ Butler |
7514:a0c71f3f3d2f | 583 | heap_stats.alloc_cnt -= 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 584 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 585 | __real__free_r(r, (void*)alloc_info); |
| Russ Butler |
7514:a0c71f3f3d2f | 586 | malloc_stats_mutex->unlock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 587 | #endif |
| Russ Butler |
7514:a0c71f3f3d2f | 588 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 589 | void* __wrap__calloc_r(struct _reent * r, size_t num, size_t size) { |
| Russ Butler |
7514:a0c71f3f3d2f | 590 | #if !defined(MBED_HEAP_STATS_ENABLED ) || !MBED_HEAP_STATS_ENABLED |
| Russ Butler |
7514:a0c71f3f3d2f | 591 | extern void* __real__calloc_r(struct _reent * r, size_t num, size_t size); |
| Russ Butler |
7514:a0c71f3f3d2f | 592 | return __real__calloc_r(r, num, size); |
| Russ Butler |
7514:a0c71f3f3d2f | 593 | #else |
| Russ Butler |
7514:a0c71f3f3d2f | 594 | |
| Russ Butler |
7514:a0c71f3f3d2f | 595 | // Note - no lock needed since malloc is thread safe |
| Russ Butler |
7514:a0c71f3f3d2f | 596 | |
| Russ Butler |
7514:a0c71f3f3d2f | 597 | void *ptr = malloc(num * size); |
| Russ Butler |
7514:a0c71f3f3d2f | 598 | if (ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 599 | memset(ptr, 0, num * size); |
| Russ Butler |
7514:a0c71f3f3d2f | 600 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 601 | |
| Russ Butler |
7514:a0c71f3f3d2f | 602 | return ptr; |
| Russ Butler |
7514:a0c71f3f3d2f | 603 | #endif |
| Niklas Hauser |
6337:760e146953ef | 604 | } |
| Niklas Hauser |
6337:760e146953ef | 605 | } |
| Niklas Hauser |
6337:760e146953ef | 606 | #endif/* FEATURE_UVISOR */ |
| Niklas Hauser |
6337:760e146953ef | 607 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 608 | extern "C" WEAK void software_init_hook_rtos(void) |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 609 | { |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 610 | // Do nothing by default. |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 611 | } |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 612 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 613 | extern "C" void software_init_hook(void) |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 614 | { |
| Jaeden Amero |
6336:a0ee59c4aa27 | 615 | #ifdef FEATURE_UVISOR |
| Jaeden Amero |
6336:a0ee59c4aa27 | 616 | int return_code; |
| Jaeden Amero |
6336:a0ee59c4aa27 | 617 | |
| Jaeden Amero |
6336:a0ee59c4aa27 | 618 | return_code = uvisor_lib_init(); |
| Jaeden Amero |
6336:a0ee59c4aa27 | 619 | if (return_code) { |
| Jaeden Amero |
6336:a0ee59c4aa27 | 620 | mbed_die(); |
| Jaeden Amero |
6336:a0ee59c4aa27 | 621 | } |
| Jaeden Amero |
6336:a0ee59c4aa27 | 622 | #endif/* FEATURE_UVISOR */ |
| Jaeden Amero |
6336:a0ee59c4aa27 | 623 | |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 624 | software_init_hook_rtos(); |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 625 | } |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 626 | #endif |
| Jaeden Amero |
6335:6fbbee1c9fd1 | 627 | |
| Russ Butler |
7514:a0c71f3f3d2f | 628 | #if defined(TOOLCHAIN_ARM) && (defined(MBED_HEAP_STATS_ENABLED ) && MBED_HEAP_STATS_ENABLED ) |
| Russ Butler |
7514:a0c71f3f3d2f | 629 | |
| Russ Butler |
7514:a0c71f3f3d2f | 630 | extern "C" void *$Super$$malloc(size_t size); |
| Russ Butler |
7514:a0c71f3f3d2f | 631 | extern "C" void *$Super$$realloc(void * ptr, size_t size); |
| Russ Butler |
7514:a0c71f3f3d2f | 632 | extern "C" void $Super$$free(void * ptr); |
| Russ Butler |
7514:a0c71f3f3d2f | 633 | |
| Russ Butler |
7514:a0c71f3f3d2f | 634 | extern "C" void *$Sub$$malloc(size_t size) |
| Russ Butler |
7514:a0c71f3f3d2f | 635 | { |
| Russ Butler |
7514:a0c71f3f3d2f | 636 | malloc_stats_mutex->lock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 637 | alloc_info_t *alloc_info = (alloc_info_t*)$Super$$malloc(size + sizeof(alloc_info_t)); |
| Russ Butler |
7514:a0c71f3f3d2f | 638 | void *ptr = NULL; |
| Russ Butler |
7514:a0c71f3f3d2f | 639 | if (alloc_info != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 640 | alloc_info->size = size; |
| Russ Butler |
7514:a0c71f3f3d2f | 641 | ptr = (void*)(alloc_info + 1); |
| Russ Butler |
7514:a0c71f3f3d2f | 642 | heap_stats.current_size += size; |
| Russ Butler |
7514:a0c71f3f3d2f | 643 | heap_stats.total_size += size; |
| Russ Butler |
7514:a0c71f3f3d2f | 644 | heap_stats.alloc_cnt += 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 645 | if (heap_stats.current_size > heap_stats.max_size) { |
| Russ Butler |
7514:a0c71f3f3d2f | 646 | heap_stats.max_size = heap_stats.current_size; |
| Russ Butler |
7514:a0c71f3f3d2f | 647 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 648 | } else { |
| Russ Butler |
7514:a0c71f3f3d2f | 649 | heap_stats.alloc_fail_cnt += 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 650 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 651 | malloc_stats_mutex->unlock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 652 | |
| Russ Butler |
7514:a0c71f3f3d2f | 653 | return ptr; |
| Russ Butler |
7514:a0c71f3f3d2f | 654 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 655 | |
| Russ Butler |
7514:a0c71f3f3d2f | 656 | extern "C" void *$Sub$$realloc(void * ptr, size_t size) |
| Russ Butler |
7514:a0c71f3f3d2f | 657 | { |
| Russ Butler |
7514:a0c71f3f3d2f | 658 | // Note - no lock needed since malloc and free are thread safe |
| Russ Butler |
7514:a0c71f3f3d2f | 659 | |
| Russ Butler |
7514:a0c71f3f3d2f | 660 | // Get old size |
| Russ Butler |
7514:a0c71f3f3d2f | 661 | uint32_t old_size = 0; |
| Russ Butler |
7514:a0c71f3f3d2f | 662 | if (ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 663 | alloc_info_t *alloc_info = ((alloc_info_t*)ptr) - 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 664 | old_size = alloc_info->size; |
| Russ Butler |
7514:a0c71f3f3d2f | 665 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 666 | |
| Russ Butler |
7514:a0c71f3f3d2f | 667 | // Allocate space |
| Russ Butler |
7514:a0c71f3f3d2f | 668 | void *new_ptr = NULL; |
| Russ Butler |
7514:a0c71f3f3d2f | 669 | if (size != 0) { |
| Russ Butler |
7514:a0c71f3f3d2f | 670 | new_ptr = malloc(size); |
| Russ Butler |
7514:a0c71f3f3d2f | 671 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 672 | |
| Russ Butler |
7514:a0c71f3f3d2f | 673 | // If the new buffer has been allocated copy the data to it |
| Russ Butler |
7514:a0c71f3f3d2f | 674 | // and free the old buffer |
| Russ Butler |
7514:a0c71f3f3d2f | 675 | if (new_ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 676 | uint32_t copy_size = (old_size < size) ? old_size : size; |
| Russ Butler |
7514:a0c71f3f3d2f | 677 | memcpy(new_ptr, (void*)ptr, copy_size); |
| Russ Butler |
7514:a0c71f3f3d2f | 678 | free(ptr); |
| Russ Butler |
7514:a0c71f3f3d2f | 679 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 680 | |
| Russ Butler |
7514:a0c71f3f3d2f | 681 | return new_ptr; |
| Russ Butler |
7514:a0c71f3f3d2f | 682 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 683 | extern "C" void $Sub$$free(void * ptr) |
| Russ Butler |
7514:a0c71f3f3d2f | 684 | { |
| Russ Butler |
7514:a0c71f3f3d2f | 685 | malloc_stats_mutex->lock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 686 | alloc_info_t *alloc_info = NULL; |
| Russ Butler |
7514:a0c71f3f3d2f | 687 | if (ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 688 | alloc_info = ((alloc_info_t*)ptr) - 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 689 | heap_stats.current_size -= alloc_info->size; |
| Russ Butler |
7514:a0c71f3f3d2f | 690 | heap_stats.alloc_cnt -= 1; |
| Russ Butler |
7514:a0c71f3f3d2f | 691 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 692 | $Super$$free((void*)alloc_info); |
| Russ Butler |
7514:a0c71f3f3d2f | 693 | malloc_stats_mutex->unlock(); |
| Russ Butler |
7514:a0c71f3f3d2f | 694 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 695 | extern "C" void *$Sub$$calloc(size_t num, size_t size) |
| Russ Butler |
7514:a0c71f3f3d2f | 696 | { |
| Russ Butler |
7514:a0c71f3f3d2f | 697 | // Note - no lock needed since malloc is thread safe |
| Russ Butler |
7514:a0c71f3f3d2f | 698 | void *ptr = malloc(num * size); |
| Russ Butler |
7514:a0c71f3f3d2f | 699 | if (ptr != NULL) { |
| Russ Butler |
7514:a0c71f3f3d2f | 700 | memset(ptr, 0, num * size); |
| Russ Butler |
7514:a0c71f3f3d2f | 701 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 702 | return ptr; |
| Russ Butler |
7514:a0c71f3f3d2f | 703 | } |
| Russ Butler |
7514:a0c71f3f3d2f | 704 | |
| Russ Butler |
7514:a0c71f3f3d2f | 705 | #endif /* defined(TOOLCHAIN_ARM) && (defined(MBED_HEAP_STATS_ENABLED ) && MBED_HEAP_STATS_ENABLED ) */ |
| Russ Butler |
7514:a0c71f3f3d2f | 706 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 707 | // **************************************************************************** |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 708 | // mbed_main is a function that is called before main() |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 709 | // mbed_sdk_init() is also a function that is called before main(), but unlike |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 710 | // mbed_main(), it is not meant for user code, but for the SDK itself to perform |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 711 | // initializations before main() is called. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 712 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 713 | extern "C" WEAK void mbed_main(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 714 | extern "C" WEAK void mbed_main(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 715 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 716 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 717 | extern "C" WEAK void mbed_sdk_init(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 718 | extern "C" WEAK void mbed_sdk_init(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 719 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 720 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 721 | #if defined(TOOLCHAIN_ARM) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 722 | extern "C" int $Super$$main(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 723 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 724 | extern "C" int $Sub$$main(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 725 | mbed_sdk_init(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 726 | mbed_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 727 | return $Super$$main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 728 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 729 | #elif defined(TOOLCHAIN_GCC) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 730 | extern "C" int __real_main(void); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 731 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 732 | extern "C" int __wrap_main(void) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 733 | mbed_sdk_init(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 734 | mbed_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 735 | return __real_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 736 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 737 | #elif defined(TOOLCHAIN_IAR) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 738 | // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 739 | // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 740 | // 'main' to another symbol looses the original 'main' symbol. However, its startup |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 741 | // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 742 | // Since mbed doesn't use argc/argv, we use this function to call our mbed_main. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 743 | extern "C" void __iar_argc_argv() { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 744 | mbed_main(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 745 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 746 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 747 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 748 | // Provide implementation of _sbrk (low-level dynamic memory allocation |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 749 | // routine) for GCC_ARM which compares new heap pointer with MSP instead of |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 750 | // SP. This make it compatible with RTX RTOS thread stacks. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 751 | #if defined(TOOLCHAIN_GCC_ARM) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 752 | // Linker defined symbol used by _sbrk to indicate where heap should start. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 753 | extern "C" int __end__; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 754 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 755 | #if defined(TARGET_CORTEX_A) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 756 | extern "C" uint32_t __HeapLimit; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 757 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 758 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 759 | // Turn off the errno macro and use actual global variable instead. |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 760 | #undef errno |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 761 | extern "C" int errno; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 762 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 763 | // For ARM7 only |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 764 | register unsigned char * stack_ptr __asm ("sp"); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 765 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 766 | // Dynamic memory allocation related syscall. |
| ccli8 |
7328:33c1e9a22f71 | 767 | #if defined(TARGET_NUMAKER_PFM_NUC472) |
| ccli8 |
7328:33c1e9a22f71 | 768 | // Overwrite _sbrk() to support two region model. |
| ccli8 |
7328:33c1e9a22f71 | 769 | extern "C" void *__wrap__sbrk(int incr); |
| ccli8 |
7328:33c1e9a22f71 | 770 | extern "C" caddr_t _sbrk(int incr) { |
| ccli8 |
7328:33c1e9a22f71 | 771 | return (caddr_t) __wrap__sbrk(incr); |
| ccli8 |
7328:33c1e9a22f71 | 772 | } |
| ccli8 |
7328:33c1e9a22f71 | 773 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 774 | extern "C" caddr_t _sbrk(int incr) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 775 | static unsigned char* heap = (unsigned char*)&__end__; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 776 | unsigned char* prev_heap = heap; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 777 | unsigned char* new_heap = heap + incr; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 778 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 779 | #if defined(TARGET_ARM7) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 780 | if (new_heap >= stack_ptr) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 781 | #elif defined(TARGET_CORTEX_A) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 782 | if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 783 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 784 | if (new_heap >= (unsigned char*)__get_MSP()) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 785 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 786 | errno = ENOMEM; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 787 | return (caddr_t)-1; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 788 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 789 | |
| Russ Butler |
7395:79e8c79e165c | 790 | // Additional heap checking if set |
| Russ Butler |
7395:79e8c79e165c | 791 | if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) { |
| Russ Butler |
7395:79e8c79e165c | 792 | errno = ENOMEM; |
| Russ Butler |
7395:79e8c79e165c | 793 | return (caddr_t)-1; |
| Russ Butler |
7395:79e8c79e165c | 794 | } |
| Russ Butler |
7395:79e8c79e165c | 795 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 796 | heap = new_heap; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 797 | return (caddr_t) prev_heap; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 798 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 799 | #endif |
| ccli8 |
7328:33c1e9a22f71 | 800 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 801 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 802 | #if defined TOOLCHAIN_GCC_ARM |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 803 | extern "C" void _exit(int return_code) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 804 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 805 | namespace std { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 806 | extern "C" void exit(int return_code) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 807 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 808 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 809 | #if DEVICE_STDIO_MESSAGES |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 810 | fflush(stdout); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 811 | fflush(stderr); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 812 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 813 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 814 | #if DEVICE_SEMIHOST |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 815 | if (mbed_interface_connected()) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 816 | semihost_exit(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 817 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 818 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 819 | if (return_code) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 820 | mbed_die(); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 821 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 822 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 823 | while (1); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 824 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 825 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 826 | #if !defined(TOOLCHAIN_GCC_ARM) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 827 | } //namespace std |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 828 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 829 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 830 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 831 | namespace mbed { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 832 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 833 | void mbed_set_unbuffered_stream(FILE *_file) { |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 834 | #if defined (__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 835 | char buf[2]; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 836 | std::setvbuf(_file,buf,_IONBF,NULL); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 837 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 838 | setbuf(_file, NULL); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 839 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 840 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 841 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 842 | int mbed_getc(FILE *_file){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 843 | #if defined (__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 844 | /*This is only valid for unbuffered streams*/ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 845 | int res = std::fgetc(_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 846 | if (res>=0){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 847 | _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 848 | _file->_Rend = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 849 | _file->_Next = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 850 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 851 | return res; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 852 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 853 | return std::fgetc(_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 854 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 855 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 856 | |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 857 | char* mbed_gets(char*s, int size, FILE *_file){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 858 | #if defined (__ICCARM__) |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 859 | /*This is only valid for unbuffered streams*/ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 860 | char *str = fgets(s,size,_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 861 | if (str!=NULL){ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 862 | _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 863 | _file->_Rend = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 864 | _file->_Next = _file->_Wend; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 865 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 866 | return str; |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 867 | #else |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 868 | return std::fgets(s,size,_file); |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 869 | #endif |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 870 | } |
| Mihail Stoyanov |
6088:e1cf77a573c5 | 871 | |
| Russ Butler |
7514:a0c71f3f3d2f | 872 | } // namespace mbed |
| Russ Butler |
7514:a0c71f3f3d2f | 873 | |
| Russ Butler |
6200:8000bcdea61d | 874 | #if defined (__ICCARM__) |
| Russ Butler |
6200:8000bcdea61d | 875 | // Stub out locks when an rtos is not present |
| Russ Butler |
6200:8000bcdea61d | 876 | extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 877 | extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 878 | extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 879 | extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 880 | extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 881 | extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 882 | extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6200:8000bcdea61d | 883 | extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {} |
| Russ Butler |
6387:1e339dc397e1 | 884 | #elif defined(__CC_ARM) |
| Russ Butler |
6387:1e339dc397e1 | 885 | // Do nothing |
| Russ Butler |
6387:1e339dc397e1 | 886 | #elif defined (__GNUC__) |
| Russ Butler |
6387:1e339dc397e1 | 887 | struct _reent; |
| Russ Butler |
6387:1e339dc397e1 | 888 | // Stub out locks when an rtos is not present |
| Russ Butler |
6387:1e339dc397e1 | 889 | extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 890 | extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 891 | extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 892 | extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {} |
| Russ Butler |
6387:1e339dc397e1 | 893 | |
| Russ Butler |
6396:723dcc4c67dd | 894 | extern "C" void __malloc_lock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 895 | { |
| Russ Butler |
6387:1e339dc397e1 | 896 | __rtos_malloc_lock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 897 | } |
| Russ Butler |
6387:1e339dc397e1 | 898 | |
| Russ Butler |
6396:723dcc4c67dd | 899 | extern "C" void __malloc_unlock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 900 | { |
| Russ Butler |
6387:1e339dc397e1 | 901 | __rtos_malloc_unlock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 902 | } |
| Russ Butler |
6387:1e339dc397e1 | 903 | |
| Russ Butler |
6396:723dcc4c67dd | 904 | extern "C" void __env_lock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 905 | { |
| Russ Butler |
6387:1e339dc397e1 | 906 | __rtos_env_lock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 907 | } |
| Russ Butler |
6387:1e339dc397e1 | 908 | |
| Russ Butler |
6396:723dcc4c67dd | 909 | extern "C" void __env_unlock( struct _reent *_r ) |
| Russ Butler |
6387:1e339dc397e1 | 910 | { |
| Russ Butler |
6387:1e339dc397e1 | 911 | __rtos_env_unlock(_r); |
| Russ Butler |
6387:1e339dc397e1 | 912 | } |
| Russ Butler |
6200:8000bcdea61d | 913 | #endif |
| Russ Butler |
6200:8000bcdea61d | 914 | |
| Russ Butler |
7397:7448008aec84 | 915 | void *operator new(std::size_t count) |
| Russ Butler |
7397:7448008aec84 | 916 | { |
| Russ Butler |
7397:7448008aec84 | 917 | void *buffer = malloc(count); |
| Russ Butler |
7397:7448008aec84 | 918 | if (NULL == buffer) { |
| Russ Butler |
7397:7448008aec84 | 919 | error("Operator new out of memory\r\n"); |
| Russ Butler |
7397:7448008aec84 | 920 | } |
| Russ Butler |
7397:7448008aec84 | 921 | return buffer; |
| Russ Butler |
7397:7448008aec84 | 922 | } |
| Russ Butler |
7397:7448008aec84 | 923 | |
| Russ Butler |
7397:7448008aec84 | 924 | void *operator new[](std::size_t count) |
| Russ Butler |
7397:7448008aec84 | 925 | { |
| Russ Butler |
7397:7448008aec84 | 926 | void *buffer = malloc(count); |
| Russ Butler |
7397:7448008aec84 | 927 | if (NULL == buffer) { |
| Russ Butler |
7397:7448008aec84 | 928 | error("Operator new[] out of memory\r\n"); |
| Russ Butler |
7397:7448008aec84 | 929 | } |
| Russ Butler |
7397:7448008aec84 | 930 | return buffer; |
| Russ Butler |
7397:7448008aec84 | 931 | } |
| Russ Butler |
7397:7448008aec84 | 932 | |
| Russ Butler |
7397:7448008aec84 | 933 | void operator delete(void *ptr) |
| Russ Butler |
7397:7448008aec84 | 934 | { |
| Russ Butler |
7397:7448008aec84 | 935 | if (ptr != NULL) { |
| Russ Butler |
7397:7448008aec84 | 936 | free(ptr); |
| Russ Butler |
7397:7448008aec84 | 937 | } |
| Russ Butler |
7397:7448008aec84 | 938 | } |
| Russ Butler |
7397:7448008aec84 | 939 | void operator delete[](void *ptr) |
| Russ Butler |
7397:7448008aec84 | 940 | { |
| Russ Butler |
7397:7448008aec84 | 941 | if (ptr != NULL) { |
| Russ Butler |
7397:7448008aec84 | 942 | free(ptr); |
| Russ Butler |
7397:7448008aec84 | 943 | } |
| Russ Butler |
7397:7448008aec84 | 944 | } |