mbed library sources. Supersedes mbed-src. Fixes analogIn and analogOut problems for TARGET_STM32F3. Tested on NUCLEO-F303K8, using 3 analogout and 7 analogin channels simultaneously. Added ability for STM32F334R8 and STM32F303K8 to use all three channels of DAC simultaneously. https://developer.mbed.org/users/StevieWray/code/mbed-dev/ Added ability for TARGET_STM32F3 to use more than one ADC simultaneously. https://developer.mbed.org/questions/67997/NUCLEO-F303K8ADC/

Fork of mbed-dev by mbed official

Committer:
neurofun
Date:
Tue Feb 23 21:59:35 2016 +0000
Revision:
70:b3a5af880266
Parent:
63:5964504d61de
Edited DAC routines to allow for the simultaneous use of three channels from two DACs as seen on the STM32F334R8 and STM32F303K8. Edited ADC routines to allow for the simultaneous use of more than one ADC.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /* mbed Microcontroller Library
bogdanm 0:9b334a45a8ff 2 * Copyright (c) 2006-2015 ARM Limited
bogdanm 0:9b334a45a8ff 3 *
bogdanm 0:9b334a45a8ff 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 0:9b334a45a8ff 5 * you may not use this file except in compliance with the License.
bogdanm 0:9b334a45a8ff 6 * You may obtain a copy of the License at
bogdanm 0:9b334a45a8ff 7 *
bogdanm 0:9b334a45a8ff 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 0:9b334a45a8ff 9 *
bogdanm 0:9b334a45a8ff 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 0:9b334a45a8ff 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 0:9b334a45a8ff 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 0:9b334a45a8ff 13 * See the License for the specific language governing permissions and
bogdanm 0:9b334a45a8ff 14 * limitations under the License.
bogdanm 0:9b334a45a8ff 15 */
bogdanm 0:9b334a45a8ff 16 #include "platform.h"
bogdanm 0:9b334a45a8ff 17 #include "FileHandle.h"
bogdanm 0:9b334a45a8ff 18 #include "FileSystemLike.h"
bogdanm 0:9b334a45a8ff 19 #include "FilePath.h"
bogdanm 0:9b334a45a8ff 20 #include "serial_api.h"
bogdanm 0:9b334a45a8ff 21 #include "toolchain.h"
bogdanm 0:9b334a45a8ff 22 #include "semihost_api.h"
bogdanm 0:9b334a45a8ff 23 #include "mbed_interface.h"
bogdanm 0:9b334a45a8ff 24 #if DEVICE_STDIO_MESSAGES
bogdanm 0:9b334a45a8ff 25 #include <stdio.h>
bogdanm 0:9b334a45a8ff 26 #endif
bogdanm 0:9b334a45a8ff 27 #include <errno.h>
bogdanm 0:9b334a45a8ff 28
bogdanm 0:9b334a45a8ff 29 #if defined(__ARMCC_VERSION)
bogdanm 0:9b334a45a8ff 30 # include <rt_sys.h>
bogdanm 0:9b334a45a8ff 31 # define PREFIX(x) _sys##x
bogdanm 0:9b334a45a8ff 32 # define OPEN_MAX _SYS_OPEN
bogdanm 0:9b334a45a8ff 33 # ifdef __MICROLIB
bogdanm 0:9b334a45a8ff 34 # pragma import(__use_full_stdio)
bogdanm 0:9b334a45a8ff 35 # endif
bogdanm 0:9b334a45a8ff 36
bogdanm 0:9b334a45a8ff 37 #elif defined(__ICCARM__)
bogdanm 0:9b334a45a8ff 38 # include <yfuns.h>
bogdanm 0:9b334a45a8ff 39 # define PREFIX(x) _##x
bogdanm 0:9b334a45a8ff 40 # define OPEN_MAX 16
bogdanm 0:9b334a45a8ff 41
bogdanm 0:9b334a45a8ff 42 # define STDIN_FILENO 0
bogdanm 0:9b334a45a8ff 43 # define STDOUT_FILENO 1
bogdanm 0:9b334a45a8ff 44 # define STDERR_FILENO 2
bogdanm 0:9b334a45a8ff 45
bogdanm 0:9b334a45a8ff 46 #else
bogdanm 0:9b334a45a8ff 47 # include <sys/stat.h>
bogdanm 0:9b334a45a8ff 48 # include <sys/unistd.h>
bogdanm 0:9b334a45a8ff 49 # include <sys/syslimits.h>
bogdanm 0:9b334a45a8ff 50 # define PREFIX(x) x
bogdanm 0:9b334a45a8ff 51 #endif
bogdanm 0:9b334a45a8ff 52
bogdanm 0:9b334a45a8ff 53 using namespace mbed;
bogdanm 0:9b334a45a8ff 54
bogdanm 0:9b334a45a8ff 55 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
bogdanm 0:9b334a45a8ff 56 // Before version 5.03, we were using a patched version of microlib with proper names
bogdanm 0:9b334a45a8ff 57 extern const char __stdin_name[] = ":tt";
bogdanm 0:9b334a45a8ff 58 extern const char __stdout_name[] = ":tt";
bogdanm 0:9b334a45a8ff 59 extern const char __stderr_name[] = ":tt";
bogdanm 0:9b334a45a8ff 60
bogdanm 0:9b334a45a8ff 61 #else
bogdanm 0:9b334a45a8ff 62 extern const char __stdin_name[] = "/stdin";
bogdanm 0:9b334a45a8ff 63 extern const char __stdout_name[] = "/stdout";
bogdanm 0:9b334a45a8ff 64 extern const char __stderr_name[] = "/stderr";
bogdanm 0:9b334a45a8ff 65 #endif
bogdanm 0:9b334a45a8ff 66
bogdanm 0:9b334a45a8ff 67 /* newlib has the filehandle field in the FILE struct as a short, so
bogdanm 0:9b334a45a8ff 68 * we can't just return a Filehandle* from _open and instead have to
bogdanm 0:9b334a45a8ff 69 * put it in a filehandles array and return the index into that array
bogdanm 0:9b334a45a8ff 70 * (or rather index+3, as filehandles 0-2 are stdin/out/err).
bogdanm 0:9b334a45a8ff 71 */
bogdanm 0:9b334a45a8ff 72 static FileHandle *filehandles[OPEN_MAX];
bogdanm 0:9b334a45a8ff 73
bogdanm 0:9b334a45a8ff 74 FileHandle::~FileHandle() {
bogdanm 0:9b334a45a8ff 75 /* Remove all open filehandles for this */
bogdanm 0:9b334a45a8ff 76 for (unsigned int fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
bogdanm 0:9b334a45a8ff 77 if (filehandles[fh_i] == this) {
bogdanm 0:9b334a45a8ff 78 filehandles[fh_i] = NULL;
bogdanm 0:9b334a45a8ff 79 }
bogdanm 0:9b334a45a8ff 80 }
bogdanm 0:9b334a45a8ff 81 }
bogdanm 0:9b334a45a8ff 82
bogdanm 0:9b334a45a8ff 83 #if DEVICE_SERIAL
bogdanm 0:9b334a45a8ff 84 extern int stdio_uart_inited;
bogdanm 0:9b334a45a8ff 85 extern serial_t stdio_uart;
bogdanm 0:9b334a45a8ff 86 #endif
bogdanm 0:9b334a45a8ff 87
bogdanm 0:9b334a45a8ff 88 static void init_serial() {
bogdanm 0:9b334a45a8ff 89 #if DEVICE_SERIAL
bogdanm 0:9b334a45a8ff 90 if (stdio_uart_inited) return;
bogdanm 0:9b334a45a8ff 91 serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
bogdanm 0:9b334a45a8ff 92 #endif
bogdanm 0:9b334a45a8ff 93 }
bogdanm 0:9b334a45a8ff 94
bogdanm 0:9b334a45a8ff 95 static inline int openmode_to_posix(int openmode) {
bogdanm 0:9b334a45a8ff 96 int posix = openmode;
bogdanm 0:9b334a45a8ff 97 #ifdef __ARMCC_VERSION
bogdanm 0:9b334a45a8ff 98 if (openmode & OPEN_PLUS) {
bogdanm 0:9b334a45a8ff 99 posix = O_RDWR;
bogdanm 0:9b334a45a8ff 100 } else if(openmode & OPEN_W) {
bogdanm 0:9b334a45a8ff 101 posix = O_WRONLY;
bogdanm 0:9b334a45a8ff 102 } else if(openmode & OPEN_A) {
bogdanm 0:9b334a45a8ff 103 posix = O_WRONLY|O_APPEND;
bogdanm 0:9b334a45a8ff 104 } else {
bogdanm 0:9b334a45a8ff 105 posix = O_RDONLY;
bogdanm 0:9b334a45a8ff 106 }
bogdanm 0:9b334a45a8ff 107 /* a, w, a+, w+ all create if file does not already exist */
bogdanm 0:9b334a45a8ff 108 if (openmode & (OPEN_A|OPEN_W)) {
bogdanm 0:9b334a45a8ff 109 posix |= O_CREAT;
bogdanm 0:9b334a45a8ff 110 }
bogdanm 0:9b334a45a8ff 111 /* w and w+ truncate */
bogdanm 0:9b334a45a8ff 112 if (openmode & OPEN_W) {
bogdanm 0:9b334a45a8ff 113 posix |= O_TRUNC;
bogdanm 0:9b334a45a8ff 114 }
bogdanm 0:9b334a45a8ff 115 #elif defined(__ICCARM__)
bogdanm 0:9b334a45a8ff 116 switch (openmode & _LLIO_RDWRMASK) {
bogdanm 0:9b334a45a8ff 117 case _LLIO_RDONLY: posix = O_RDONLY; break;
bogdanm 0:9b334a45a8ff 118 case _LLIO_WRONLY: posix = O_WRONLY; break;
bogdanm 0:9b334a45a8ff 119 case _LLIO_RDWR : posix = O_RDWR ; break;
bogdanm 0:9b334a45a8ff 120 }
bogdanm 0:9b334a45a8ff 121 if (openmode & _LLIO_CREAT ) posix |= O_CREAT;
bogdanm 0:9b334a45a8ff 122 if (openmode & _LLIO_APPEND) posix |= O_APPEND;
bogdanm 0:9b334a45a8ff 123 if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC;
bogdanm 0:9b334a45a8ff 124 #endif
bogdanm 0:9b334a45a8ff 125 return posix;
bogdanm 0:9b334a45a8ff 126 }
bogdanm 0:9b334a45a8ff 127
bogdanm 0:9b334a45a8ff 128 extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
bogdanm 0:9b334a45a8ff 129 #if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
bogdanm 0:9b334a45a8ff 130 // Before version 5.03, we were using a patched version of microlib with proper names
bogdanm 0:9b334a45a8ff 131 // This is the workaround that the microlib author suggested us
bogdanm 0:9b334a45a8ff 132 static int n = 0;
bogdanm 0:9b334a45a8ff 133 if (!std::strcmp(name, ":tt")) return n++;
bogdanm 0:9b334a45a8ff 134
bogdanm 0:9b334a45a8ff 135 #else
bogdanm 0:9b334a45a8ff 136 /* Use the posix convention that stdin,out,err are filehandles 0,1,2.
bogdanm 0:9b334a45a8ff 137 */
bogdanm 0:9b334a45a8ff 138 if (std::strcmp(name, __stdin_name) == 0) {
bogdanm 0:9b334a45a8ff 139 init_serial();
bogdanm 0:9b334a45a8ff 140 return 0;
bogdanm 0:9b334a45a8ff 141 } else if (std::strcmp(name, __stdout_name) == 0) {
bogdanm 0:9b334a45a8ff 142 init_serial();
bogdanm 0:9b334a45a8ff 143 return 1;
bogdanm 0:9b334a45a8ff 144 } else if (std::strcmp(name, __stderr_name) == 0) {
bogdanm 0:9b334a45a8ff 145 init_serial();
bogdanm 0:9b334a45a8ff 146 return 2;
bogdanm 0:9b334a45a8ff 147 }
bogdanm 0:9b334a45a8ff 148 #endif
bogdanm 0:9b334a45a8ff 149
bogdanm 0:9b334a45a8ff 150 // find the first empty slot in filehandles
bogdanm 0:9b334a45a8ff 151 unsigned int fh_i;
bogdanm 0:9b334a45a8ff 152 for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) {
bogdanm 0:9b334a45a8ff 153 if (filehandles[fh_i] == NULL) break;
bogdanm 0:9b334a45a8ff 154 }
bogdanm 0:9b334a45a8ff 155 if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) {
bogdanm 0:9b334a45a8ff 156 return -1;
bogdanm 0:9b334a45a8ff 157 }
bogdanm 0:9b334a45a8ff 158
bogdanm 0:9b334a45a8ff 159 FileHandle *res;
bogdanm 0:9b334a45a8ff 160
bogdanm 0:9b334a45a8ff 161 /* FILENAME: ":0x12345678" describes a FileLike* */
bogdanm 0:9b334a45a8ff 162 if (name[0] == ':') {
bogdanm 0:9b334a45a8ff 163 void *p;
bogdanm 0:9b334a45a8ff 164 sscanf(name, ":%p", &p);
bogdanm 0:9b334a45a8ff 165 res = (FileHandle*)p;
bogdanm 0:9b334a45a8ff 166
bogdanm 0:9b334a45a8ff 167 /* FILENAME: "/file_system/file_name" */
bogdanm 0:9b334a45a8ff 168 } else {
bogdanm 0:9b334a45a8ff 169 FilePath path(name);
bogdanm 0:9b334a45a8ff 170
bogdanm 0:9b334a45a8ff 171 if (!path.exists())
bogdanm 0:9b334a45a8ff 172 return -1;
bogdanm 0:9b334a45a8ff 173 else if (path.isFile()) {
bogdanm 0:9b334a45a8ff 174 res = path.file();
bogdanm 0:9b334a45a8ff 175 } else {
bogdanm 0:9b334a45a8ff 176 FileSystemLike *fs = path.fileSystem();
bogdanm 0:9b334a45a8ff 177 if (fs == NULL) return -1;
bogdanm 0:9b334a45a8ff 178 int posix_mode = openmode_to_posix(openmode);
bogdanm 0:9b334a45a8ff 179 res = fs->open(path.fileName(), posix_mode); /* NULL if fails */
bogdanm 0:9b334a45a8ff 180 }
bogdanm 0:9b334a45a8ff 181 }
bogdanm 0:9b334a45a8ff 182
bogdanm 0:9b334a45a8ff 183 if (res == NULL) return -1;
bogdanm 0:9b334a45a8ff 184 filehandles[fh_i] = res;
bogdanm 0:9b334a45a8ff 185
bogdanm 0:9b334a45a8ff 186 return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err
bogdanm 0:9b334a45a8ff 187 }
bogdanm 0:9b334a45a8ff 188
bogdanm 0:9b334a45a8ff 189 extern "C" int PREFIX(_close)(FILEHANDLE fh) {
bogdanm 0:9b334a45a8ff 190 if (fh < 3) return 0;
bogdanm 0:9b334a45a8ff 191
bogdanm 0:9b334a45a8ff 192 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 193 filehandles[fh-3] = NULL;
bogdanm 0:9b334a45a8ff 194 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 195
bogdanm 0:9b334a45a8ff 196 return fhc->close();
bogdanm 0:9b334a45a8ff 197 }
bogdanm 0:9b334a45a8ff 198
bogdanm 0:9b334a45a8ff 199 #if defined(__ICCARM__)
bogdanm 0:9b334a45a8ff 200 extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) {
bogdanm 0:9b334a45a8ff 201 #else
bogdanm 0:9b334a45a8ff 202 extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) {
bogdanm 0:9b334a45a8ff 203 #endif
bogdanm 0:9b334a45a8ff 204 int n; // n is the number of bytes written
bogdanm 0:9b334a45a8ff 205 if (fh < 3) {
bogdanm 0:9b334a45a8ff 206 #if DEVICE_SERIAL
bogdanm 0:9b334a45a8ff 207 if (!stdio_uart_inited) init_serial();
bogdanm 0:9b334a45a8ff 208 for (unsigned int i = 0; i < length; i++) {
bogdanm 0:9b334a45a8ff 209 serial_putc(&stdio_uart, buffer[i]);
bogdanm 0:9b334a45a8ff 210 }
bogdanm 0:9b334a45a8ff 211 #endif
bogdanm 0:9b334a45a8ff 212 n = length;
bogdanm 0:9b334a45a8ff 213 } else {
bogdanm 0:9b334a45a8ff 214 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 215 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 216
bogdanm 0:9b334a45a8ff 217 n = fhc->write(buffer, length);
bogdanm 0:9b334a45a8ff 218 }
bogdanm 0:9b334a45a8ff 219 #ifdef __ARMCC_VERSION
bogdanm 0:9b334a45a8ff 220 return length-n;
bogdanm 0:9b334a45a8ff 221 #else
bogdanm 0:9b334a45a8ff 222 return n;
bogdanm 0:9b334a45a8ff 223 #endif
bogdanm 0:9b334a45a8ff 224 }
bogdanm 0:9b334a45a8ff 225
bogdanm 0:9b334a45a8ff 226 #if defined(__ICCARM__)
bogdanm 0:9b334a45a8ff 227 extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) {
bogdanm 0:9b334a45a8ff 228 #else
bogdanm 0:9b334a45a8ff 229 extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) {
bogdanm 0:9b334a45a8ff 230 #endif
bogdanm 0:9b334a45a8ff 231 int n; // n is the number of bytes read
bogdanm 0:9b334a45a8ff 232 if (fh < 3) {
bogdanm 0:9b334a45a8ff 233 // only read a character at a time from stdin
bogdanm 0:9b334a45a8ff 234 #if DEVICE_SERIAL
bogdanm 0:9b334a45a8ff 235 if (!stdio_uart_inited) init_serial();
bogdanm 0:9b334a45a8ff 236 *buffer = serial_getc(&stdio_uart);
bogdanm 0:9b334a45a8ff 237 #endif
bogdanm 0:9b334a45a8ff 238 n = 1;
bogdanm 0:9b334a45a8ff 239 } else {
bogdanm 0:9b334a45a8ff 240 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 241 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 242
bogdanm 0:9b334a45a8ff 243 n = fhc->read(buffer, length);
bogdanm 0:9b334a45a8ff 244 }
bogdanm 0:9b334a45a8ff 245 #ifdef __ARMCC_VERSION
bogdanm 0:9b334a45a8ff 246 return length-n;
bogdanm 0:9b334a45a8ff 247 #else
bogdanm 0:9b334a45a8ff 248 return n;
bogdanm 0:9b334a45a8ff 249 #endif
bogdanm 0:9b334a45a8ff 250 }
bogdanm 0:9b334a45a8ff 251
bogdanm 0:9b334a45a8ff 252 #ifdef __ARMCC_VERSION
bogdanm 0:9b334a45a8ff 253 extern "C" int PREFIX(_istty)(FILEHANDLE fh)
bogdanm 0:9b334a45a8ff 254 #else
bogdanm 0:9b334a45a8ff 255 extern "C" int _isatty(FILEHANDLE fh)
bogdanm 0:9b334a45a8ff 256 #endif
bogdanm 0:9b334a45a8ff 257 {
bogdanm 0:9b334a45a8ff 258 /* stdin, stdout and stderr should be tty */
bogdanm 0:9b334a45a8ff 259 if (fh < 3) return 1;
bogdanm 0:9b334a45a8ff 260
bogdanm 0:9b334a45a8ff 261 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 262 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 263
bogdanm 0:9b334a45a8ff 264 return fhc->isatty();
bogdanm 0:9b334a45a8ff 265 }
bogdanm 0:9b334a45a8ff 266
bogdanm 0:9b334a45a8ff 267 extern "C"
bogdanm 0:9b334a45a8ff 268 #if defined(__ARMCC_VERSION)
bogdanm 0:9b334a45a8ff 269 int _sys_seek(FILEHANDLE fh, long position)
bogdanm 0:9b334a45a8ff 270 #elif defined(__ICCARM__)
bogdanm 0:9b334a45a8ff 271 long __lseek(int fh, long offset, int whence)
bogdanm 0:9b334a45a8ff 272 #else
bogdanm 0:9b334a45a8ff 273 int _lseek(FILEHANDLE fh, int offset, int whence)
bogdanm 0:9b334a45a8ff 274 #endif
bogdanm 0:9b334a45a8ff 275 {
bogdanm 0:9b334a45a8ff 276 if (fh < 3) return 0;
bogdanm 0:9b334a45a8ff 277
bogdanm 0:9b334a45a8ff 278 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 279 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 280
bogdanm 0:9b334a45a8ff 281 #if defined(__ARMCC_VERSION)
bogdanm 0:9b334a45a8ff 282 return fhc->lseek(position, SEEK_SET);
bogdanm 0:9b334a45a8ff 283 #else
bogdanm 0:9b334a45a8ff 284 return fhc->lseek(offset, whence);
bogdanm 0:9b334a45a8ff 285 #endif
bogdanm 0:9b334a45a8ff 286 }
bogdanm 0:9b334a45a8ff 287
bogdanm 0:9b334a45a8ff 288 #ifdef __ARMCC_VERSION
bogdanm 0:9b334a45a8ff 289 extern "C" int PREFIX(_ensure)(FILEHANDLE fh) {
bogdanm 0:9b334a45a8ff 290 if (fh < 3) return 0;
bogdanm 0:9b334a45a8ff 291
bogdanm 0:9b334a45a8ff 292 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 293 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 294
bogdanm 0:9b334a45a8ff 295 return fhc->fsync();
bogdanm 0:9b334a45a8ff 296 }
bogdanm 0:9b334a45a8ff 297
bogdanm 0:9b334a45a8ff 298 extern "C" long PREFIX(_flen)(FILEHANDLE fh) {
bogdanm 0:9b334a45a8ff 299 if (fh < 3) return 0;
bogdanm 0:9b334a45a8ff 300
bogdanm 0:9b334a45a8ff 301 FileHandle* fhc = filehandles[fh-3];
bogdanm 0:9b334a45a8ff 302 if (fhc == NULL) return -1;
bogdanm 0:9b334a45a8ff 303
bogdanm 0:9b334a45a8ff 304 return fhc->flen();
bogdanm 0:9b334a45a8ff 305 }
bogdanm 0:9b334a45a8ff 306 #endif
bogdanm 0:9b334a45a8ff 307
bogdanm 0:9b334a45a8ff 308
bogdanm 0:9b334a45a8ff 309 #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
bogdanm 0:9b334a45a8ff 310 extern "C" int _fstat(int fd, struct stat *st) {
bogdanm 0:9b334a45a8ff 311 if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) {
bogdanm 0:9b334a45a8ff 312 st->st_mode = S_IFCHR;
bogdanm 0:9b334a45a8ff 313 return 0;
bogdanm 0:9b334a45a8ff 314 }
bogdanm 0:9b334a45a8ff 315
bogdanm 0:9b334a45a8ff 316 errno = EBADF;
bogdanm 0:9b334a45a8ff 317 return -1;
bogdanm 0:9b334a45a8ff 318 }
bogdanm 0:9b334a45a8ff 319 #endif
bogdanm 0:9b334a45a8ff 320
bogdanm 0:9b334a45a8ff 321 namespace std {
bogdanm 0:9b334a45a8ff 322 extern "C" int remove(const char *path) {
bogdanm 0:9b334a45a8ff 323 FilePath fp(path);
bogdanm 0:9b334a45a8ff 324 FileSystemLike *fs = fp.fileSystem();
bogdanm 0:9b334a45a8ff 325 if (fs == NULL) return -1;
bogdanm 0:9b334a45a8ff 326
bogdanm 0:9b334a45a8ff 327 return fs->remove(fp.fileName());
bogdanm 0:9b334a45a8ff 328 }
bogdanm 0:9b334a45a8ff 329
bogdanm 0:9b334a45a8ff 330 extern "C" int rename(const char *oldname, const char *newname) {
bogdanm 0:9b334a45a8ff 331 FilePath fpOld(oldname);
bogdanm 0:9b334a45a8ff 332 FilePath fpNew(newname);
bogdanm 0:9b334a45a8ff 333 FileSystemLike *fsOld = fpOld.fileSystem();
bogdanm 0:9b334a45a8ff 334 FileSystemLike *fsNew = fpNew.fileSystem();
bogdanm 0:9b334a45a8ff 335
bogdanm 0:9b334a45a8ff 336 /* rename only if both files are on the same FS */
bogdanm 0:9b334a45a8ff 337 if (fsOld != fsNew || fsOld == NULL) return -1;
bogdanm 0:9b334a45a8ff 338
bogdanm 0:9b334a45a8ff 339 return fsOld->rename(fpOld.fileName(), fpNew.fileName());
bogdanm 0:9b334a45a8ff 340 }
bogdanm 0:9b334a45a8ff 341
bogdanm 0:9b334a45a8ff 342 extern "C" char *tmpnam(char *s) {
bogdanm 0:9b334a45a8ff 343 return NULL;
bogdanm 0:9b334a45a8ff 344 }
bogdanm 0:9b334a45a8ff 345
bogdanm 0:9b334a45a8ff 346 extern "C" FILE *tmpfile() {
bogdanm 0:9b334a45a8ff 347 return NULL;
bogdanm 0:9b334a45a8ff 348 }
bogdanm 0:9b334a45a8ff 349 } // namespace std
bogdanm 0:9b334a45a8ff 350
bogdanm 0:9b334a45a8ff 351 #ifdef __ARMCC_VERSION
bogdanm 0:9b334a45a8ff 352 extern "C" char *_sys_command_string(char *cmd, int len) {
bogdanm 0:9b334a45a8ff 353 return NULL;
bogdanm 0:9b334a45a8ff 354 }
bogdanm 0:9b334a45a8ff 355 #endif
bogdanm 0:9b334a45a8ff 356
bogdanm 0:9b334a45a8ff 357 extern "C" DIR *opendir(const char *path) {
bogdanm 0:9b334a45a8ff 358 /* root dir is FileSystemLike */
bogdanm 0:9b334a45a8ff 359 if (path[0] == '/' && path[1] == 0) {
bogdanm 0:9b334a45a8ff 360 return FileSystemLike::opendir();
bogdanm 0:9b334a45a8ff 361 }
bogdanm 0:9b334a45a8ff 362
bogdanm 0:9b334a45a8ff 363 FilePath fp(path);
bogdanm 0:9b334a45a8ff 364 FileSystemLike* fs = fp.fileSystem();
bogdanm 0:9b334a45a8ff 365 if (fs == NULL) return NULL;
bogdanm 0:9b334a45a8ff 366
bogdanm 0:9b334a45a8ff 367 return fs->opendir(fp.fileName());
bogdanm 0:9b334a45a8ff 368 }
bogdanm 0:9b334a45a8ff 369
bogdanm 0:9b334a45a8ff 370 extern "C" struct dirent *readdir(DIR *dir) {
bogdanm 0:9b334a45a8ff 371 return dir->readdir();
bogdanm 0:9b334a45a8ff 372 }
bogdanm 0:9b334a45a8ff 373
bogdanm 0:9b334a45a8ff 374 extern "C" int closedir(DIR *dir) {
bogdanm 0:9b334a45a8ff 375 return dir->closedir();
bogdanm 0:9b334a45a8ff 376 }
bogdanm 0:9b334a45a8ff 377
bogdanm 0:9b334a45a8ff 378 extern "C" void rewinddir(DIR *dir) {
bogdanm 0:9b334a45a8ff 379 dir->rewinddir();
bogdanm 0:9b334a45a8ff 380 }
bogdanm 0:9b334a45a8ff 381
bogdanm 0:9b334a45a8ff 382 extern "C" off_t telldir(DIR *dir) {
bogdanm 0:9b334a45a8ff 383 return dir->telldir();
bogdanm 0:9b334a45a8ff 384 }
bogdanm 0:9b334a45a8ff 385
bogdanm 0:9b334a45a8ff 386 extern "C" void seekdir(DIR *dir, off_t off) {
bogdanm 0:9b334a45a8ff 387 dir->seekdir(off);
bogdanm 0:9b334a45a8ff 388 }
bogdanm 0:9b334a45a8ff 389
bogdanm 0:9b334a45a8ff 390 extern "C" int mkdir(const char *path, mode_t mode) {
bogdanm 0:9b334a45a8ff 391 FilePath fp(path);
bogdanm 0:9b334a45a8ff 392 FileSystemLike *fs = fp.fileSystem();
bogdanm 0:9b334a45a8ff 393 if (fs == NULL) return -1;
bogdanm 0:9b334a45a8ff 394
bogdanm 0:9b334a45a8ff 395 return fs->mkdir(fp.fileName(), mode);
bogdanm 0:9b334a45a8ff 396 }
bogdanm 0:9b334a45a8ff 397
bogdanm 0:9b334a45a8ff 398 #if defined(TOOLCHAIN_GCC)
bogdanm 0:9b334a45a8ff 399 /* prevents the exception handling name demangling code getting pulled in */
bogdanm 0:9b334a45a8ff 400 #include "mbed_error.h"
bogdanm 0:9b334a45a8ff 401 namespace __gnu_cxx {
bogdanm 0:9b334a45a8ff 402 void __verbose_terminate_handler() {
bogdanm 0:9b334a45a8ff 403 error("Exception");
bogdanm 0:9b334a45a8ff 404 }
bogdanm 0:9b334a45a8ff 405 }
bogdanm 0:9b334a45a8ff 406 extern "C" WEAK void __cxa_pure_virtual(void);
bogdanm 0:9b334a45a8ff 407 extern "C" WEAK void __cxa_pure_virtual(void) {
bogdanm 0:9b334a45a8ff 408 exit(1);
bogdanm 0:9b334a45a8ff 409 }
bogdanm 0:9b334a45a8ff 410
bogdanm 0:9b334a45a8ff 411 #endif
bogdanm 0:9b334a45a8ff 412
bogdanm 0:9b334a45a8ff 413 // ****************************************************************************
bogdanm 0:9b334a45a8ff 414 // mbed_main is a function that is called before main()
bogdanm 0:9b334a45a8ff 415 // mbed_sdk_init() is also a function that is called before main(), but unlike
bogdanm 0:9b334a45a8ff 416 // mbed_main(), it is not meant for user code, but for the SDK itself to perform
bogdanm 0:9b334a45a8ff 417 // initializations before main() is called.
bogdanm 0:9b334a45a8ff 418
bogdanm 0:9b334a45a8ff 419 extern "C" WEAK void mbed_main(void);
bogdanm 0:9b334a45a8ff 420 extern "C" WEAK void mbed_main(void) {
bogdanm 0:9b334a45a8ff 421 }
bogdanm 0:9b334a45a8ff 422
bogdanm 0:9b334a45a8ff 423 extern "C" WEAK void mbed_sdk_init(void);
bogdanm 0:9b334a45a8ff 424 extern "C" WEAK void mbed_sdk_init(void) {
bogdanm 0:9b334a45a8ff 425 }
bogdanm 0:9b334a45a8ff 426
bogdanm 0:9b334a45a8ff 427 #if defined(TOOLCHAIN_ARM)
bogdanm 0:9b334a45a8ff 428 extern "C" int $Super$$main(void);
bogdanm 0:9b334a45a8ff 429
bogdanm 0:9b334a45a8ff 430 extern "C" int $Sub$$main(void) {
bogdanm 0:9b334a45a8ff 431 mbed_sdk_init();
bogdanm 0:9b334a45a8ff 432 mbed_main();
bogdanm 0:9b334a45a8ff 433 return $Super$$main();
bogdanm 0:9b334a45a8ff 434 }
bogdanm 0:9b334a45a8ff 435 #elif defined(TOOLCHAIN_GCC)
bogdanm 0:9b334a45a8ff 436 extern "C" int __real_main(void);
bogdanm 0:9b334a45a8ff 437
bogdanm 0:9b334a45a8ff 438 extern "C" int __wrap_main(void) {
bogdanm 0:9b334a45a8ff 439 mbed_sdk_init();
bogdanm 0:9b334a45a8ff 440 mbed_main();
bogdanm 0:9b334a45a8ff 441 return __real_main();
bogdanm 0:9b334a45a8ff 442 }
bogdanm 0:9b334a45a8ff 443 #elif defined(TOOLCHAIN_IAR)
bogdanm 0:9b334a45a8ff 444 // IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
bogdanm 0:9b334a45a8ff 445 // to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
bogdanm 0:9b334a45a8ff 446 // 'main' to another symbol looses the original 'main' symbol. However, its startup
bogdanm 0:9b334a45a8ff 447 // code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
bogdanm 0:9b334a45a8ff 448 // Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
bogdanm 0:9b334a45a8ff 449 extern "C" void __iar_argc_argv() {
bogdanm 0:9b334a45a8ff 450 mbed_sdk_init();
bogdanm 0:9b334a45a8ff 451 mbed_main();
bogdanm 0:9b334a45a8ff 452 }
bogdanm 0:9b334a45a8ff 453 #endif
bogdanm 0:9b334a45a8ff 454
bogdanm 0:9b334a45a8ff 455 // Provide implementation of _sbrk (low-level dynamic memory allocation
bogdanm 0:9b334a45a8ff 456 // routine) for GCC_ARM which compares new heap pointer with MSP instead of
bogdanm 0:9b334a45a8ff 457 // SP. This make it compatible with RTX RTOS thread stacks.
bogdanm 0:9b334a45a8ff 458 #if defined(TOOLCHAIN_GCC_ARM)
bogdanm 0:9b334a45a8ff 459 // Linker defined symbol used by _sbrk to indicate where heap should start.
bogdanm 0:9b334a45a8ff 460 extern "C" int __end__;
bogdanm 0:9b334a45a8ff 461
bogdanm 0:9b334a45a8ff 462 #if defined(TARGET_CORTEX_A)
bogdanm 0:9b334a45a8ff 463 extern "C" uint32_t __HeapLimit;
bogdanm 0:9b334a45a8ff 464 #endif
bogdanm 0:9b334a45a8ff 465
bogdanm 0:9b334a45a8ff 466 // Turn off the errno macro and use actual global variable instead.
bogdanm 0:9b334a45a8ff 467 #undef errno
bogdanm 0:9b334a45a8ff 468 extern "C" int errno;
bogdanm 0:9b334a45a8ff 469
bogdanm 0:9b334a45a8ff 470 // For ARM7 only
bogdanm 0:9b334a45a8ff 471 register unsigned char * stack_ptr __asm ("sp");
bogdanm 0:9b334a45a8ff 472
bogdanm 0:9b334a45a8ff 473 // Dynamic memory allocation related syscall.
bogdanm 0:9b334a45a8ff 474 extern "C" caddr_t _sbrk(int incr) {
bogdanm 0:9b334a45a8ff 475 static unsigned char* heap = (unsigned char*)&__end__;
bogdanm 0:9b334a45a8ff 476 unsigned char* prev_heap = heap;
bogdanm 0:9b334a45a8ff 477 unsigned char* new_heap = heap + incr;
bogdanm 0:9b334a45a8ff 478
bogdanm 0:9b334a45a8ff 479 #if defined(TARGET_ARM7)
bogdanm 0:9b334a45a8ff 480 if (new_heap >= stack_ptr) {
bogdanm 0:9b334a45a8ff 481 #elif defined(TARGET_CORTEX_A)
bogdanm 0:9b334a45a8ff 482 if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */
bogdanm 0:9b334a45a8ff 483 #else
bogdanm 0:9b334a45a8ff 484 if (new_heap >= (unsigned char*)__get_MSP()) {
bogdanm 0:9b334a45a8ff 485 #endif
bogdanm 0:9b334a45a8ff 486 errno = ENOMEM;
bogdanm 0:9b334a45a8ff 487 return (caddr_t)-1;
bogdanm 0:9b334a45a8ff 488 }
bogdanm 0:9b334a45a8ff 489
bogdanm 0:9b334a45a8ff 490 heap = new_heap;
bogdanm 0:9b334a45a8ff 491 return (caddr_t) prev_heap;
bogdanm 0:9b334a45a8ff 492 }
bogdanm 0:9b334a45a8ff 493 #endif
bogdanm 0:9b334a45a8ff 494
bogdanm 0:9b334a45a8ff 495
mbed_official 63:5964504d61de 496 #if defined TOOLCHAIN_GCC_ARM
bogdanm 0:9b334a45a8ff 497 extern "C" void _exit(int return_code) {
bogdanm 0:9b334a45a8ff 498 #else
bogdanm 0:9b334a45a8ff 499 namespace std {
bogdanm 0:9b334a45a8ff 500 extern "C" void exit(int return_code) {
bogdanm 0:9b334a45a8ff 501 #endif
bogdanm 0:9b334a45a8ff 502
bogdanm 0:9b334a45a8ff 503 #if DEVICE_STDIO_MESSAGES
bogdanm 0:9b334a45a8ff 504 fflush(stdout);
bogdanm 0:9b334a45a8ff 505 fflush(stderr);
bogdanm 0:9b334a45a8ff 506 #endif
bogdanm 0:9b334a45a8ff 507
bogdanm 0:9b334a45a8ff 508 #if DEVICE_SEMIHOST
bogdanm 0:9b334a45a8ff 509 if (mbed_interface_connected()) {
bogdanm 0:9b334a45a8ff 510 semihost_exit();
bogdanm 0:9b334a45a8ff 511 }
bogdanm 0:9b334a45a8ff 512 #endif
bogdanm 0:9b334a45a8ff 513 if (return_code) {
bogdanm 0:9b334a45a8ff 514 mbed_die();
bogdanm 0:9b334a45a8ff 515 }
bogdanm 0:9b334a45a8ff 516
bogdanm 0:9b334a45a8ff 517 while (1);
bogdanm 0:9b334a45a8ff 518 }
bogdanm 0:9b334a45a8ff 519
mbed_official 63:5964504d61de 520 #if !defined(TOOLCHAIN_GCC_ARM)
bogdanm 0:9b334a45a8ff 521 } //namespace std
bogdanm 0:9b334a45a8ff 522 #endif
bogdanm 0:9b334a45a8ff 523
bogdanm 0:9b334a45a8ff 524
bogdanm 0:9b334a45a8ff 525 namespace mbed {
bogdanm 0:9b334a45a8ff 526
bogdanm 0:9b334a45a8ff 527 void mbed_set_unbuffered_stream(FILE *_file) {
bogdanm 0:9b334a45a8ff 528 #if defined (__ICCARM__)
bogdanm 0:9b334a45a8ff 529 char buf[2];
bogdanm 0:9b334a45a8ff 530 std::setvbuf(_file,buf,_IONBF,NULL);
bogdanm 0:9b334a45a8ff 531 #else
bogdanm 0:9b334a45a8ff 532 setbuf(_file, NULL);
bogdanm 0:9b334a45a8ff 533 #endif
bogdanm 0:9b334a45a8ff 534 }
bogdanm 0:9b334a45a8ff 535
bogdanm 0:9b334a45a8ff 536 int mbed_getc(FILE *_file){
bogdanm 0:9b334a45a8ff 537 #if defined (__ICCARM__)
bogdanm 0:9b334a45a8ff 538 /*This is only valid for unbuffered streams*/
bogdanm 0:9b334a45a8ff 539 int res = std::fgetc(_file);
bogdanm 0:9b334a45a8ff 540 if (res>=0){
bogdanm 0:9b334a45a8ff 541 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
bogdanm 0:9b334a45a8ff 542 _file->_Rend = _file->_Wend;
bogdanm 0:9b334a45a8ff 543 _file->_Next = _file->_Wend;
bogdanm 0:9b334a45a8ff 544 }
bogdanm 0:9b334a45a8ff 545 return res;
bogdanm 0:9b334a45a8ff 546 #else
bogdanm 0:9b334a45a8ff 547 return std::fgetc(_file);
bogdanm 0:9b334a45a8ff 548 #endif
bogdanm 0:9b334a45a8ff 549 }
bogdanm 0:9b334a45a8ff 550
bogdanm 0:9b334a45a8ff 551 char* mbed_gets(char*s, int size, FILE *_file){
bogdanm 0:9b334a45a8ff 552 #if defined (__ICCARM__)
bogdanm 0:9b334a45a8ff 553 /*This is only valid for unbuffered streams*/
bogdanm 0:9b334a45a8ff 554 char *str = fgets(s,size,_file);
bogdanm 0:9b334a45a8ff 555 if (str!=NULL){
bogdanm 0:9b334a45a8ff 556 _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
bogdanm 0:9b334a45a8ff 557 _file->_Rend = _file->_Wend;
bogdanm 0:9b334a45a8ff 558 _file->_Next = _file->_Wend;
bogdanm 0:9b334a45a8ff 559 }
bogdanm 0:9b334a45a8ff 560 return str;
bogdanm 0:9b334a45a8ff 561 #else
bogdanm 0:9b334a45a8ff 562 return std::fgets(s,size,_file);
bogdanm 0:9b334a45a8ff 563 #endif
bogdanm 0:9b334a45a8ff 564 }
bogdanm 0:9b334a45a8ff 565
bogdanm 0:9b334a45a8ff 566 } // namespace mbed