Marco Zecchini
/
Example_RTOS
Rtos API example
mbed-os/platform/mbed_retarget.cpp@0:9fca2b23d0ba, 2019-02-23 (annotated)
- Committer:
- marcozecchini
- Date:
- Sat Feb 23 12:13:36 2019 +0000
- Revision:
- 0:9fca2b23d0ba
final commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
marcozecchini | 0:9fca2b23d0ba | 1 | /* mbed Microcontroller Library |
marcozecchini | 0:9fca2b23d0ba | 2 | * Copyright (c) 2006-2015 ARM Limited |
marcozecchini | 0:9fca2b23d0ba | 3 | * |
marcozecchini | 0:9fca2b23d0ba | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
marcozecchini | 0:9fca2b23d0ba | 5 | * you may not use this file except in compliance with the License. |
marcozecchini | 0:9fca2b23d0ba | 6 | * You may obtain a copy of the License at |
marcozecchini | 0:9fca2b23d0ba | 7 | * |
marcozecchini | 0:9fca2b23d0ba | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
marcozecchini | 0:9fca2b23d0ba | 9 | * |
marcozecchini | 0:9fca2b23d0ba | 10 | * Unless required by applicable law or agreed to in writing, software |
marcozecchini | 0:9fca2b23d0ba | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
marcozecchini | 0:9fca2b23d0ba | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
marcozecchini | 0:9fca2b23d0ba | 13 | * See the License for the specific language governing permissions and |
marcozecchini | 0:9fca2b23d0ba | 14 | * limitations under the License. |
marcozecchini | 0:9fca2b23d0ba | 15 | */ |
marcozecchini | 0:9fca2b23d0ba | 16 | #include <time.h> |
marcozecchini | 0:9fca2b23d0ba | 17 | #include "platform/platform.h" |
marcozecchini | 0:9fca2b23d0ba | 18 | #include "platform/FilePath.h" |
marcozecchini | 0:9fca2b23d0ba | 19 | #include "hal/serial_api.h" |
marcozecchini | 0:9fca2b23d0ba | 20 | #include "hal/us_ticker_api.h" |
marcozecchini | 0:9fca2b23d0ba | 21 | #include "platform/mbed_toolchain.h" |
marcozecchini | 0:9fca2b23d0ba | 22 | #include "platform/mbed_semihost_api.h" |
marcozecchini | 0:9fca2b23d0ba | 23 | #include "platform/mbed_interface.h" |
marcozecchini | 0:9fca2b23d0ba | 24 | #include "platform/SingletonPtr.h" |
marcozecchini | 0:9fca2b23d0ba | 25 | #include "platform/PlatformMutex.h" |
marcozecchini | 0:9fca2b23d0ba | 26 | #include "platform/mbed_error.h" |
marcozecchini | 0:9fca2b23d0ba | 27 | #include "platform/mbed_stats.h" |
marcozecchini | 0:9fca2b23d0ba | 28 | #include "platform/mbed_critical.h" |
marcozecchini | 0:9fca2b23d0ba | 29 | #include "platform/PlatformMutex.h" |
marcozecchini | 0:9fca2b23d0ba | 30 | #include "us_ticker_api.h" |
marcozecchini | 0:9fca2b23d0ba | 31 | #include "lp_ticker_api.h" |
marcozecchini | 0:9fca2b23d0ba | 32 | #include <stdlib.h> |
marcozecchini | 0:9fca2b23d0ba | 33 | #include <string.h> |
marcozecchini | 0:9fca2b23d0ba | 34 | #include <limits.h> |
marcozecchini | 0:9fca2b23d0ba | 35 | #if DEVICE_STDIO_MESSAGES |
marcozecchini | 0:9fca2b23d0ba | 36 | #include <stdio.h> |
marcozecchini | 0:9fca2b23d0ba | 37 | #endif |
marcozecchini | 0:9fca2b23d0ba | 38 | #include <errno.h> |
marcozecchini | 0:9fca2b23d0ba | 39 | #include "platform/mbed_retarget.h" |
marcozecchini | 0:9fca2b23d0ba | 40 | |
marcozecchini | 0:9fca2b23d0ba | 41 | static SingletonPtr<PlatformMutex> _mutex; |
marcozecchini | 0:9fca2b23d0ba | 42 | |
marcozecchini | 0:9fca2b23d0ba | 43 | #if defined(__ARMCC_VERSION) |
marcozecchini | 0:9fca2b23d0ba | 44 | # if __ARMCC_VERSION >= 6010050 |
marcozecchini | 0:9fca2b23d0ba | 45 | # include <arm_compat.h> |
marcozecchini | 0:9fca2b23d0ba | 46 | # endif |
marcozecchini | 0:9fca2b23d0ba | 47 | # include <rt_sys.h> |
marcozecchini | 0:9fca2b23d0ba | 48 | # include <rt_misc.h> |
marcozecchini | 0:9fca2b23d0ba | 49 | # include <stdint.h> |
marcozecchini | 0:9fca2b23d0ba | 50 | # define PREFIX(x) _sys##x |
marcozecchini | 0:9fca2b23d0ba | 51 | # define OPEN_MAX _SYS_OPEN |
marcozecchini | 0:9fca2b23d0ba | 52 | # ifdef __MICROLIB |
marcozecchini | 0:9fca2b23d0ba | 53 | # pragma import(__use_full_stdio) |
marcozecchini | 0:9fca2b23d0ba | 54 | # endif |
marcozecchini | 0:9fca2b23d0ba | 55 | |
marcozecchini | 0:9fca2b23d0ba | 56 | #elif defined(__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 57 | # include <yfuns.h> |
marcozecchini | 0:9fca2b23d0ba | 58 | # define PREFIX(x) _##x |
marcozecchini | 0:9fca2b23d0ba | 59 | # define OPEN_MAX 16 |
marcozecchini | 0:9fca2b23d0ba | 60 | |
marcozecchini | 0:9fca2b23d0ba | 61 | # define STDIN_FILENO 0 |
marcozecchini | 0:9fca2b23d0ba | 62 | # define STDOUT_FILENO 1 |
marcozecchini | 0:9fca2b23d0ba | 63 | # define STDERR_FILENO 2 |
marcozecchini | 0:9fca2b23d0ba | 64 | |
marcozecchini | 0:9fca2b23d0ba | 65 | #else |
marcozecchini | 0:9fca2b23d0ba | 66 | # include <sys/syslimits.h> |
marcozecchini | 0:9fca2b23d0ba | 67 | # define PREFIX(x) x |
marcozecchini | 0:9fca2b23d0ba | 68 | #endif |
marcozecchini | 0:9fca2b23d0ba | 69 | |
marcozecchini | 0:9fca2b23d0ba | 70 | #define FILE_HANDLE_RESERVED 0xFFFFFFFF |
marcozecchini | 0:9fca2b23d0ba | 71 | |
marcozecchini | 0:9fca2b23d0ba | 72 | using namespace mbed; |
marcozecchini | 0:9fca2b23d0ba | 73 | |
marcozecchini | 0:9fca2b23d0ba | 74 | #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) |
marcozecchini | 0:9fca2b23d0ba | 75 | // Before version 5.03, we were using a patched version of microlib with proper names |
marcozecchini | 0:9fca2b23d0ba | 76 | extern const char __stdin_name[] = ":tt"; |
marcozecchini | 0:9fca2b23d0ba | 77 | extern const char __stdout_name[] = ":tt"; |
marcozecchini | 0:9fca2b23d0ba | 78 | extern const char __stderr_name[] = ":tt"; |
marcozecchini | 0:9fca2b23d0ba | 79 | |
marcozecchini | 0:9fca2b23d0ba | 80 | #else |
marcozecchini | 0:9fca2b23d0ba | 81 | extern const char __stdin_name[] = "/stdin"; |
marcozecchini | 0:9fca2b23d0ba | 82 | extern const char __stdout_name[] = "/stdout"; |
marcozecchini | 0:9fca2b23d0ba | 83 | extern const char __stderr_name[] = "/stderr"; |
marcozecchini | 0:9fca2b23d0ba | 84 | #endif |
marcozecchini | 0:9fca2b23d0ba | 85 | |
marcozecchini | 0:9fca2b23d0ba | 86 | unsigned char *mbed_heap_start = 0; |
marcozecchini | 0:9fca2b23d0ba | 87 | uint32_t mbed_heap_size = 0; |
marcozecchini | 0:9fca2b23d0ba | 88 | |
marcozecchini | 0:9fca2b23d0ba | 89 | /* newlib has the filehandle field in the FILE struct as a short, so |
marcozecchini | 0:9fca2b23d0ba | 90 | * we can't just return a Filehandle* from _open and instead have to |
marcozecchini | 0:9fca2b23d0ba | 91 | * put it in a filehandles array and return the index into that array |
marcozecchini | 0:9fca2b23d0ba | 92 | * (or rather index+3, as filehandles 0-2 are stdin/out/err). |
marcozecchini | 0:9fca2b23d0ba | 93 | */ |
marcozecchini | 0:9fca2b23d0ba | 94 | static FileHandle *filehandles[OPEN_MAX]; |
marcozecchini | 0:9fca2b23d0ba | 95 | static SingletonPtr<PlatformMutex> filehandle_mutex; |
marcozecchini | 0:9fca2b23d0ba | 96 | |
marcozecchini | 0:9fca2b23d0ba | 97 | namespace mbed { |
marcozecchini | 0:9fca2b23d0ba | 98 | void remove_filehandle(FileHandle *file) { |
marcozecchini | 0:9fca2b23d0ba | 99 | filehandle_mutex->lock(); |
marcozecchini | 0:9fca2b23d0ba | 100 | /* Remove all open filehandles for this */ |
marcozecchini | 0:9fca2b23d0ba | 101 | for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { |
marcozecchini | 0:9fca2b23d0ba | 102 | if (filehandles[fh_i] == file) { |
marcozecchini | 0:9fca2b23d0ba | 103 | filehandles[fh_i] = NULL; |
marcozecchini | 0:9fca2b23d0ba | 104 | } |
marcozecchini | 0:9fca2b23d0ba | 105 | } |
marcozecchini | 0:9fca2b23d0ba | 106 | filehandle_mutex->unlock(); |
marcozecchini | 0:9fca2b23d0ba | 107 | } |
marcozecchini | 0:9fca2b23d0ba | 108 | } |
marcozecchini | 0:9fca2b23d0ba | 109 | |
marcozecchini | 0:9fca2b23d0ba | 110 | #if DEVICE_SERIAL |
marcozecchini | 0:9fca2b23d0ba | 111 | extern int stdio_uart_inited; |
marcozecchini | 0:9fca2b23d0ba | 112 | extern serial_t stdio_uart; |
marcozecchini | 0:9fca2b23d0ba | 113 | #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES |
marcozecchini | 0:9fca2b23d0ba | 114 | static char stdio_in_prev; |
marcozecchini | 0:9fca2b23d0ba | 115 | static char stdio_out_prev; |
marcozecchini | 0:9fca2b23d0ba | 116 | #endif |
marcozecchini | 0:9fca2b23d0ba | 117 | #endif |
marcozecchini | 0:9fca2b23d0ba | 118 | |
marcozecchini | 0:9fca2b23d0ba | 119 | static void init_serial() { |
marcozecchini | 0:9fca2b23d0ba | 120 | #if DEVICE_SERIAL |
marcozecchini | 0:9fca2b23d0ba | 121 | if (stdio_uart_inited) return; |
marcozecchini | 0:9fca2b23d0ba | 122 | serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX); |
marcozecchini | 0:9fca2b23d0ba | 123 | #if MBED_CONF_PLATFORM_STDIO_BAUD_RATE |
marcozecchini | 0:9fca2b23d0ba | 124 | serial_baud(&stdio_uart, MBED_CONF_PLATFORM_STDIO_BAUD_RATE); |
marcozecchini | 0:9fca2b23d0ba | 125 | #endif |
marcozecchini | 0:9fca2b23d0ba | 126 | #endif |
marcozecchini | 0:9fca2b23d0ba | 127 | } |
marcozecchini | 0:9fca2b23d0ba | 128 | |
marcozecchini | 0:9fca2b23d0ba | 129 | /** |
marcozecchini | 0:9fca2b23d0ba | 130 | * Sets errno when file opening fails. |
marcozecchini | 0:9fca2b23d0ba | 131 | * Wipes out the filehandle too. |
marcozecchini | 0:9fca2b23d0ba | 132 | * |
marcozecchini | 0:9fca2b23d0ba | 133 | * @param error is a negative error code returned from an mbed function and |
marcozecchini | 0:9fca2b23d0ba | 134 | * will be negated to store a positive error code in errno |
marcozecchini | 0:9fca2b23d0ba | 135 | */ |
marcozecchini | 0:9fca2b23d0ba | 136 | static int handle_open_errors(int error, unsigned filehandle_idx) { |
marcozecchini | 0:9fca2b23d0ba | 137 | errno = -error; |
marcozecchini | 0:9fca2b23d0ba | 138 | // Free file handle |
marcozecchini | 0:9fca2b23d0ba | 139 | filehandles[filehandle_idx] = NULL; |
marcozecchini | 0:9fca2b23d0ba | 140 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 141 | } |
marcozecchini | 0:9fca2b23d0ba | 142 | |
marcozecchini | 0:9fca2b23d0ba | 143 | static inline int openmode_to_posix(int openmode) { |
marcozecchini | 0:9fca2b23d0ba | 144 | int posix = openmode; |
marcozecchini | 0:9fca2b23d0ba | 145 | #ifdef __ARMCC_VERSION |
marcozecchini | 0:9fca2b23d0ba | 146 | if (openmode & OPEN_PLUS) { |
marcozecchini | 0:9fca2b23d0ba | 147 | posix = O_RDWR; |
marcozecchini | 0:9fca2b23d0ba | 148 | } else if(openmode & OPEN_W) { |
marcozecchini | 0:9fca2b23d0ba | 149 | posix = O_WRONLY; |
marcozecchini | 0:9fca2b23d0ba | 150 | } else if(openmode & OPEN_A) { |
marcozecchini | 0:9fca2b23d0ba | 151 | posix = O_WRONLY|O_APPEND; |
marcozecchini | 0:9fca2b23d0ba | 152 | } else { |
marcozecchini | 0:9fca2b23d0ba | 153 | posix = O_RDONLY; |
marcozecchini | 0:9fca2b23d0ba | 154 | } |
marcozecchini | 0:9fca2b23d0ba | 155 | /* a, w, a+, w+ all create if file does not already exist */ |
marcozecchini | 0:9fca2b23d0ba | 156 | if (openmode & (OPEN_A|OPEN_W)) { |
marcozecchini | 0:9fca2b23d0ba | 157 | posix |= O_CREAT; |
marcozecchini | 0:9fca2b23d0ba | 158 | } |
marcozecchini | 0:9fca2b23d0ba | 159 | /* w and w+ truncate */ |
marcozecchini | 0:9fca2b23d0ba | 160 | if (openmode & OPEN_W) { |
marcozecchini | 0:9fca2b23d0ba | 161 | posix |= O_TRUNC; |
marcozecchini | 0:9fca2b23d0ba | 162 | } |
marcozecchini | 0:9fca2b23d0ba | 163 | #elif defined(__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 164 | switch (openmode & _LLIO_RDWRMASK) { |
marcozecchini | 0:9fca2b23d0ba | 165 | case _LLIO_RDONLY: posix = O_RDONLY; break; |
marcozecchini | 0:9fca2b23d0ba | 166 | case _LLIO_WRONLY: posix = O_WRONLY; break; |
marcozecchini | 0:9fca2b23d0ba | 167 | case _LLIO_RDWR : posix = O_RDWR ; break; |
marcozecchini | 0:9fca2b23d0ba | 168 | } |
marcozecchini | 0:9fca2b23d0ba | 169 | if (openmode & _LLIO_CREAT ) posix |= O_CREAT; |
marcozecchini | 0:9fca2b23d0ba | 170 | if (openmode & _LLIO_APPEND) posix |= O_APPEND; |
marcozecchini | 0:9fca2b23d0ba | 171 | if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC; |
marcozecchini | 0:9fca2b23d0ba | 172 | #elif defined(TOOLCHAIN_GCC) |
marcozecchini | 0:9fca2b23d0ba | 173 | posix &= ~O_BINARY; |
marcozecchini | 0:9fca2b23d0ba | 174 | #endif |
marcozecchini | 0:9fca2b23d0ba | 175 | return posix; |
marcozecchini | 0:9fca2b23d0ba | 176 | } |
marcozecchini | 0:9fca2b23d0ba | 177 | |
marcozecchini | 0:9fca2b23d0ba | 178 | /* @brief standard c library fopen() retargeting function. |
marcozecchini | 0:9fca2b23d0ba | 179 | * |
marcozecchini | 0:9fca2b23d0ba | 180 | * This function is invoked by the standard c library retargeting to handle fopen() |
marcozecchini | 0:9fca2b23d0ba | 181 | * |
marcozecchini | 0:9fca2b23d0ba | 182 | * @return |
marcozecchini | 0:9fca2b23d0ba | 183 | * On success, a valid FILEHANDLE is returned. |
marcozecchini | 0:9fca2b23d0ba | 184 | * On failure, -1 is returned and errno is set to an appropriate value e.g. |
marcozecchini | 0:9fca2b23d0ba | 185 | * ENOENT file not found (default errno setting) |
marcozecchini | 0:9fca2b23d0ba | 186 | * EMFILE the maximum number of open files was exceeded. |
marcozecchini | 0:9fca2b23d0ba | 187 | * |
marcozecchini | 0:9fca2b23d0ba | 188 | * */ |
marcozecchini | 0:9fca2b23d0ba | 189 | extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { |
marcozecchini | 0:9fca2b23d0ba | 190 | #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000) |
marcozecchini | 0:9fca2b23d0ba | 191 | #if !defined(MBED_CONF_RTOS_PRESENT) |
marcozecchini | 0:9fca2b23d0ba | 192 | // valid only for mbed 2 |
marcozecchini | 0:9fca2b23d0ba | 193 | // for ulib, this is invoked after RAM init, prior c++ |
marcozecchini | 0:9fca2b23d0ba | 194 | // used as hook, as post stack/heap is not active there |
marcozecchini | 0:9fca2b23d0ba | 195 | extern void mbed_copy_nvic(void); |
marcozecchini | 0:9fca2b23d0ba | 196 | extern void mbed_sdk_init(void); |
marcozecchini | 0:9fca2b23d0ba | 197 | |
marcozecchini | 0:9fca2b23d0ba | 198 | static int mbed_sdk_inited = 0; |
marcozecchini | 0:9fca2b23d0ba | 199 | if (!mbed_sdk_inited) { |
marcozecchini | 0:9fca2b23d0ba | 200 | mbed_copy_nvic(); |
marcozecchini | 0:9fca2b23d0ba | 201 | mbed_sdk_init(); |
marcozecchini | 0:9fca2b23d0ba | 202 | mbed_sdk_inited = 1; |
marcozecchini | 0:9fca2b23d0ba | 203 | } |
marcozecchini | 0:9fca2b23d0ba | 204 | #endif |
marcozecchini | 0:9fca2b23d0ba | 205 | // Before version 5.03, we were using a patched version of microlib with proper names |
marcozecchini | 0:9fca2b23d0ba | 206 | // This is the workaround that the microlib author suggested us |
marcozecchini | 0:9fca2b23d0ba | 207 | static int n = 0; |
marcozecchini | 0:9fca2b23d0ba | 208 | if (!std::strcmp(name, ":tt")) return n++; |
marcozecchini | 0:9fca2b23d0ba | 209 | #else |
marcozecchini | 0:9fca2b23d0ba | 210 | /* Use the posix convention that stdin,out,err are filehandles 0,1,2. |
marcozecchini | 0:9fca2b23d0ba | 211 | */ |
marcozecchini | 0:9fca2b23d0ba | 212 | if (std::strcmp(name, __stdin_name) == 0) { |
marcozecchini | 0:9fca2b23d0ba | 213 | init_serial(); |
marcozecchini | 0:9fca2b23d0ba | 214 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 215 | } else if (std::strcmp(name, __stdout_name) == 0) { |
marcozecchini | 0:9fca2b23d0ba | 216 | init_serial(); |
marcozecchini | 0:9fca2b23d0ba | 217 | return 1; |
marcozecchini | 0:9fca2b23d0ba | 218 | } else if (std::strcmp(name, __stderr_name) == 0) { |
marcozecchini | 0:9fca2b23d0ba | 219 | init_serial(); |
marcozecchini | 0:9fca2b23d0ba | 220 | return 2; |
marcozecchini | 0:9fca2b23d0ba | 221 | } |
marcozecchini | 0:9fca2b23d0ba | 222 | #endif |
marcozecchini | 0:9fca2b23d0ba | 223 | |
marcozecchini | 0:9fca2b23d0ba | 224 | // find the first empty slot in filehandles |
marcozecchini | 0:9fca2b23d0ba | 225 | filehandle_mutex->lock(); |
marcozecchini | 0:9fca2b23d0ba | 226 | unsigned int fh_i; |
marcozecchini | 0:9fca2b23d0ba | 227 | for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { |
marcozecchini | 0:9fca2b23d0ba | 228 | /* Take a next free filehandle slot available. */ |
marcozecchini | 0:9fca2b23d0ba | 229 | if (filehandles[fh_i] == NULL) break; |
marcozecchini | 0:9fca2b23d0ba | 230 | } |
marcozecchini | 0:9fca2b23d0ba | 231 | if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { |
marcozecchini | 0:9fca2b23d0ba | 232 | /* Too many file handles have been opened */ |
marcozecchini | 0:9fca2b23d0ba | 233 | errno = EMFILE; |
marcozecchini | 0:9fca2b23d0ba | 234 | filehandle_mutex->unlock(); |
marcozecchini | 0:9fca2b23d0ba | 235 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 236 | } |
marcozecchini | 0:9fca2b23d0ba | 237 | filehandles[fh_i] = (FileHandle*)FILE_HANDLE_RESERVED; |
marcozecchini | 0:9fca2b23d0ba | 238 | filehandle_mutex->unlock(); |
marcozecchini | 0:9fca2b23d0ba | 239 | |
marcozecchini | 0:9fca2b23d0ba | 240 | FileHandle *res = NULL; |
marcozecchini | 0:9fca2b23d0ba | 241 | |
marcozecchini | 0:9fca2b23d0ba | 242 | /* FILENAME: ":(pointer)" describes a FileHandle* */ |
marcozecchini | 0:9fca2b23d0ba | 243 | if (name[0] == ':') { |
marcozecchini | 0:9fca2b23d0ba | 244 | void *p; |
marcozecchini | 0:9fca2b23d0ba | 245 | memcpy(&p, name + 1, sizeof(p)); |
marcozecchini | 0:9fca2b23d0ba | 246 | res = (FileHandle*)p; |
marcozecchini | 0:9fca2b23d0ba | 247 | |
marcozecchini | 0:9fca2b23d0ba | 248 | /* FILENAME: "/file_system/file_name" */ |
marcozecchini | 0:9fca2b23d0ba | 249 | } else { |
marcozecchini | 0:9fca2b23d0ba | 250 | FilePath path(name); |
marcozecchini | 0:9fca2b23d0ba | 251 | |
marcozecchini | 0:9fca2b23d0ba | 252 | if (!path.exists()) { |
marcozecchini | 0:9fca2b23d0ba | 253 | /* The first part of the filename (between first 2 '/') is not a |
marcozecchini | 0:9fca2b23d0ba | 254 | * registered mount point in the namespace. |
marcozecchini | 0:9fca2b23d0ba | 255 | */ |
marcozecchini | 0:9fca2b23d0ba | 256 | return handle_open_errors(-ENODEV, fh_i); |
marcozecchini | 0:9fca2b23d0ba | 257 | } |
marcozecchini | 0:9fca2b23d0ba | 258 | |
marcozecchini | 0:9fca2b23d0ba | 259 | if (path.isFile()) { |
marcozecchini | 0:9fca2b23d0ba | 260 | res = path.file(); |
marcozecchini | 0:9fca2b23d0ba | 261 | } else { |
marcozecchini | 0:9fca2b23d0ba | 262 | FileSystemHandle *fs = path.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 263 | if (fs == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 264 | return handle_open_errors(-ENODEV, fh_i); |
marcozecchini | 0:9fca2b23d0ba | 265 | } |
marcozecchini | 0:9fca2b23d0ba | 266 | int posix_mode = openmode_to_posix(openmode); |
marcozecchini | 0:9fca2b23d0ba | 267 | int err = fs->open(&res, path.fileName(), posix_mode); |
marcozecchini | 0:9fca2b23d0ba | 268 | if (err) { |
marcozecchini | 0:9fca2b23d0ba | 269 | return handle_open_errors(err, fh_i); |
marcozecchini | 0:9fca2b23d0ba | 270 | } |
marcozecchini | 0:9fca2b23d0ba | 271 | } |
marcozecchini | 0:9fca2b23d0ba | 272 | } |
marcozecchini | 0:9fca2b23d0ba | 273 | |
marcozecchini | 0:9fca2b23d0ba | 274 | filehandles[fh_i] = res; |
marcozecchini | 0:9fca2b23d0ba | 275 | |
marcozecchini | 0:9fca2b23d0ba | 276 | return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err |
marcozecchini | 0:9fca2b23d0ba | 277 | } |
marcozecchini | 0:9fca2b23d0ba | 278 | |
marcozecchini | 0:9fca2b23d0ba | 279 | extern "C" int PREFIX(_close)(FILEHANDLE fh) { |
marcozecchini | 0:9fca2b23d0ba | 280 | if (fh < 3) return 0; |
marcozecchini | 0:9fca2b23d0ba | 281 | |
marcozecchini | 0:9fca2b23d0ba | 282 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 283 | filehandles[fh-3] = NULL; |
marcozecchini | 0:9fca2b23d0ba | 284 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 285 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 286 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 287 | } |
marcozecchini | 0:9fca2b23d0ba | 288 | |
marcozecchini | 0:9fca2b23d0ba | 289 | int err = fhc->close(); |
marcozecchini | 0:9fca2b23d0ba | 290 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 291 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 292 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 293 | } else { |
marcozecchini | 0:9fca2b23d0ba | 294 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 295 | } |
marcozecchini | 0:9fca2b23d0ba | 296 | } |
marcozecchini | 0:9fca2b23d0ba | 297 | |
marcozecchini | 0:9fca2b23d0ba | 298 | #if defined(__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 299 | extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { |
marcozecchini | 0:9fca2b23d0ba | 300 | #else |
marcozecchini | 0:9fca2b23d0ba | 301 | extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { |
marcozecchini | 0:9fca2b23d0ba | 302 | #endif |
marcozecchini | 0:9fca2b23d0ba | 303 | int n; // n is the number of bytes written |
marcozecchini | 0:9fca2b23d0ba | 304 | |
marcozecchini | 0:9fca2b23d0ba | 305 | #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT) |
marcozecchini | 0:9fca2b23d0ba | 306 | if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) { |
marcozecchini | 0:9fca2b23d0ba | 307 | error("Error - writing to a file in an ISR or critical section\r\n"); |
marcozecchini | 0:9fca2b23d0ba | 308 | } |
marcozecchini | 0:9fca2b23d0ba | 309 | #endif |
marcozecchini | 0:9fca2b23d0ba | 310 | |
marcozecchini | 0:9fca2b23d0ba | 311 | if (fh < 3) { |
marcozecchini | 0:9fca2b23d0ba | 312 | #if DEVICE_SERIAL |
marcozecchini | 0:9fca2b23d0ba | 313 | if (!stdio_uart_inited) init_serial(); |
marcozecchini | 0:9fca2b23d0ba | 314 | #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES |
marcozecchini | 0:9fca2b23d0ba | 315 | for (unsigned int i = 0; i < length; i++) { |
marcozecchini | 0:9fca2b23d0ba | 316 | if (buffer[i] == '\n' && stdio_out_prev != '\r') { |
marcozecchini | 0:9fca2b23d0ba | 317 | serial_putc(&stdio_uart, '\r'); |
marcozecchini | 0:9fca2b23d0ba | 318 | } |
marcozecchini | 0:9fca2b23d0ba | 319 | serial_putc(&stdio_uart, buffer[i]); |
marcozecchini | 0:9fca2b23d0ba | 320 | stdio_out_prev = buffer[i]; |
marcozecchini | 0:9fca2b23d0ba | 321 | } |
marcozecchini | 0:9fca2b23d0ba | 322 | #else |
marcozecchini | 0:9fca2b23d0ba | 323 | for (unsigned int i = 0; i < length; i++) { |
marcozecchini | 0:9fca2b23d0ba | 324 | serial_putc(&stdio_uart, buffer[i]); |
marcozecchini | 0:9fca2b23d0ba | 325 | } |
marcozecchini | 0:9fca2b23d0ba | 326 | #endif |
marcozecchini | 0:9fca2b23d0ba | 327 | #endif |
marcozecchini | 0:9fca2b23d0ba | 328 | n = length; |
marcozecchini | 0:9fca2b23d0ba | 329 | } else { |
marcozecchini | 0:9fca2b23d0ba | 330 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 331 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 332 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 333 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 334 | } |
marcozecchini | 0:9fca2b23d0ba | 335 | |
marcozecchini | 0:9fca2b23d0ba | 336 | n = fhc->write(buffer, length); |
marcozecchini | 0:9fca2b23d0ba | 337 | if (n < 0) { |
marcozecchini | 0:9fca2b23d0ba | 338 | errno = -n; |
marcozecchini | 0:9fca2b23d0ba | 339 | } |
marcozecchini | 0:9fca2b23d0ba | 340 | } |
marcozecchini | 0:9fca2b23d0ba | 341 | #ifdef __ARMCC_VERSION |
marcozecchini | 0:9fca2b23d0ba | 342 | return length-n; |
marcozecchini | 0:9fca2b23d0ba | 343 | #else |
marcozecchini | 0:9fca2b23d0ba | 344 | return n; |
marcozecchini | 0:9fca2b23d0ba | 345 | #endif |
marcozecchini | 0:9fca2b23d0ba | 346 | } |
marcozecchini | 0:9fca2b23d0ba | 347 | |
marcozecchini | 0:9fca2b23d0ba | 348 | #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) |
marcozecchini | 0:9fca2b23d0ba | 349 | extern "C" void PREFIX(_exit)(int return_code) { |
marcozecchini | 0:9fca2b23d0ba | 350 | while(1) {} |
marcozecchini | 0:9fca2b23d0ba | 351 | } |
marcozecchini | 0:9fca2b23d0ba | 352 | |
marcozecchini | 0:9fca2b23d0ba | 353 | extern "C" void _ttywrch(int ch) { |
marcozecchini | 0:9fca2b23d0ba | 354 | serial_putc(&stdio_uart, ch); |
marcozecchini | 0:9fca2b23d0ba | 355 | } |
marcozecchini | 0:9fca2b23d0ba | 356 | #endif |
marcozecchini | 0:9fca2b23d0ba | 357 | |
marcozecchini | 0:9fca2b23d0ba | 358 | #if defined(__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 359 | extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { |
marcozecchini | 0:9fca2b23d0ba | 360 | #else |
marcozecchini | 0:9fca2b23d0ba | 361 | extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { |
marcozecchini | 0:9fca2b23d0ba | 362 | #endif |
marcozecchini | 0:9fca2b23d0ba | 363 | int n; // n is the number of bytes read |
marcozecchini | 0:9fca2b23d0ba | 364 | |
marcozecchini | 0:9fca2b23d0ba | 365 | #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT) |
marcozecchini | 0:9fca2b23d0ba | 366 | if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) { |
marcozecchini | 0:9fca2b23d0ba | 367 | error("Error - reading from a file in an ISR or critical section\r\n"); |
marcozecchini | 0:9fca2b23d0ba | 368 | } |
marcozecchini | 0:9fca2b23d0ba | 369 | #endif |
marcozecchini | 0:9fca2b23d0ba | 370 | |
marcozecchini | 0:9fca2b23d0ba | 371 | if (fh < 3) { |
marcozecchini | 0:9fca2b23d0ba | 372 | // only read a character at a time from stdin |
marcozecchini | 0:9fca2b23d0ba | 373 | #if DEVICE_SERIAL |
marcozecchini | 0:9fca2b23d0ba | 374 | if (!stdio_uart_inited) init_serial(); |
marcozecchini | 0:9fca2b23d0ba | 375 | #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES |
marcozecchini | 0:9fca2b23d0ba | 376 | while (true) { |
marcozecchini | 0:9fca2b23d0ba | 377 | char c = serial_getc(&stdio_uart); |
marcozecchini | 0:9fca2b23d0ba | 378 | if ((c == '\r' && stdio_in_prev != '\n') || |
marcozecchini | 0:9fca2b23d0ba | 379 | (c == '\n' && stdio_in_prev != '\r')) { |
marcozecchini | 0:9fca2b23d0ba | 380 | stdio_in_prev = c; |
marcozecchini | 0:9fca2b23d0ba | 381 | *buffer = '\n'; |
marcozecchini | 0:9fca2b23d0ba | 382 | break; |
marcozecchini | 0:9fca2b23d0ba | 383 | } else if ((c == '\r' && stdio_in_prev == '\n') || |
marcozecchini | 0:9fca2b23d0ba | 384 | (c == '\n' && stdio_in_prev == '\r')) { |
marcozecchini | 0:9fca2b23d0ba | 385 | stdio_in_prev = c; |
marcozecchini | 0:9fca2b23d0ba | 386 | // onto next character |
marcozecchini | 0:9fca2b23d0ba | 387 | continue; |
marcozecchini | 0:9fca2b23d0ba | 388 | } else { |
marcozecchini | 0:9fca2b23d0ba | 389 | stdio_in_prev = c; |
marcozecchini | 0:9fca2b23d0ba | 390 | *buffer = c; |
marcozecchini | 0:9fca2b23d0ba | 391 | break; |
marcozecchini | 0:9fca2b23d0ba | 392 | } |
marcozecchini | 0:9fca2b23d0ba | 393 | } |
marcozecchini | 0:9fca2b23d0ba | 394 | #else |
marcozecchini | 0:9fca2b23d0ba | 395 | *buffer = serial_getc(&stdio_uart); |
marcozecchini | 0:9fca2b23d0ba | 396 | #endif |
marcozecchini | 0:9fca2b23d0ba | 397 | #endif |
marcozecchini | 0:9fca2b23d0ba | 398 | n = 1; |
marcozecchini | 0:9fca2b23d0ba | 399 | } else { |
marcozecchini | 0:9fca2b23d0ba | 400 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 401 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 402 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 403 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 404 | } |
marcozecchini | 0:9fca2b23d0ba | 405 | |
marcozecchini | 0:9fca2b23d0ba | 406 | n = fhc->read(buffer, length); |
marcozecchini | 0:9fca2b23d0ba | 407 | if (n < 0) { |
marcozecchini | 0:9fca2b23d0ba | 408 | errno = -n; |
marcozecchini | 0:9fca2b23d0ba | 409 | } |
marcozecchini | 0:9fca2b23d0ba | 410 | } |
marcozecchini | 0:9fca2b23d0ba | 411 | #ifdef __ARMCC_VERSION |
marcozecchini | 0:9fca2b23d0ba | 412 | return length-n; |
marcozecchini | 0:9fca2b23d0ba | 413 | #else |
marcozecchini | 0:9fca2b23d0ba | 414 | return n; |
marcozecchini | 0:9fca2b23d0ba | 415 | #endif |
marcozecchini | 0:9fca2b23d0ba | 416 | } |
marcozecchini | 0:9fca2b23d0ba | 417 | |
marcozecchini | 0:9fca2b23d0ba | 418 | |
marcozecchini | 0:9fca2b23d0ba | 419 | #ifdef __ARMCC_VERSION |
marcozecchini | 0:9fca2b23d0ba | 420 | extern "C" int PREFIX(_istty)(FILEHANDLE fh) |
marcozecchini | 0:9fca2b23d0ba | 421 | #else |
marcozecchini | 0:9fca2b23d0ba | 422 | extern "C" int _isatty(FILEHANDLE fh) |
marcozecchini | 0:9fca2b23d0ba | 423 | #endif |
marcozecchini | 0:9fca2b23d0ba | 424 | { |
marcozecchini | 0:9fca2b23d0ba | 425 | /* stdin, stdout and stderr should be tty */ |
marcozecchini | 0:9fca2b23d0ba | 426 | if (fh < 3) return 1; |
marcozecchini | 0:9fca2b23d0ba | 427 | |
marcozecchini | 0:9fca2b23d0ba | 428 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 429 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 430 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 431 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 432 | } |
marcozecchini | 0:9fca2b23d0ba | 433 | |
marcozecchini | 0:9fca2b23d0ba | 434 | int tty = fhc->isatty(); |
marcozecchini | 0:9fca2b23d0ba | 435 | if (tty < 0) { |
marcozecchini | 0:9fca2b23d0ba | 436 | errno = -tty; |
marcozecchini | 0:9fca2b23d0ba | 437 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 438 | } else { |
marcozecchini | 0:9fca2b23d0ba | 439 | return tty; |
marcozecchini | 0:9fca2b23d0ba | 440 | } |
marcozecchini | 0:9fca2b23d0ba | 441 | } |
marcozecchini | 0:9fca2b23d0ba | 442 | |
marcozecchini | 0:9fca2b23d0ba | 443 | extern "C" |
marcozecchini | 0:9fca2b23d0ba | 444 | #if defined(__ARMCC_VERSION) |
marcozecchini | 0:9fca2b23d0ba | 445 | int _sys_seek(FILEHANDLE fh, long offset) |
marcozecchini | 0:9fca2b23d0ba | 446 | #elif defined(__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 447 | long __lseek(int fh, long offset, int whence) |
marcozecchini | 0:9fca2b23d0ba | 448 | #else |
marcozecchini | 0:9fca2b23d0ba | 449 | int _lseek(FILEHANDLE fh, int offset, int whence) |
marcozecchini | 0:9fca2b23d0ba | 450 | #endif |
marcozecchini | 0:9fca2b23d0ba | 451 | { |
marcozecchini | 0:9fca2b23d0ba | 452 | #if defined(__ARMCC_VERSION) |
marcozecchini | 0:9fca2b23d0ba | 453 | int whence = SEEK_SET; |
marcozecchini | 0:9fca2b23d0ba | 454 | #endif |
marcozecchini | 0:9fca2b23d0ba | 455 | |
marcozecchini | 0:9fca2b23d0ba | 456 | if (fh < 3) { |
marcozecchini | 0:9fca2b23d0ba | 457 | errno = ESPIPE; |
marcozecchini | 0:9fca2b23d0ba | 458 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 459 | } |
marcozecchini | 0:9fca2b23d0ba | 460 | |
marcozecchini | 0:9fca2b23d0ba | 461 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 462 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 463 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 464 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 465 | } |
marcozecchini | 0:9fca2b23d0ba | 466 | |
marcozecchini | 0:9fca2b23d0ba | 467 | off_t off = fhc->seek(offset, whence); |
marcozecchini | 0:9fca2b23d0ba | 468 | if (off < 0) { |
marcozecchini | 0:9fca2b23d0ba | 469 | errno = -off; |
marcozecchini | 0:9fca2b23d0ba | 470 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 471 | } |
marcozecchini | 0:9fca2b23d0ba | 472 | // Assuming INT_MAX = LONG_MAX, so we don't care about prototype difference |
marcozecchini | 0:9fca2b23d0ba | 473 | if (off > INT_MAX) { |
marcozecchini | 0:9fca2b23d0ba | 474 | errno = EOVERFLOW; |
marcozecchini | 0:9fca2b23d0ba | 475 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 476 | } |
marcozecchini | 0:9fca2b23d0ba | 477 | return off; |
marcozecchini | 0:9fca2b23d0ba | 478 | } |
marcozecchini | 0:9fca2b23d0ba | 479 | |
marcozecchini | 0:9fca2b23d0ba | 480 | #ifdef __ARMCC_VERSION |
marcozecchini | 0:9fca2b23d0ba | 481 | extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { |
marcozecchini | 0:9fca2b23d0ba | 482 | if (fh < 3) return 0; |
marcozecchini | 0:9fca2b23d0ba | 483 | |
marcozecchini | 0:9fca2b23d0ba | 484 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 485 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 486 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 487 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 488 | } |
marcozecchini | 0:9fca2b23d0ba | 489 | |
marcozecchini | 0:9fca2b23d0ba | 490 | int err = fhc->sync(); |
marcozecchini | 0:9fca2b23d0ba | 491 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 492 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 493 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 494 | } else { |
marcozecchini | 0:9fca2b23d0ba | 495 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 496 | } |
marcozecchini | 0:9fca2b23d0ba | 497 | } |
marcozecchini | 0:9fca2b23d0ba | 498 | |
marcozecchini | 0:9fca2b23d0ba | 499 | extern "C" long PREFIX(_flen)(FILEHANDLE fh) { |
marcozecchini | 0:9fca2b23d0ba | 500 | if (fh < 3) { |
marcozecchini | 0:9fca2b23d0ba | 501 | errno = EINVAL; |
marcozecchini | 0:9fca2b23d0ba | 502 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 503 | } |
marcozecchini | 0:9fca2b23d0ba | 504 | |
marcozecchini | 0:9fca2b23d0ba | 505 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 506 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 507 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 508 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 509 | } |
marcozecchini | 0:9fca2b23d0ba | 510 | |
marcozecchini | 0:9fca2b23d0ba | 511 | off_t size = fhc->size(); |
marcozecchini | 0:9fca2b23d0ba | 512 | if (size < 0) { |
marcozecchini | 0:9fca2b23d0ba | 513 | errno = -size; |
marcozecchini | 0:9fca2b23d0ba | 514 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 515 | } |
marcozecchini | 0:9fca2b23d0ba | 516 | if (size > LONG_MAX) { |
marcozecchini | 0:9fca2b23d0ba | 517 | errno = EOVERFLOW; |
marcozecchini | 0:9fca2b23d0ba | 518 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 519 | } |
marcozecchini | 0:9fca2b23d0ba | 520 | return size; |
marcozecchini | 0:9fca2b23d0ba | 521 | } |
marcozecchini | 0:9fca2b23d0ba | 522 | |
marcozecchini | 0:9fca2b23d0ba | 523 | extern "C" char Image$$RW_IRAM1$$ZI$$Limit[]; |
marcozecchini | 0:9fca2b23d0ba | 524 | |
marcozecchini | 0:9fca2b23d0ba | 525 | extern "C" MBED_WEAK __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) |
marcozecchini | 0:9fca2b23d0ba | 526 | { |
marcozecchini | 0:9fca2b23d0ba | 527 | uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; |
marcozecchini | 0:9fca2b23d0ba | 528 | uint32_t sp_limit = __current_sp(); |
marcozecchini | 0:9fca2b23d0ba | 529 | |
marcozecchini | 0:9fca2b23d0ba | 530 | zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned |
marcozecchini | 0:9fca2b23d0ba | 531 | |
marcozecchini | 0:9fca2b23d0ba | 532 | struct __initial_stackheap r; |
marcozecchini | 0:9fca2b23d0ba | 533 | r.heap_base = zi_limit; |
marcozecchini | 0:9fca2b23d0ba | 534 | r.heap_limit = sp_limit; |
marcozecchini | 0:9fca2b23d0ba | 535 | return r; |
marcozecchini | 0:9fca2b23d0ba | 536 | } |
marcozecchini | 0:9fca2b23d0ba | 537 | |
marcozecchini | 0:9fca2b23d0ba | 538 | extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { |
marcozecchini | 0:9fca2b23d0ba | 539 | return _mbed_user_setup_stackheap(R0, R1, R2, R3); |
marcozecchini | 0:9fca2b23d0ba | 540 | } |
marcozecchini | 0:9fca2b23d0ba | 541 | |
marcozecchini | 0:9fca2b23d0ba | 542 | #endif |
marcozecchini | 0:9fca2b23d0ba | 543 | |
marcozecchini | 0:9fca2b23d0ba | 544 | |
marcozecchini | 0:9fca2b23d0ba | 545 | #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 546 | extern "C" int _fstat(int fh, struct stat *st) { |
marcozecchini | 0:9fca2b23d0ba | 547 | if (fh < 3) { |
marcozecchini | 0:9fca2b23d0ba | 548 | st->st_mode = S_IFCHR; |
marcozecchini | 0:9fca2b23d0ba | 549 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 550 | } |
marcozecchini | 0:9fca2b23d0ba | 551 | |
marcozecchini | 0:9fca2b23d0ba | 552 | FileHandle* fhc = filehandles[fh-3]; |
marcozecchini | 0:9fca2b23d0ba | 553 | if (fhc == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 554 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 555 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 556 | } |
marcozecchini | 0:9fca2b23d0ba | 557 | |
marcozecchini | 0:9fca2b23d0ba | 558 | st->st_mode = fhc->isatty() ? S_IFCHR : S_IFREG; |
marcozecchini | 0:9fca2b23d0ba | 559 | st->st_size = fhc->size(); |
marcozecchini | 0:9fca2b23d0ba | 560 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 561 | } |
marcozecchini | 0:9fca2b23d0ba | 562 | #endif |
marcozecchini | 0:9fca2b23d0ba | 563 | |
marcozecchini | 0:9fca2b23d0ba | 564 | namespace std { |
marcozecchini | 0:9fca2b23d0ba | 565 | extern "C" int remove(const char *path) { |
marcozecchini | 0:9fca2b23d0ba | 566 | FilePath fp(path); |
marcozecchini | 0:9fca2b23d0ba | 567 | FileSystemHandle *fs = fp.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 568 | if (fs == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 569 | errno = ENODEV; |
marcozecchini | 0:9fca2b23d0ba | 570 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 571 | } |
marcozecchini | 0:9fca2b23d0ba | 572 | |
marcozecchini | 0:9fca2b23d0ba | 573 | int err = fs->remove(fp.fileName()); |
marcozecchini | 0:9fca2b23d0ba | 574 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 575 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 576 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 577 | } else { |
marcozecchini | 0:9fca2b23d0ba | 578 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 579 | } |
marcozecchini | 0:9fca2b23d0ba | 580 | } |
marcozecchini | 0:9fca2b23d0ba | 581 | |
marcozecchini | 0:9fca2b23d0ba | 582 | extern "C" int rename(const char *oldname, const char *newname) { |
marcozecchini | 0:9fca2b23d0ba | 583 | FilePath fpOld(oldname); |
marcozecchini | 0:9fca2b23d0ba | 584 | FilePath fpNew(newname); |
marcozecchini | 0:9fca2b23d0ba | 585 | FileSystemHandle *fsOld = fpOld.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 586 | FileSystemHandle *fsNew = fpNew.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 587 | |
marcozecchini | 0:9fca2b23d0ba | 588 | if (fsOld == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 589 | errno = ENODEV; |
marcozecchini | 0:9fca2b23d0ba | 590 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 591 | } |
marcozecchini | 0:9fca2b23d0ba | 592 | |
marcozecchini | 0:9fca2b23d0ba | 593 | /* rename only if both files are on the same FS */ |
marcozecchini | 0:9fca2b23d0ba | 594 | if (fsOld != fsNew) { |
marcozecchini | 0:9fca2b23d0ba | 595 | errno = EXDEV; |
marcozecchini | 0:9fca2b23d0ba | 596 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 597 | } |
marcozecchini | 0:9fca2b23d0ba | 598 | |
marcozecchini | 0:9fca2b23d0ba | 599 | int err = fsOld->rename(fpOld.fileName(), fpNew.fileName()); |
marcozecchini | 0:9fca2b23d0ba | 600 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 601 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 602 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 603 | } else { |
marcozecchini | 0:9fca2b23d0ba | 604 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 605 | } |
marcozecchini | 0:9fca2b23d0ba | 606 | } |
marcozecchini | 0:9fca2b23d0ba | 607 | |
marcozecchini | 0:9fca2b23d0ba | 608 | extern "C" char *tmpnam(char *s) { |
marcozecchini | 0:9fca2b23d0ba | 609 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 610 | return NULL; |
marcozecchini | 0:9fca2b23d0ba | 611 | } |
marcozecchini | 0:9fca2b23d0ba | 612 | |
marcozecchini | 0:9fca2b23d0ba | 613 | extern "C" FILE *tmpfile() { |
marcozecchini | 0:9fca2b23d0ba | 614 | errno = EBADF; |
marcozecchini | 0:9fca2b23d0ba | 615 | return NULL; |
marcozecchini | 0:9fca2b23d0ba | 616 | } |
marcozecchini | 0:9fca2b23d0ba | 617 | } // namespace std |
marcozecchini | 0:9fca2b23d0ba | 618 | |
marcozecchini | 0:9fca2b23d0ba | 619 | #ifdef __ARMCC_VERSION |
marcozecchini | 0:9fca2b23d0ba | 620 | extern "C" char *_sys_command_string(char *cmd, int len) { |
marcozecchini | 0:9fca2b23d0ba | 621 | return NULL; |
marcozecchini | 0:9fca2b23d0ba | 622 | } |
marcozecchini | 0:9fca2b23d0ba | 623 | #endif |
marcozecchini | 0:9fca2b23d0ba | 624 | |
marcozecchini | 0:9fca2b23d0ba | 625 | extern "C" DIR *opendir(const char *path) { |
marcozecchini | 0:9fca2b23d0ba | 626 | FilePath fp(path); |
marcozecchini | 0:9fca2b23d0ba | 627 | FileSystemHandle* fs = fp.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 628 | if (fs == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 629 | errno = ENODEV; |
marcozecchini | 0:9fca2b23d0ba | 630 | return NULL; |
marcozecchini | 0:9fca2b23d0ba | 631 | } |
marcozecchini | 0:9fca2b23d0ba | 632 | |
marcozecchini | 0:9fca2b23d0ba | 633 | DirHandle *dir; |
marcozecchini | 0:9fca2b23d0ba | 634 | int err = fs->open(&dir, fp.fileName()); |
marcozecchini | 0:9fca2b23d0ba | 635 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 636 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 637 | return NULL; |
marcozecchini | 0:9fca2b23d0ba | 638 | } |
marcozecchini | 0:9fca2b23d0ba | 639 | |
marcozecchini | 0:9fca2b23d0ba | 640 | return dir; |
marcozecchini | 0:9fca2b23d0ba | 641 | } |
marcozecchini | 0:9fca2b23d0ba | 642 | |
marcozecchini | 0:9fca2b23d0ba | 643 | extern "C" struct dirent *readdir(DIR *dir) { |
marcozecchini | 0:9fca2b23d0ba | 644 | static struct dirent ent; |
marcozecchini | 0:9fca2b23d0ba | 645 | int err = dir->read(&ent); |
marcozecchini | 0:9fca2b23d0ba | 646 | if (err < 1) { |
marcozecchini | 0:9fca2b23d0ba | 647 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 648 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 649 | } |
marcozecchini | 0:9fca2b23d0ba | 650 | return NULL; |
marcozecchini | 0:9fca2b23d0ba | 651 | } |
marcozecchini | 0:9fca2b23d0ba | 652 | |
marcozecchini | 0:9fca2b23d0ba | 653 | return &ent; |
marcozecchini | 0:9fca2b23d0ba | 654 | } |
marcozecchini | 0:9fca2b23d0ba | 655 | |
marcozecchini | 0:9fca2b23d0ba | 656 | extern "C" int closedir(DIR *dir) { |
marcozecchini | 0:9fca2b23d0ba | 657 | int err = dir->close(); |
marcozecchini | 0:9fca2b23d0ba | 658 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 659 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 660 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 661 | } else { |
marcozecchini | 0:9fca2b23d0ba | 662 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 663 | } |
marcozecchini | 0:9fca2b23d0ba | 664 | } |
marcozecchini | 0:9fca2b23d0ba | 665 | |
marcozecchini | 0:9fca2b23d0ba | 666 | extern "C" void rewinddir(DIR *dir) { |
marcozecchini | 0:9fca2b23d0ba | 667 | dir->rewind(); |
marcozecchini | 0:9fca2b23d0ba | 668 | } |
marcozecchini | 0:9fca2b23d0ba | 669 | |
marcozecchini | 0:9fca2b23d0ba | 670 | extern "C" off_t telldir(DIR *dir) { |
marcozecchini | 0:9fca2b23d0ba | 671 | return dir->tell(); |
marcozecchini | 0:9fca2b23d0ba | 672 | } |
marcozecchini | 0:9fca2b23d0ba | 673 | |
marcozecchini | 0:9fca2b23d0ba | 674 | extern "C" void seekdir(DIR *dir, off_t off) { |
marcozecchini | 0:9fca2b23d0ba | 675 | dir->seek(off); |
marcozecchini | 0:9fca2b23d0ba | 676 | } |
marcozecchini | 0:9fca2b23d0ba | 677 | |
marcozecchini | 0:9fca2b23d0ba | 678 | extern "C" int mkdir(const char *path, mode_t mode) { |
marcozecchini | 0:9fca2b23d0ba | 679 | FilePath fp(path); |
marcozecchini | 0:9fca2b23d0ba | 680 | FileSystemHandle *fs = fp.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 681 | if (fs == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 682 | errno = ENODEV; |
marcozecchini | 0:9fca2b23d0ba | 683 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 684 | } |
marcozecchini | 0:9fca2b23d0ba | 685 | |
marcozecchini | 0:9fca2b23d0ba | 686 | int err = fs->mkdir(fp.fileName(), mode); |
marcozecchini | 0:9fca2b23d0ba | 687 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 688 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 689 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 690 | } else { |
marcozecchini | 0:9fca2b23d0ba | 691 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 692 | } |
marcozecchini | 0:9fca2b23d0ba | 693 | } |
marcozecchini | 0:9fca2b23d0ba | 694 | |
marcozecchini | 0:9fca2b23d0ba | 695 | extern "C" int stat(const char *path, struct stat *st) { |
marcozecchini | 0:9fca2b23d0ba | 696 | FilePath fp(path); |
marcozecchini | 0:9fca2b23d0ba | 697 | FileSystemHandle *fs = fp.fileSystem(); |
marcozecchini | 0:9fca2b23d0ba | 698 | if (fs == NULL) { |
marcozecchini | 0:9fca2b23d0ba | 699 | errno = ENODEV; |
marcozecchini | 0:9fca2b23d0ba | 700 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 701 | } |
marcozecchini | 0:9fca2b23d0ba | 702 | |
marcozecchini | 0:9fca2b23d0ba | 703 | int err = fs->stat(fp.fileName(), st); |
marcozecchini | 0:9fca2b23d0ba | 704 | if (err < 0) { |
marcozecchini | 0:9fca2b23d0ba | 705 | errno = -err; |
marcozecchini | 0:9fca2b23d0ba | 706 | return -1; |
marcozecchini | 0:9fca2b23d0ba | 707 | } else { |
marcozecchini | 0:9fca2b23d0ba | 708 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 709 | } |
marcozecchini | 0:9fca2b23d0ba | 710 | } |
marcozecchini | 0:9fca2b23d0ba | 711 | |
marcozecchini | 0:9fca2b23d0ba | 712 | #if defined(TOOLCHAIN_GCC) |
marcozecchini | 0:9fca2b23d0ba | 713 | /* prevents the exception handling name demangling code getting pulled in */ |
marcozecchini | 0:9fca2b23d0ba | 714 | #include "mbed_error.h" |
marcozecchini | 0:9fca2b23d0ba | 715 | namespace __gnu_cxx { |
marcozecchini | 0:9fca2b23d0ba | 716 | void __verbose_terminate_handler() { |
marcozecchini | 0:9fca2b23d0ba | 717 | error("Exception"); |
marcozecchini | 0:9fca2b23d0ba | 718 | } |
marcozecchini | 0:9fca2b23d0ba | 719 | } |
marcozecchini | 0:9fca2b23d0ba | 720 | extern "C" WEAK void __cxa_pure_virtual(void); |
marcozecchini | 0:9fca2b23d0ba | 721 | extern "C" WEAK void __cxa_pure_virtual(void) { |
marcozecchini | 0:9fca2b23d0ba | 722 | exit(1); |
marcozecchini | 0:9fca2b23d0ba | 723 | } |
marcozecchini | 0:9fca2b23d0ba | 724 | |
marcozecchini | 0:9fca2b23d0ba | 725 | #endif |
marcozecchini | 0:9fca2b23d0ba | 726 | |
marcozecchini | 0:9fca2b23d0ba | 727 | // Provide implementation of _sbrk (low-level dynamic memory allocation |
marcozecchini | 0:9fca2b23d0ba | 728 | // routine) for GCC_ARM which compares new heap pointer with MSP instead of |
marcozecchini | 0:9fca2b23d0ba | 729 | // SP. This make it compatible with RTX RTOS thread stacks. |
marcozecchini | 0:9fca2b23d0ba | 730 | #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) |
marcozecchini | 0:9fca2b23d0ba | 731 | |
marcozecchini | 0:9fca2b23d0ba | 732 | #if defined(TARGET_CORTEX_A) |
marcozecchini | 0:9fca2b23d0ba | 733 | extern "C" uint32_t __HeapLimit; |
marcozecchini | 0:9fca2b23d0ba | 734 | #endif |
marcozecchini | 0:9fca2b23d0ba | 735 | |
marcozecchini | 0:9fca2b23d0ba | 736 | // Turn off the errno macro and use actual global variable instead. |
marcozecchini | 0:9fca2b23d0ba | 737 | #undef errno |
marcozecchini | 0:9fca2b23d0ba | 738 | extern "C" int errno; |
marcozecchini | 0:9fca2b23d0ba | 739 | |
marcozecchini | 0:9fca2b23d0ba | 740 | // Dynamic memory allocation related syscall. |
marcozecchini | 0:9fca2b23d0ba | 741 | #if defined(TARGET_NUVOTON) |
marcozecchini | 0:9fca2b23d0ba | 742 | // Overwrite _sbrk() to support two region model (heap and stack are two distinct regions). |
marcozecchini | 0:9fca2b23d0ba | 743 | // __wrap__sbrk() is implemented in: |
marcozecchini | 0:9fca2b23d0ba | 744 | // TARGET_NUMAKER_PFM_NUC472 targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/nuc472_retarget.c |
marcozecchini | 0:9fca2b23d0ba | 745 | // TARGET_NUMAKER_PFM_M453 targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/m451_retarget.c |
marcozecchini | 0:9fca2b23d0ba | 746 | extern "C" void *__wrap__sbrk(int incr); |
marcozecchini | 0:9fca2b23d0ba | 747 | extern "C" caddr_t _sbrk(int incr) { |
marcozecchini | 0:9fca2b23d0ba | 748 | return (caddr_t) __wrap__sbrk(incr); |
marcozecchini | 0:9fca2b23d0ba | 749 | } |
marcozecchini | 0:9fca2b23d0ba | 750 | #else |
marcozecchini | 0:9fca2b23d0ba | 751 | // Linker defined symbol used by _sbrk to indicate where heap should start. |
marcozecchini | 0:9fca2b23d0ba | 752 | extern "C" uint32_t __end__; |
marcozecchini | 0:9fca2b23d0ba | 753 | extern "C" caddr_t _sbrk(int incr) { |
marcozecchini | 0:9fca2b23d0ba | 754 | static unsigned char* heap = (unsigned char*)&__end__; |
marcozecchini | 0:9fca2b23d0ba | 755 | unsigned char* prev_heap = heap; |
marcozecchini | 0:9fca2b23d0ba | 756 | unsigned char* new_heap = heap + incr; |
marcozecchini | 0:9fca2b23d0ba | 757 | |
marcozecchini | 0:9fca2b23d0ba | 758 | #if defined(TARGET_CORTEX_A) |
marcozecchini | 0:9fca2b23d0ba | 759 | if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */ |
marcozecchini | 0:9fca2b23d0ba | 760 | #else |
marcozecchini | 0:9fca2b23d0ba | 761 | if (new_heap >= (unsigned char*)__get_MSP()) { |
marcozecchini | 0:9fca2b23d0ba | 762 | #endif |
marcozecchini | 0:9fca2b23d0ba | 763 | errno = ENOMEM; |
marcozecchini | 0:9fca2b23d0ba | 764 | return (caddr_t)-1; |
marcozecchini | 0:9fca2b23d0ba | 765 | } |
marcozecchini | 0:9fca2b23d0ba | 766 | |
marcozecchini | 0:9fca2b23d0ba | 767 | // Additional heap checking if set |
marcozecchini | 0:9fca2b23d0ba | 768 | if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) { |
marcozecchini | 0:9fca2b23d0ba | 769 | errno = ENOMEM; |
marcozecchini | 0:9fca2b23d0ba | 770 | return (caddr_t)-1; |
marcozecchini | 0:9fca2b23d0ba | 771 | } |
marcozecchini | 0:9fca2b23d0ba | 772 | |
marcozecchini | 0:9fca2b23d0ba | 773 | heap = new_heap; |
marcozecchini | 0:9fca2b23d0ba | 774 | return (caddr_t) prev_heap; |
marcozecchini | 0:9fca2b23d0ba | 775 | } |
marcozecchini | 0:9fca2b23d0ba | 776 | #endif |
marcozecchini | 0:9fca2b23d0ba | 777 | #endif |
marcozecchini | 0:9fca2b23d0ba | 778 | |
marcozecchini | 0:9fca2b23d0ba | 779 | #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) |
marcozecchini | 0:9fca2b23d0ba | 780 | extern "C" void _exit(int return_code) { |
marcozecchini | 0:9fca2b23d0ba | 781 | #else |
marcozecchini | 0:9fca2b23d0ba | 782 | namespace std { |
marcozecchini | 0:9fca2b23d0ba | 783 | extern "C" void exit(int return_code) { |
marcozecchini | 0:9fca2b23d0ba | 784 | #endif |
marcozecchini | 0:9fca2b23d0ba | 785 | |
marcozecchini | 0:9fca2b23d0ba | 786 | #if DEVICE_STDIO_MESSAGES |
marcozecchini | 0:9fca2b23d0ba | 787 | #if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT |
marcozecchini | 0:9fca2b23d0ba | 788 | fflush(stdout); |
marcozecchini | 0:9fca2b23d0ba | 789 | fflush(stderr); |
marcozecchini | 0:9fca2b23d0ba | 790 | #endif |
marcozecchini | 0:9fca2b23d0ba | 791 | #endif |
marcozecchini | 0:9fca2b23d0ba | 792 | |
marcozecchini | 0:9fca2b23d0ba | 793 | #if DEVICE_SEMIHOST |
marcozecchini | 0:9fca2b23d0ba | 794 | if (mbed_interface_connected()) { |
marcozecchini | 0:9fca2b23d0ba | 795 | semihost_exit(); |
marcozecchini | 0:9fca2b23d0ba | 796 | } |
marcozecchini | 0:9fca2b23d0ba | 797 | #endif |
marcozecchini | 0:9fca2b23d0ba | 798 | if (return_code) { |
marcozecchini | 0:9fca2b23d0ba | 799 | mbed_die(); |
marcozecchini | 0:9fca2b23d0ba | 800 | } |
marcozecchini | 0:9fca2b23d0ba | 801 | |
marcozecchini | 0:9fca2b23d0ba | 802 | while (1); |
marcozecchini | 0:9fca2b23d0ba | 803 | } |
marcozecchini | 0:9fca2b23d0ba | 804 | |
marcozecchini | 0:9fca2b23d0ba | 805 | #if !defined(TOOLCHAIN_GCC_ARM) && !defined(TOOLCHAIN_GCC_CR) |
marcozecchini | 0:9fca2b23d0ba | 806 | } //namespace std |
marcozecchini | 0:9fca2b23d0ba | 807 | #endif |
marcozecchini | 0:9fca2b23d0ba | 808 | |
marcozecchini | 0:9fca2b23d0ba | 809 | #if defined(TOOLCHAIN_ARM) || defined(TOOLCHAIN_GCC) |
marcozecchini | 0:9fca2b23d0ba | 810 | |
marcozecchini | 0:9fca2b23d0ba | 811 | // This series of function disable the registration of global destructors |
marcozecchini | 0:9fca2b23d0ba | 812 | // in a dynamic table which will be called when the application exit. |
marcozecchini | 0:9fca2b23d0ba | 813 | // In mbed, program never exit properly, it dies. |
marcozecchini | 0:9fca2b23d0ba | 814 | // More informations about this topic for ARMCC here: |
marcozecchini | 0:9fca2b23d0ba | 815 | // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/6449.html |
marcozecchini | 0:9fca2b23d0ba | 816 | extern "C" { |
marcozecchini | 0:9fca2b23d0ba | 817 | int __aeabi_atexit(void *object, void (*dtor)(void* /*this*/), void *handle) { |
marcozecchini | 0:9fca2b23d0ba | 818 | return 1; |
marcozecchini | 0:9fca2b23d0ba | 819 | } |
marcozecchini | 0:9fca2b23d0ba | 820 | |
marcozecchini | 0:9fca2b23d0ba | 821 | int __cxa_atexit(void (*dtor)(void* /*this*/), void *object, void *handle) { |
marcozecchini | 0:9fca2b23d0ba | 822 | return 1; |
marcozecchini | 0:9fca2b23d0ba | 823 | } |
marcozecchini | 0:9fca2b23d0ba | 824 | |
marcozecchini | 0:9fca2b23d0ba | 825 | void __cxa_finalize(void *handle) { |
marcozecchini | 0:9fca2b23d0ba | 826 | } |
marcozecchini | 0:9fca2b23d0ba | 827 | |
marcozecchini | 0:9fca2b23d0ba | 828 | } // end of extern "C" |
marcozecchini | 0:9fca2b23d0ba | 829 | |
marcozecchini | 0:9fca2b23d0ba | 830 | #endif |
marcozecchini | 0:9fca2b23d0ba | 831 | |
marcozecchini | 0:9fca2b23d0ba | 832 | |
marcozecchini | 0:9fca2b23d0ba | 833 | #if defined(TOOLCHAIN_GCC) |
marcozecchini | 0:9fca2b23d0ba | 834 | |
marcozecchini | 0:9fca2b23d0ba | 835 | /* |
marcozecchini | 0:9fca2b23d0ba | 836 | * Depending on how newlib is configured, it is often not enough to define |
marcozecchini | 0:9fca2b23d0ba | 837 | * __aeabi_atexit, __cxa_atexit and __cxa_finalize in order to override the |
marcozecchini | 0:9fca2b23d0ba | 838 | * behavior regarding the registration of handlers with atexit. |
marcozecchini | 0:9fca2b23d0ba | 839 | * |
marcozecchini | 0:9fca2b23d0ba | 840 | * To overcome this limitation, exit and atexit are overriden here. |
marcozecchini | 0:9fca2b23d0ba | 841 | */ |
marcozecchini | 0:9fca2b23d0ba | 842 | extern "C"{ |
marcozecchini | 0:9fca2b23d0ba | 843 | |
marcozecchini | 0:9fca2b23d0ba | 844 | /** |
marcozecchini | 0:9fca2b23d0ba | 845 | * @brief Retarget of exit for GCC. |
marcozecchini | 0:9fca2b23d0ba | 846 | * @details Unlike the standard version, this function doesn't call any function |
marcozecchini | 0:9fca2b23d0ba | 847 | * registered with atexit before calling _exit. |
marcozecchini | 0:9fca2b23d0ba | 848 | */ |
marcozecchini | 0:9fca2b23d0ba | 849 | void __wrap_exit(int return_code) { |
marcozecchini | 0:9fca2b23d0ba | 850 | _exit(return_code); |
marcozecchini | 0:9fca2b23d0ba | 851 | } |
marcozecchini | 0:9fca2b23d0ba | 852 | |
marcozecchini | 0:9fca2b23d0ba | 853 | /** |
marcozecchini | 0:9fca2b23d0ba | 854 | * @brief Retarget atexit from GCC. |
marcozecchini | 0:9fca2b23d0ba | 855 | * @details This function will always fail and never register any handler to be |
marcozecchini | 0:9fca2b23d0ba | 856 | * called at exit. |
marcozecchini | 0:9fca2b23d0ba | 857 | */ |
marcozecchini | 0:9fca2b23d0ba | 858 | int __wrap_atexit(void (*func)()) { |
marcozecchini | 0:9fca2b23d0ba | 859 | return 1; |
marcozecchini | 0:9fca2b23d0ba | 860 | } |
marcozecchini | 0:9fca2b23d0ba | 861 | |
marcozecchini | 0:9fca2b23d0ba | 862 | } |
marcozecchini | 0:9fca2b23d0ba | 863 | |
marcozecchini | 0:9fca2b23d0ba | 864 | #endif |
marcozecchini | 0:9fca2b23d0ba | 865 | |
marcozecchini | 0:9fca2b23d0ba | 866 | |
marcozecchini | 0:9fca2b23d0ba | 867 | |
marcozecchini | 0:9fca2b23d0ba | 868 | namespace mbed { |
marcozecchini | 0:9fca2b23d0ba | 869 | |
marcozecchini | 0:9fca2b23d0ba | 870 | void mbed_set_unbuffered_stream(std::FILE *_file) { |
marcozecchini | 0:9fca2b23d0ba | 871 | #if defined (__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 872 | char buf[2]; |
marcozecchini | 0:9fca2b23d0ba | 873 | std::setvbuf(_file,buf,_IONBF,NULL); |
marcozecchini | 0:9fca2b23d0ba | 874 | #else |
marcozecchini | 0:9fca2b23d0ba | 875 | setbuf(_file, NULL); |
marcozecchini | 0:9fca2b23d0ba | 876 | #endif |
marcozecchini | 0:9fca2b23d0ba | 877 | } |
marcozecchini | 0:9fca2b23d0ba | 878 | |
marcozecchini | 0:9fca2b23d0ba | 879 | /* Applications are expected to use fdopen() |
marcozecchini | 0:9fca2b23d0ba | 880 | * not this function directly. This code had to live here because FILE and FileHandle |
marcozecchini | 0:9fca2b23d0ba | 881 | * processes are all linked together here. |
marcozecchini | 0:9fca2b23d0ba | 882 | */ |
marcozecchini | 0:9fca2b23d0ba | 883 | std::FILE *mbed_fdopen(FileHandle *fh, const char *mode) |
marcozecchini | 0:9fca2b23d0ba | 884 | { |
marcozecchini | 0:9fca2b23d0ba | 885 | // This is to avoid scanf(buf, ":%.4s", fh) and the bloat it brings. |
marcozecchini | 0:9fca2b23d0ba | 886 | char buf[1 + sizeof(fh)]; /* :(pointer) */ |
marcozecchini | 0:9fca2b23d0ba | 887 | MBED_STATIC_ASSERT(sizeof(buf) == 5, "Pointers should be 4 bytes."); |
marcozecchini | 0:9fca2b23d0ba | 888 | buf[0] = ':'; |
marcozecchini | 0:9fca2b23d0ba | 889 | memcpy(buf + 1, &fh, sizeof(fh)); |
marcozecchini | 0:9fca2b23d0ba | 890 | |
marcozecchini | 0:9fca2b23d0ba | 891 | std::FILE *stream = std::fopen(buf, mode); |
marcozecchini | 0:9fca2b23d0ba | 892 | /* newlib-nano doesn't appear to ever call _isatty itself, so |
marcozecchini | 0:9fca2b23d0ba | 893 | * happily fully buffers an interactive stream. Deal with that here. |
marcozecchini | 0:9fca2b23d0ba | 894 | */ |
marcozecchini | 0:9fca2b23d0ba | 895 | if (stream && fh->isatty()) { |
marcozecchini | 0:9fca2b23d0ba | 896 | mbed_set_unbuffered_stream(stream); |
marcozecchini | 0:9fca2b23d0ba | 897 | } |
marcozecchini | 0:9fca2b23d0ba | 898 | return stream; |
marcozecchini | 0:9fca2b23d0ba | 899 | } |
marcozecchini | 0:9fca2b23d0ba | 900 | |
marcozecchini | 0:9fca2b23d0ba | 901 | int mbed_getc(std::FILE *_file){ |
marcozecchini | 0:9fca2b23d0ba | 902 | #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ < 8000000) |
marcozecchini | 0:9fca2b23d0ba | 903 | /*This is only valid for unbuffered streams*/ |
marcozecchini | 0:9fca2b23d0ba | 904 | int res = std::fgetc(_file); |
marcozecchini | 0:9fca2b23d0ba | 905 | if (res>=0){ |
marcozecchini | 0:9fca2b23d0ba | 906 | _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ |
marcozecchini | 0:9fca2b23d0ba | 907 | _file->_Rend = _file->_Wend; |
marcozecchini | 0:9fca2b23d0ba | 908 | _file->_Next = _file->_Wend; |
marcozecchini | 0:9fca2b23d0ba | 909 | } |
marcozecchini | 0:9fca2b23d0ba | 910 | return res; |
marcozecchini | 0:9fca2b23d0ba | 911 | #else |
marcozecchini | 0:9fca2b23d0ba | 912 | return std::fgetc(_file); |
marcozecchini | 0:9fca2b23d0ba | 913 | #endif |
marcozecchini | 0:9fca2b23d0ba | 914 | } |
marcozecchini | 0:9fca2b23d0ba | 915 | |
marcozecchini | 0:9fca2b23d0ba | 916 | char* mbed_gets(char*s, int size, std::FILE *_file){ |
marcozecchini | 0:9fca2b23d0ba | 917 | #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ < 8000000) |
marcozecchini | 0:9fca2b23d0ba | 918 | /*This is only valid for unbuffered streams*/ |
marcozecchini | 0:9fca2b23d0ba | 919 | char *str = fgets(s,size,_file); |
marcozecchini | 0:9fca2b23d0ba | 920 | if (str!=NULL){ |
marcozecchini | 0:9fca2b23d0ba | 921 | _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ |
marcozecchini | 0:9fca2b23d0ba | 922 | _file->_Rend = _file->_Wend; |
marcozecchini | 0:9fca2b23d0ba | 923 | _file->_Next = _file->_Wend; |
marcozecchini | 0:9fca2b23d0ba | 924 | } |
marcozecchini | 0:9fca2b23d0ba | 925 | return str; |
marcozecchini | 0:9fca2b23d0ba | 926 | #else |
marcozecchini | 0:9fca2b23d0ba | 927 | return std::fgets(s,size,_file); |
marcozecchini | 0:9fca2b23d0ba | 928 | #endif |
marcozecchini | 0:9fca2b23d0ba | 929 | } |
marcozecchini | 0:9fca2b23d0ba | 930 | |
marcozecchini | 0:9fca2b23d0ba | 931 | } // namespace mbed |
marcozecchini | 0:9fca2b23d0ba | 932 | |
marcozecchini | 0:9fca2b23d0ba | 933 | #if defined (__ICCARM__) |
marcozecchini | 0:9fca2b23d0ba | 934 | // Stub out locks when an rtos is not present |
marcozecchini | 0:9fca2b23d0ba | 935 | extern "C" WEAK void __iar_system_Mtxinit(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 936 | extern "C" WEAK void __iar_system_Mtxdst(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 937 | extern "C" WEAK void __iar_system_Mtxlock(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 938 | extern "C" WEAK void __iar_system_Mtxunlock(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 939 | extern "C" WEAK void __iar_file_Mtxinit(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 940 | extern "C" WEAK void __iar_file_Mtxdst(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 941 | extern "C" WEAK void __iar_file_Mtxlock(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 942 | extern "C" WEAK void __iar_file_Mtxunlock(__iar_Rmtx *mutex) {} |
marcozecchini | 0:9fca2b23d0ba | 943 | #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000) |
marcozecchini | 0:9fca2b23d0ba | 944 | #pragma section="__iar_tls$$DATA" |
marcozecchini | 0:9fca2b23d0ba | 945 | extern "C" WEAK void *__aeabi_read_tp (void) { |
marcozecchini | 0:9fca2b23d0ba | 946 | // Thread Local storage is not supported, using main thread memory for errno |
marcozecchini | 0:9fca2b23d0ba | 947 | return __section_begin("__iar_tls$$DATA"); |
marcozecchini | 0:9fca2b23d0ba | 948 | } |
marcozecchini | 0:9fca2b23d0ba | 949 | #endif |
marcozecchini | 0:9fca2b23d0ba | 950 | #elif defined(__CC_ARM) |
marcozecchini | 0:9fca2b23d0ba | 951 | // Do nothing |
marcozecchini | 0:9fca2b23d0ba | 952 | #elif defined (__GNUC__) |
marcozecchini | 0:9fca2b23d0ba | 953 | struct _reent; |
marcozecchini | 0:9fca2b23d0ba | 954 | // Stub out locks when an rtos is not present |
marcozecchini | 0:9fca2b23d0ba | 955 | extern "C" WEAK void __rtos_malloc_lock( struct _reent *_r ) {} |
marcozecchini | 0:9fca2b23d0ba | 956 | extern "C" WEAK void __rtos_malloc_unlock( struct _reent *_r ) {} |
marcozecchini | 0:9fca2b23d0ba | 957 | extern "C" WEAK void __rtos_env_lock( struct _reent *_r ) {} |
marcozecchini | 0:9fca2b23d0ba | 958 | extern "C" WEAK void __rtos_env_unlock( struct _reent *_r ) {} |
marcozecchini | 0:9fca2b23d0ba | 959 | |
marcozecchini | 0:9fca2b23d0ba | 960 | extern "C" void __malloc_lock( struct _reent *_r ) |
marcozecchini | 0:9fca2b23d0ba | 961 | { |
marcozecchini | 0:9fca2b23d0ba | 962 | __rtos_malloc_lock(_r); |
marcozecchini | 0:9fca2b23d0ba | 963 | } |
marcozecchini | 0:9fca2b23d0ba | 964 | |
marcozecchini | 0:9fca2b23d0ba | 965 | extern "C" void __malloc_unlock( struct _reent *_r ) |
marcozecchini | 0:9fca2b23d0ba | 966 | { |
marcozecchini | 0:9fca2b23d0ba | 967 | __rtos_malloc_unlock(_r); |
marcozecchini | 0:9fca2b23d0ba | 968 | } |
marcozecchini | 0:9fca2b23d0ba | 969 | |
marcozecchini | 0:9fca2b23d0ba | 970 | extern "C" void __env_lock( struct _reent *_r ) |
marcozecchini | 0:9fca2b23d0ba | 971 | { |
marcozecchini | 0:9fca2b23d0ba | 972 | __rtos_env_lock(_r); |
marcozecchini | 0:9fca2b23d0ba | 973 | } |
marcozecchini | 0:9fca2b23d0ba | 974 | |
marcozecchini | 0:9fca2b23d0ba | 975 | extern "C" void __env_unlock( struct _reent *_r ) |
marcozecchini | 0:9fca2b23d0ba | 976 | { |
marcozecchini | 0:9fca2b23d0ba | 977 | __rtos_env_unlock(_r); |
marcozecchini | 0:9fca2b23d0ba | 978 | } |
marcozecchini | 0:9fca2b23d0ba | 979 | |
marcozecchini | 0:9fca2b23d0ba | 980 | #define CXA_GUARD_INIT_DONE (1 << 0) |
marcozecchini | 0:9fca2b23d0ba | 981 | #define CXA_GUARD_INIT_IN_PROGRESS (1 << 1) |
marcozecchini | 0:9fca2b23d0ba | 982 | #define CXA_GUARD_MASK (CXA_GUARD_INIT_DONE | CXA_GUARD_INIT_IN_PROGRESS) |
marcozecchini | 0:9fca2b23d0ba | 983 | |
marcozecchini | 0:9fca2b23d0ba | 984 | extern "C" int __cxa_guard_acquire(int *guard_object_p) |
marcozecchini | 0:9fca2b23d0ba | 985 | { |
marcozecchini | 0:9fca2b23d0ba | 986 | uint8_t *guard_object = (uint8_t *)guard_object_p; |
marcozecchini | 0:9fca2b23d0ba | 987 | if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { |
marcozecchini | 0:9fca2b23d0ba | 988 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 989 | } |
marcozecchini | 0:9fca2b23d0ba | 990 | singleton_lock(); |
marcozecchini | 0:9fca2b23d0ba | 991 | if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) { |
marcozecchini | 0:9fca2b23d0ba | 992 | singleton_unlock(); |
marcozecchini | 0:9fca2b23d0ba | 993 | return 0; |
marcozecchini | 0:9fca2b23d0ba | 994 | } |
marcozecchini | 0:9fca2b23d0ba | 995 | MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK)); |
marcozecchini | 0:9fca2b23d0ba | 996 | *guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS; |
marcozecchini | 0:9fca2b23d0ba | 997 | return 1; |
marcozecchini | 0:9fca2b23d0ba | 998 | } |
marcozecchini | 0:9fca2b23d0ba | 999 | |
marcozecchini | 0:9fca2b23d0ba | 1000 | extern "C" void __cxa_guard_release(int *guard_object_p) |
marcozecchini | 0:9fca2b23d0ba | 1001 | { |
marcozecchini | 0:9fca2b23d0ba | 1002 | uint8_t *guard_object = (uint8_t *)guard_object_p; |
marcozecchini | 0:9fca2b23d0ba | 1003 | MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); |
marcozecchini | 0:9fca2b23d0ba | 1004 | *guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE; |
marcozecchini | 0:9fca2b23d0ba | 1005 | singleton_unlock(); |
marcozecchini | 0:9fca2b23d0ba | 1006 | } |
marcozecchini | 0:9fca2b23d0ba | 1007 | |
marcozecchini | 0:9fca2b23d0ba | 1008 | extern "C" void __cxa_guard_abort(int *guard_object_p) |
marcozecchini | 0:9fca2b23d0ba | 1009 | { |
marcozecchini | 0:9fca2b23d0ba | 1010 | uint8_t *guard_object = (uint8_t *)guard_object_p; |
marcozecchini | 0:9fca2b23d0ba | 1011 | MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK)); |
marcozecchini | 0:9fca2b23d0ba | 1012 | *guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS; |
marcozecchini | 0:9fca2b23d0ba | 1013 | singleton_unlock(); |
marcozecchini | 0:9fca2b23d0ba | 1014 | } |
marcozecchini | 0:9fca2b23d0ba | 1015 | |
marcozecchini | 0:9fca2b23d0ba | 1016 | #endif |
marcozecchini | 0:9fca2b23d0ba | 1017 | |
marcozecchini | 0:9fca2b23d0ba | 1018 | void *operator new(std::size_t count) |
marcozecchini | 0:9fca2b23d0ba | 1019 | { |
marcozecchini | 0:9fca2b23d0ba | 1020 | void *buffer = malloc(count); |
marcozecchini | 0:9fca2b23d0ba | 1021 | if (NULL == buffer) { |
marcozecchini | 0:9fca2b23d0ba | 1022 | error("Operator new out of memory\r\n"); |
marcozecchini | 0:9fca2b23d0ba | 1023 | } |
marcozecchini | 0:9fca2b23d0ba | 1024 | return buffer; |
marcozecchini | 0:9fca2b23d0ba | 1025 | } |
marcozecchini | 0:9fca2b23d0ba | 1026 | |
marcozecchini | 0:9fca2b23d0ba | 1027 | void *operator new[](std::size_t count) |
marcozecchini | 0:9fca2b23d0ba | 1028 | { |
marcozecchini | 0:9fca2b23d0ba | 1029 | void *buffer = malloc(count); |
marcozecchini | 0:9fca2b23d0ba | 1030 | if (NULL == buffer) { |
marcozecchini | 0:9fca2b23d0ba | 1031 | error("Operator new[] out of memory\r\n"); |
marcozecchini | 0:9fca2b23d0ba | 1032 | } |
marcozecchini | 0:9fca2b23d0ba | 1033 | return buffer; |
marcozecchini | 0:9fca2b23d0ba | 1034 | } |
marcozecchini | 0:9fca2b23d0ba | 1035 | |
marcozecchini | 0:9fca2b23d0ba | 1036 | void *operator new(std::size_t count, const std::nothrow_t& tag) |
marcozecchini | 0:9fca2b23d0ba | 1037 | { |
marcozecchini | 0:9fca2b23d0ba | 1038 | return malloc(count); |
marcozecchini | 0:9fca2b23d0ba | 1039 | } |
marcozecchini | 0:9fca2b23d0ba | 1040 | |
marcozecchini | 0:9fca2b23d0ba | 1041 | void *operator new[](std::size_t count, const std::nothrow_t& tag) |
marcozecchini | 0:9fca2b23d0ba | 1042 | { |
marcozecchini | 0:9fca2b23d0ba | 1043 | return malloc(count); |
marcozecchini | 0:9fca2b23d0ba | 1044 | } |
marcozecchini | 0:9fca2b23d0ba | 1045 | |
marcozecchini | 0:9fca2b23d0ba | 1046 | void operator delete(void *ptr) |
marcozecchini | 0:9fca2b23d0ba | 1047 | { |
marcozecchini | 0:9fca2b23d0ba | 1048 | if (ptr != NULL) { |
marcozecchini | 0:9fca2b23d0ba | 1049 | free(ptr); |
marcozecchini | 0:9fca2b23d0ba | 1050 | } |
marcozecchini | 0:9fca2b23d0ba | 1051 | } |
marcozecchini | 0:9fca2b23d0ba | 1052 | void operator delete[](void *ptr) |
marcozecchini | 0:9fca2b23d0ba | 1053 | { |
marcozecchini | 0:9fca2b23d0ba | 1054 | if (ptr != NULL) { |
marcozecchini | 0:9fca2b23d0ba | 1055 | free(ptr); |
marcozecchini | 0:9fca2b23d0ba | 1056 | } |
marcozecchini | 0:9fca2b23d0ba | 1057 | } |
marcozecchini | 0:9fca2b23d0ba | 1058 | |
marcozecchini | 0:9fca2b23d0ba | 1059 | /* @brief standard c library clock() function. |
marcozecchini | 0:9fca2b23d0ba | 1060 | * |
marcozecchini | 0:9fca2b23d0ba | 1061 | * This function returns the number of clock ticks elapsed since the start of the program. |
marcozecchini | 0:9fca2b23d0ba | 1062 | * |
marcozecchini | 0:9fca2b23d0ba | 1063 | * @note Synchronization level: Thread safe |
marcozecchini | 0:9fca2b23d0ba | 1064 | * |
marcozecchini | 0:9fca2b23d0ba | 1065 | * @return |
marcozecchini | 0:9fca2b23d0ba | 1066 | * the number of clock ticks elapsed since the start of the program. |
marcozecchini | 0:9fca2b23d0ba | 1067 | * |
marcozecchini | 0:9fca2b23d0ba | 1068 | * */ |
marcozecchini | 0:9fca2b23d0ba | 1069 | extern "C" clock_t clock() |
marcozecchini | 0:9fca2b23d0ba | 1070 | { |
marcozecchini | 0:9fca2b23d0ba | 1071 | _mutex->lock(); |
marcozecchini | 0:9fca2b23d0ba | 1072 | clock_t t = ticker_read(get_us_ticker_data()); |
marcozecchini | 0:9fca2b23d0ba | 1073 | t /= 1000000 / CLOCKS_PER_SEC; // convert to processor time |
marcozecchini | 0:9fca2b23d0ba | 1074 | _mutex->unlock(); |
marcozecchini | 0:9fca2b23d0ba | 1075 | return t; |
marcozecchini | 0:9fca2b23d0ba | 1076 | } |
marcozecchini | 0:9fca2b23d0ba | 1077 | |
marcozecchini | 0:9fca2b23d0ba | 1078 | // temporary - Default to 1MHz at 32 bits if target does not have us_ticker_get_info |
marcozecchini | 0:9fca2b23d0ba | 1079 | MBED_WEAK const ticker_info_t* us_ticker_get_info() |
marcozecchini | 0:9fca2b23d0ba | 1080 | { |
marcozecchini | 0:9fca2b23d0ba | 1081 | static const ticker_info_t info = { |
marcozecchini | 0:9fca2b23d0ba | 1082 | 1000000, |
marcozecchini | 0:9fca2b23d0ba | 1083 | 32 |
marcozecchini | 0:9fca2b23d0ba | 1084 | }; |
marcozecchini | 0:9fca2b23d0ba | 1085 | return &info; |
marcozecchini | 0:9fca2b23d0ba | 1086 | } |
marcozecchini | 0:9fca2b23d0ba | 1087 | |
marcozecchini | 0:9fca2b23d0ba | 1088 | // temporary - Default to 1MHz at 32 bits if target does not have lp_ticker_get_info |
marcozecchini | 0:9fca2b23d0ba | 1089 | MBED_WEAK const ticker_info_t* lp_ticker_get_info() |
marcozecchini | 0:9fca2b23d0ba | 1090 | { |
marcozecchini | 0:9fca2b23d0ba | 1091 | static const ticker_info_t info = { |
marcozecchini | 0:9fca2b23d0ba | 1092 | 1000000, |
marcozecchini | 0:9fca2b23d0ba | 1093 | 32 |
marcozecchini | 0:9fca2b23d0ba | 1094 | }; |
marcozecchini | 0:9fca2b23d0ba | 1095 | return &info; |
marcozecchini | 0:9fca2b23d0ba | 1096 | } |