mbed library sources

Dependents:   bare

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Tue Nov 20 17:24:08 2012 +0000
Revision:
0:fd0d7bdfcdc2
Child:
2:143cac498751
mbed sources

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:fd0d7bdfcdc2 1 /* mbed Microcontroller Library
mbed_official 0:fd0d7bdfcdc2 2 * Copyright (c) 2006-2012 ARM Limited
mbed_official 0:fd0d7bdfcdc2 3 *
mbed_official 0:fd0d7bdfcdc2 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
mbed_official 0:fd0d7bdfcdc2 5 * of this software and associated documentation files (the "Software"), to deal
mbed_official 0:fd0d7bdfcdc2 6 * in the Software without restriction, including without limitation the rights
mbed_official 0:fd0d7bdfcdc2 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
mbed_official 0:fd0d7bdfcdc2 8 * copies of the Software, and to permit persons to whom the Software is
mbed_official 0:fd0d7bdfcdc2 9 * furnished to do so, subject to the following conditions:
mbed_official 0:fd0d7bdfcdc2 10 *
mbed_official 0:fd0d7bdfcdc2 11 * The above copyright notice and this permission notice shall be included in
mbed_official 0:fd0d7bdfcdc2 12 * all copies or substantial portions of the Software.
mbed_official 0:fd0d7bdfcdc2 13 *
mbed_official 0:fd0d7bdfcdc2 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
mbed_official 0:fd0d7bdfcdc2 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
mbed_official 0:fd0d7bdfcdc2 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
mbed_official 0:fd0d7bdfcdc2 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
mbed_official 0:fd0d7bdfcdc2 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mbed_official 0:fd0d7bdfcdc2 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
mbed_official 0:fd0d7bdfcdc2 20 * SOFTWARE.
mbed_official 0:fd0d7bdfcdc2 21 */
mbed_official 0:fd0d7bdfcdc2 22 #include "LocalFileSystem.h"
mbed_official 0:fd0d7bdfcdc2 23
mbed_official 0:fd0d7bdfcdc2 24 #if DEVICE_LOCALFILESYSTEM
mbed_official 0:fd0d7bdfcdc2 25
mbed_official 0:fd0d7bdfcdc2 26 #include "semihost_api.h"
mbed_official 0:fd0d7bdfcdc2 27 #include <string.h>
mbed_official 0:fd0d7bdfcdc2 28 #include <stdio.h>
mbed_official 0:fd0d7bdfcdc2 29
mbed_official 0:fd0d7bdfcdc2 30 namespace mbed {
mbed_official 0:fd0d7bdfcdc2 31
mbed_official 0:fd0d7bdfcdc2 32 /* Extension to FINFO type defined in RTL.h (in Keil RL) - adds 'create time'. */
mbed_official 0:fd0d7bdfcdc2 33 typedef struct {
mbed_official 0:fd0d7bdfcdc2 34 unsigned char hr; /* Hours [0..23] */
mbed_official 0:fd0d7bdfcdc2 35 unsigned char min; /* Minutes [0..59] */
mbed_official 0:fd0d7bdfcdc2 36 unsigned char sec; /* Seconds [0..59] */
mbed_official 0:fd0d7bdfcdc2 37 unsigned char day; /* Day [1..31] */
mbed_official 0:fd0d7bdfcdc2 38 unsigned char mon; /* Month [1..12] */
mbed_official 0:fd0d7bdfcdc2 39 unsigned short year; /* Year [1980..2107] */
mbed_official 0:fd0d7bdfcdc2 40 } FTIME;
mbed_official 0:fd0d7bdfcdc2 41
mbed_official 0:fd0d7bdfcdc2 42 typedef struct { /* File Search info record */
mbed_official 0:fd0d7bdfcdc2 43 char name[32]; /* File name */
mbed_official 0:fd0d7bdfcdc2 44 long size; /* File size in bytes */
mbed_official 0:fd0d7bdfcdc2 45 int fileID; /* System File Identification */
mbed_official 0:fd0d7bdfcdc2 46 FTIME create_time; /* Date & time file was created */
mbed_official 0:fd0d7bdfcdc2 47 FTIME write_time; /* Date & time of last write */
mbed_official 0:fd0d7bdfcdc2 48 } XFINFO;
mbed_official 0:fd0d7bdfcdc2 49
mbed_official 0:fd0d7bdfcdc2 50 #define RESERVED_FOR_USER_APPLICATIONS (0x100) /* 0x100 - 0x1ff */
mbed_official 0:fd0d7bdfcdc2 51 #define USR_XFFIND (RESERVED_FOR_USER_APPLICATIONS + 0)
mbed_official 0:fd0d7bdfcdc2 52
mbed_official 0:fd0d7bdfcdc2 53 static int xffind (const char *pattern, XFINFO *info) {
mbed_official 0:fd0d7bdfcdc2 54 unsigned param[4];
mbed_official 0:fd0d7bdfcdc2 55
mbed_official 0:fd0d7bdfcdc2 56 param[0] = (unsigned long)pattern;
mbed_official 0:fd0d7bdfcdc2 57 param[1] = (unsigned long)strlen(pattern);
mbed_official 0:fd0d7bdfcdc2 58 param[2] = (unsigned long)info;
mbed_official 0:fd0d7bdfcdc2 59 param[3] = (unsigned long)sizeof(XFINFO);
mbed_official 0:fd0d7bdfcdc2 60
mbed_official 0:fd0d7bdfcdc2 61 return __semihost(USR_XFFIND, param);
mbed_official 0:fd0d7bdfcdc2 62 }
mbed_official 0:fd0d7bdfcdc2 63
mbed_official 0:fd0d7bdfcdc2 64 #define OPEN_R 0
mbed_official 0:fd0d7bdfcdc2 65 #define OPEN_B 1
mbed_official 0:fd0d7bdfcdc2 66 #define OPEN_PLUS 2
mbed_official 0:fd0d7bdfcdc2 67 #define OPEN_W 4
mbed_official 0:fd0d7bdfcdc2 68 #define OPEN_A 8
mbed_official 0:fd0d7bdfcdc2 69 #define OPEN_INVALID -1
mbed_official 0:fd0d7bdfcdc2 70
mbed_official 0:fd0d7bdfcdc2 71 int posix_to_semihost_open_flags(int flags) {
mbed_official 0:fd0d7bdfcdc2 72 /* POSIX flags -> semihosting open mode */
mbed_official 0:fd0d7bdfcdc2 73 int openmode;
mbed_official 0:fd0d7bdfcdc2 74 if (flags & O_RDWR) {
mbed_official 0:fd0d7bdfcdc2 75 /* a plus mode */
mbed_official 0:fd0d7bdfcdc2 76 openmode = OPEN_PLUS;
mbed_official 0:fd0d7bdfcdc2 77 if (flags & O_APPEND) {
mbed_official 0:fd0d7bdfcdc2 78 openmode |= OPEN_A;
mbed_official 0:fd0d7bdfcdc2 79 } else if (flags & O_TRUNC) {
mbed_official 0:fd0d7bdfcdc2 80 openmode |= OPEN_W;
mbed_official 0:fd0d7bdfcdc2 81 } else {
mbed_official 0:fd0d7bdfcdc2 82 openmode |= OPEN_R;
mbed_official 0:fd0d7bdfcdc2 83 }
mbed_official 0:fd0d7bdfcdc2 84 } else if (flags & O_WRONLY) {
mbed_official 0:fd0d7bdfcdc2 85 /* write or append */
mbed_official 0:fd0d7bdfcdc2 86 if (flags & O_APPEND) {
mbed_official 0:fd0d7bdfcdc2 87 openmode = OPEN_A;
mbed_official 0:fd0d7bdfcdc2 88 } else {
mbed_official 0:fd0d7bdfcdc2 89 openmode = OPEN_W;
mbed_official 0:fd0d7bdfcdc2 90 }
mbed_official 0:fd0d7bdfcdc2 91 } else if (flags == O_RDONLY) {
mbed_official 0:fd0d7bdfcdc2 92 /* read mode */
mbed_official 0:fd0d7bdfcdc2 93 openmode = OPEN_R;
mbed_official 0:fd0d7bdfcdc2 94 } else {
mbed_official 0:fd0d7bdfcdc2 95 /* invalid flags */
mbed_official 0:fd0d7bdfcdc2 96 openmode = OPEN_INVALID;
mbed_official 0:fd0d7bdfcdc2 97 }
mbed_official 0:fd0d7bdfcdc2 98
mbed_official 0:fd0d7bdfcdc2 99 return openmode;
mbed_official 0:fd0d7bdfcdc2 100 }
mbed_official 0:fd0d7bdfcdc2 101
mbed_official 0:fd0d7bdfcdc2 102 FILEHANDLE local_file_open(const char* name, int flags) {
mbed_official 0:fd0d7bdfcdc2 103 int openmode = posix_to_semihost_open_flags(flags);
mbed_official 0:fd0d7bdfcdc2 104 if (openmode == OPEN_INVALID) {
mbed_official 0:fd0d7bdfcdc2 105 return (FILEHANDLE)NULL;
mbed_official 0:fd0d7bdfcdc2 106 }
mbed_official 0:fd0d7bdfcdc2 107
mbed_official 0:fd0d7bdfcdc2 108 FILEHANDLE fh = semihost_open(name, openmode);
mbed_official 0:fd0d7bdfcdc2 109 if (fh == -1) {
mbed_official 0:fd0d7bdfcdc2 110 return (FILEHANDLE)NULL;
mbed_official 0:fd0d7bdfcdc2 111 }
mbed_official 0:fd0d7bdfcdc2 112
mbed_official 0:fd0d7bdfcdc2 113 return fh;
mbed_official 0:fd0d7bdfcdc2 114 }
mbed_official 0:fd0d7bdfcdc2 115
mbed_official 0:fd0d7bdfcdc2 116 LocalFileHandle::LocalFileHandle(FILEHANDLE fh) {
mbed_official 0:fd0d7bdfcdc2 117 _fh = fh;
mbed_official 0:fd0d7bdfcdc2 118 pos = 0;
mbed_official 0:fd0d7bdfcdc2 119 }
mbed_official 0:fd0d7bdfcdc2 120
mbed_official 0:fd0d7bdfcdc2 121 int LocalFileHandle::close() {
mbed_official 0:fd0d7bdfcdc2 122 int retval = semihost_close(_fh);
mbed_official 0:fd0d7bdfcdc2 123 delete this;
mbed_official 0:fd0d7bdfcdc2 124 return retval;
mbed_official 0:fd0d7bdfcdc2 125 }
mbed_official 0:fd0d7bdfcdc2 126
mbed_official 0:fd0d7bdfcdc2 127 ssize_t LocalFileHandle::write(const void *buffer, size_t length) {
mbed_official 0:fd0d7bdfcdc2 128 ssize_t n = semihost_write(_fh, (const unsigned char*)buffer, length, 0); // number of characters not written
mbed_official 0:fd0d7bdfcdc2 129 n = length - n; // number of characters written
mbed_official 0:fd0d7bdfcdc2 130 pos += n;
mbed_official 0:fd0d7bdfcdc2 131 return n;
mbed_official 0:fd0d7bdfcdc2 132 }
mbed_official 0:fd0d7bdfcdc2 133
mbed_official 0:fd0d7bdfcdc2 134 ssize_t LocalFileHandle::read(void *buffer, size_t length) {
mbed_official 0:fd0d7bdfcdc2 135 ssize_t n = semihost_read(_fh, (unsigned char*)buffer, length, 0); // number of characters not read
mbed_official 0:fd0d7bdfcdc2 136 n = length - n; // number of characters read
mbed_official 0:fd0d7bdfcdc2 137 pos += n;
mbed_official 0:fd0d7bdfcdc2 138 return n;
mbed_official 0:fd0d7bdfcdc2 139 }
mbed_official 0:fd0d7bdfcdc2 140
mbed_official 0:fd0d7bdfcdc2 141 int LocalFileHandle::isatty() {
mbed_official 0:fd0d7bdfcdc2 142 return semihost_istty(_fh);
mbed_official 0:fd0d7bdfcdc2 143 }
mbed_official 0:fd0d7bdfcdc2 144
mbed_official 0:fd0d7bdfcdc2 145 off_t LocalFileHandle::lseek(off_t position, int whence) {
mbed_official 0:fd0d7bdfcdc2 146 if (whence == SEEK_CUR) {
mbed_official 0:fd0d7bdfcdc2 147 position += pos;
mbed_official 0:fd0d7bdfcdc2 148 } else if (whence == SEEK_END) {
mbed_official 0:fd0d7bdfcdc2 149 position += semihost_flen(_fh);
mbed_official 0:fd0d7bdfcdc2 150 } /* otherwise SEEK_SET, so position is fine */
mbed_official 0:fd0d7bdfcdc2 151
mbed_official 0:fd0d7bdfcdc2 152 /* Always seems to return -1, so just ignore for now. */
mbed_official 0:fd0d7bdfcdc2 153 semihost_seek(_fh, position);
mbed_official 0:fd0d7bdfcdc2 154 pos = position;
mbed_official 0:fd0d7bdfcdc2 155 return position;
mbed_official 0:fd0d7bdfcdc2 156 }
mbed_official 0:fd0d7bdfcdc2 157
mbed_official 0:fd0d7bdfcdc2 158 int LocalFileHandle::fsync() {
mbed_official 0:fd0d7bdfcdc2 159 return semihost_ensure(_fh);
mbed_official 0:fd0d7bdfcdc2 160 }
mbed_official 0:fd0d7bdfcdc2 161
mbed_official 0:fd0d7bdfcdc2 162 off_t LocalFileHandle::flen() {
mbed_official 0:fd0d7bdfcdc2 163 return semihost_flen(_fh);
mbed_official 0:fd0d7bdfcdc2 164 }
mbed_official 0:fd0d7bdfcdc2 165
mbed_official 0:fd0d7bdfcdc2 166 class LocalDirHandle : public DirHandle {
mbed_official 0:fd0d7bdfcdc2 167
mbed_official 0:fd0d7bdfcdc2 168 public:
mbed_official 0:fd0d7bdfcdc2 169 struct dirent cur_entry;
mbed_official 0:fd0d7bdfcdc2 170 XFINFO info;
mbed_official 0:fd0d7bdfcdc2 171
mbed_official 0:fd0d7bdfcdc2 172 LocalDirHandle() {
mbed_official 0:fd0d7bdfcdc2 173 info.fileID = 0;
mbed_official 0:fd0d7bdfcdc2 174 }
mbed_official 0:fd0d7bdfcdc2 175
mbed_official 0:fd0d7bdfcdc2 176 virtual int closedir() {
mbed_official 0:fd0d7bdfcdc2 177 delete this;
mbed_official 0:fd0d7bdfcdc2 178 return 0;
mbed_official 0:fd0d7bdfcdc2 179 }
mbed_official 0:fd0d7bdfcdc2 180
mbed_official 0:fd0d7bdfcdc2 181 virtual struct dirent *readdir() {
mbed_official 0:fd0d7bdfcdc2 182 if (xffind("*", &info)!=0) {
mbed_official 0:fd0d7bdfcdc2 183 return NULL;
mbed_official 0:fd0d7bdfcdc2 184 }
mbed_official 0:fd0d7bdfcdc2 185 memcpy(cur_entry.d_name, info.name, sizeof(info.name));
mbed_official 0:fd0d7bdfcdc2 186 return &cur_entry;
mbed_official 0:fd0d7bdfcdc2 187 }
mbed_official 0:fd0d7bdfcdc2 188
mbed_official 0:fd0d7bdfcdc2 189 virtual void rewinddir() {
mbed_official 0:fd0d7bdfcdc2 190 info.fileID = 0;
mbed_official 0:fd0d7bdfcdc2 191 }
mbed_official 0:fd0d7bdfcdc2 192
mbed_official 0:fd0d7bdfcdc2 193 virtual off_t telldir() {
mbed_official 0:fd0d7bdfcdc2 194 return info.fileID;
mbed_official 0:fd0d7bdfcdc2 195 }
mbed_official 0:fd0d7bdfcdc2 196
mbed_official 0:fd0d7bdfcdc2 197 virtual void seekdir(off_t offset) {
mbed_official 0:fd0d7bdfcdc2 198 info.fileID = offset;
mbed_official 0:fd0d7bdfcdc2 199 }
mbed_official 0:fd0d7bdfcdc2 200 };
mbed_official 0:fd0d7bdfcdc2 201
mbed_official 0:fd0d7bdfcdc2 202 FileHandle *LocalFileSystem::open(const char* name, int flags) {
mbed_official 0:fd0d7bdfcdc2 203 /* reject filenames with / in them */
mbed_official 0:fd0d7bdfcdc2 204 for (const char *tmp = name; *tmp; tmp++) {
mbed_official 0:fd0d7bdfcdc2 205 if (*tmp == '/') {
mbed_official 0:fd0d7bdfcdc2 206 return NULL;
mbed_official 0:fd0d7bdfcdc2 207 }
mbed_official 0:fd0d7bdfcdc2 208 }
mbed_official 0:fd0d7bdfcdc2 209
mbed_official 0:fd0d7bdfcdc2 210 int openmode = posix_to_semihost_open_flags(flags);
mbed_official 0:fd0d7bdfcdc2 211 if (openmode == OPEN_INVALID) {
mbed_official 0:fd0d7bdfcdc2 212 return NULL;
mbed_official 0:fd0d7bdfcdc2 213 }
mbed_official 0:fd0d7bdfcdc2 214
mbed_official 0:fd0d7bdfcdc2 215 FILEHANDLE fh = semihost_open(name, openmode);
mbed_official 0:fd0d7bdfcdc2 216 if (fh == -1) {
mbed_official 0:fd0d7bdfcdc2 217 return NULL;
mbed_official 0:fd0d7bdfcdc2 218 }
mbed_official 0:fd0d7bdfcdc2 219 return new LocalFileHandle(fh);
mbed_official 0:fd0d7bdfcdc2 220 }
mbed_official 0:fd0d7bdfcdc2 221
mbed_official 0:fd0d7bdfcdc2 222 int LocalFileSystem::remove(const char *filename) {
mbed_official 0:fd0d7bdfcdc2 223 return semihost_remove(filename);
mbed_official 0:fd0d7bdfcdc2 224 }
mbed_official 0:fd0d7bdfcdc2 225
mbed_official 0:fd0d7bdfcdc2 226 DirHandle *LocalFileSystem::opendir(const char *name) {
mbed_official 0:fd0d7bdfcdc2 227 return new LocalDirHandle();
mbed_official 0:fd0d7bdfcdc2 228 }
mbed_official 0:fd0d7bdfcdc2 229
mbed_official 0:fd0d7bdfcdc2 230 } // namespace mbed
mbed_official 0:fd0d7bdfcdc2 231
mbed_official 0:fd0d7bdfcdc2 232 #endif