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 Nothing Special

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 to Optimise for size (-Os)
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?

UserRevisionLine numberNew 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 }