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