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