fix for mbed lib issue 3 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/3 affected implementations: LPC812, LPC11U24, LPC1768, LPC2368, LPC4088
Fork of mbed-src by
Diff: cpp/stdio.cpp
- Revision:
- 2:143cac498751
- Parent:
- 1:62685faffa05
- Child:
- 5:ab1c572cb536
--- a/cpp/stdio.cpp Thu Nov 29 15:41:14 2012 +0000 +++ b/cpp/stdio.cpp Mon Feb 18 11:44:18 2013 +0000 @@ -1,31 +1,26 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2012 ARM Limited + * Copyright (c) 2006-2013 ARM Limited * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #include "platform.h" #include "FileHandle.h" #include "FileSystemLike.h" +#include "FilePath.h" #include "serial_api.h" #include <errno.h> -#ifdef __ARMCC_VERSION +#if defined(__ARMCC_VERSION) # include <rt_sys.h> # define PREFIX(x) _sys##x # define OPEN_MAX _SYS_OPEN @@ -33,6 +28,15 @@ # pragma import(__use_full_stdio) # endif +#elif defined(__ICCARM__) +# include <yfuns.h> +# define PREFIX(x) _##x +# define OPEN_MAX 16 + +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 + #else # include <sys/stat.h> # include <sys/unistd.h> @@ -76,30 +80,38 @@ #endif } +static inline int openmode_to_posix(int openmode) { + int posix = openmode; #ifdef __ARMCC_VERSION -static int rvct_openmode_to_posix(int openmode) { - /* RVCT openmode -> POSIX flags */ - int tmpmode = openmode; - if (tmpmode & OPEN_PLUS) { - openmode = O_RDWR; - } else if(tmpmode & OPEN_W) { - openmode = O_WRONLY; - } else if(tmpmode & OPEN_A) { - openmode = O_WRONLY|O_APPEND; + if (openmode & OPEN_PLUS) { + posix = O_RDWR; + } else if(openmode & OPEN_W) { + posix = O_WRONLY; + } else if(openmode & OPEN_A) { + posix = O_WRONLY|O_APPEND; } else { - openmode = O_RDONLY; + posix = O_RDONLY; } /* a, w, a+, w+ all create if file does not already exist */ - if (tmpmode & (OPEN_A|OPEN_W)) { - openmode |= O_CREAT; + if (openmode & (OPEN_A|OPEN_W)) { + posix |= O_CREAT; } /* w and w+ truncate */ - if (tmpmode & OPEN_W) { - openmode |= O_TRUNC; + if (openmode & OPEN_W) { + posix |= O_TRUNC; } - return openmode; +#elif defined(__ICCARM__) + switch (openmode & _LLIO_RDWRMASK) { + case _LLIO_RDONLY: posix = O_RDONLY; break; + case _LLIO_WRONLY: posix = O_WRONLY; break; + case _LLIO_RDWR : posix = O_RDWR ; break; + } + if (openmode & _LLIO_CREAT ) posix |= O_CREAT; + if (openmode & _LLIO_APPEND) posix |= O_APPEND; + if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC; +#endif + return posix; } -#endif extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { /* Use the posix convention that stdin,out,err are filehandles 0,1,2. @@ -114,7 +126,7 @@ init_serial(); return 2; } - + // find the first empty slot in filehandles unsigned int fh_i; for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { @@ -123,44 +135,50 @@ if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { return -1; } - + FileHandle *res; - + /* FILENAME: ":0x12345678" describes a FileLike* */ if (name[0] == ':') { void *p; sscanf(name, ":%p", &p); res = (FileHandle*)p; - + /* FILENAME: "/file_system/file_name" */ } else { FilePath path(name); - - FileSystemLike *fs = path.fileSystem(); - if (fs == NULL) return -1; - -#ifdef __ARMCC_VERSION - openmode = rvct_openmode_to_posix(openmode); -#endif - res = fs->open(path.fileName(), openmode); /* NULL if fails */ + + if (path.isFile()) { + res = path.file(); + } else { + FileSystemLike *fs = path.fileSystem(); + if (fs == NULL) return -1; + int posix_mode = openmode_to_posix(openmode); + res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ + } } - + if (res == NULL) return -1; filehandles[fh_i] = res; + return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err } extern "C" int PREFIX(_close)(FILEHANDLE fh) { if (fh < 3) return 0; - + FileHandle* fhc = filehandles[fh-3]; filehandles[fh-3] = NULL; if (fhc == NULL) return -1; - + return fhc->close(); } -extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char* buffer, unsigned int length, int mode) { +#if defined(__ICCARM__) +extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { +#else +extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { +#endif int n; // n is the number of bytes written if (fh < 3) { #if DEVICE_SERIAL @@ -173,17 +191,21 @@ } else { FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + n = fhc->write(buffer, length); } #ifdef __ARMCC_VERSION return length-n; #else return n; -#endif +#endif } -extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char* buffer, unsigned int length, int mode) { +#if defined(__ICCARM__) +extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { +#else +extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { +#endif int n; // n is the number of bytes read if (fh < 3) { // only read a character at a time from stdin @@ -194,79 +216,80 @@ } else { FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + n = fhc->read(buffer, length); } #ifdef __ARMCC_VERSION return length-n; #else return n; -#endif +#endif } #ifdef __ARMCC_VERSION extern "C" int PREFIX(_istty)(FILEHANDLE fh) #else -extern "C" int isatty(FILEHANDLE fh) +extern "C" int _isatty(FILEHANDLE fh) #endif { /* stdin, stdout and stderr should be tty */ if (fh < 3) return 1; - + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + return fhc->isatty(); } -#ifdef __ARMCC_VERSION -extern "C" int PREFIX(_seek)(FILEHANDLE fh, long position) { - if (fh < 3) return 0; - - FileHandle* fhc = filehandles[fh-3]; - if (fhc == NULL || fhc->lseek(position, SEEK_SET) == -1) return -1; - - return 0; -} +extern "C" +#if defined(__ARMCC_VERSION) +int _sys_seek(FILEHANDLE fh, long position) +#elif defined(__ICCARM__) +long __lseek(int fh, long offset, int whence) #else -extern "C" int _lseek(FILEHANDLE fh, int offset, int whence) { +int _lseek(FILEHANDLE fh, int offset, int whence) +#endif +{ if (fh < 3) return 0; - - FileHandle *fhc = filehandles[fh-3]; + + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + +#if defined(__ARMCC_VERSION) + return fhc->lseek(position, SEEK_SET); +#else return fhc->lseek(offset, whence); +#endif } -#endif #ifdef __ARMCC_VERSION extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { if (fh < 3) return 0; - + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + return fhc->fsync(); } extern "C" long PREFIX(_flen)(FILEHANDLE fh) { if (fh < 3) return 0; - + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + return fhc->flen(); } #endif -#ifndef __ARMCC_VERSION +#if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) extern "C" int _fstat(int fd, struct stat *st) { if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) { st->st_mode = S_IFCHR; return 0; } - + errno = EBADF; return -1; } @@ -277,7 +300,7 @@ FilePath fp(path); FileSystemLike *fs = fp.fileSystem(); if (fs == NULL) return -1; - + return fs->remove(fp.fileName()); } @@ -305,11 +328,11 @@ if (path[0] == '/' && path[1] == 0) { return FileSystemLike::opendir(); } - + FilePath fp(path); FileSystemLike* fs = fp.fileSystem(); if (fs == NULL) return NULL; - + return fs->opendir(fp.fileName()); } @@ -337,7 +360,7 @@ FilePath fp(path); FileSystemLike *fs = fp.fileSystem(); if (fs == NULL) return -1; - + return fs->mkdir(fp.fileName(), mode); }