mbed library sources

Fork of mbed-src by mbed official

Committer:
emilmont
Date:
Mon Jun 10 16:03:00 2013 +0100
Revision:
9:0ce32e54c9a7
Parent:
cpp/LocalFileSystem.cpp@2:143cac498751
Child:
10:3bc89ef62ce7
Refactoring of the mbed SDK:
- Provide a well defined HAL and API
- Keep separated the HAL implementations for the different targets

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:fd0d7bdfcdc2 1 /* mbed Microcontroller Library
emilmont 2:143cac498751 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 0:fd0d7bdfcdc2 3 *
emilmont 2:143cac498751 4 * Licensed under the Apache License, Version 2.0 (the "License");
emilmont 2:143cac498751 5 * you may not use this file except in compliance with the License.
emilmont 2:143cac498751 6 * You may obtain a copy of the License at
mbed_official 0:fd0d7bdfcdc2 7 *
emilmont 2:143cac498751 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 0:fd0d7bdfcdc2 9 *
emilmont 2:143cac498751 10 * Unless required by applicable law or agreed to in writing, software
emilmont 2:143cac498751 11 * distributed under the License is distributed on an "AS IS" BASIS,
emilmont 2:143cac498751 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
emilmont 2:143cac498751 13 * See the License for the specific language governing permissions and
emilmont 2:143cac498751 14 * limitations under the License.
mbed_official 0:fd0d7bdfcdc2 15 */
mbed_official 0:fd0d7bdfcdc2 16 #include "LocalFileSystem.h"
mbed_official 0:fd0d7bdfcdc2 17
mbed_official 0:fd0d7bdfcdc2 18 #if DEVICE_LOCALFILESYSTEM
mbed_official 0:fd0d7bdfcdc2 19
mbed_official 0:fd0d7bdfcdc2 20 #include "semihost_api.h"
mbed_official 0:fd0d7bdfcdc2 21 #include <string.h>
mbed_official 0:fd0d7bdfcdc2 22 #include <stdio.h>
mbed_official 0:fd0d7bdfcdc2 23
mbed_official 0:fd0d7bdfcdc2 24 namespace mbed {
mbed_official 0:fd0d7bdfcdc2 25
mbed_official 0:fd0d7bdfcdc2 26 /* Extension to FINFO type defined in RTL.h (in Keil RL) - adds 'create time'. */
mbed_official 0:fd0d7bdfcdc2 27 typedef struct {
mbed_official 0:fd0d7bdfcdc2 28 unsigned char hr; /* Hours [0..23] */
mbed_official 0:fd0d7bdfcdc2 29 unsigned char min; /* Minutes [0..59] */
mbed_official 0:fd0d7bdfcdc2 30 unsigned char sec; /* Seconds [0..59] */
mbed_official 0:fd0d7bdfcdc2 31 unsigned char day; /* Day [1..31] */
mbed_official 0:fd0d7bdfcdc2 32 unsigned char mon; /* Month [1..12] */
mbed_official 0:fd0d7bdfcdc2 33 unsigned short year; /* Year [1980..2107] */
mbed_official 0:fd0d7bdfcdc2 34 } FTIME;
mbed_official 0:fd0d7bdfcdc2 35
mbed_official 0:fd0d7bdfcdc2 36 typedef struct { /* File Search info record */
mbed_official 0:fd0d7bdfcdc2 37 char name[32]; /* File name */
mbed_official 0:fd0d7bdfcdc2 38 long size; /* File size in bytes */
mbed_official 0:fd0d7bdfcdc2 39 int fileID; /* System File Identification */
mbed_official 0:fd0d7bdfcdc2 40 FTIME create_time; /* Date & time file was created */
mbed_official 0:fd0d7bdfcdc2 41 FTIME write_time; /* Date & time of last write */
mbed_official 0:fd0d7bdfcdc2 42 } XFINFO;
mbed_official 0:fd0d7bdfcdc2 43
mbed_official 0:fd0d7bdfcdc2 44 #define RESERVED_FOR_USER_APPLICATIONS (0x100) /* 0x100 - 0x1ff */
mbed_official 0:fd0d7bdfcdc2 45 #define USR_XFFIND (RESERVED_FOR_USER_APPLICATIONS + 0)
mbed_official 0:fd0d7bdfcdc2 46
mbed_official 0:fd0d7bdfcdc2 47 static int xffind (const char *pattern, XFINFO *info) {
mbed_official 0:fd0d7bdfcdc2 48 unsigned param[4];
mbed_official 0:fd0d7bdfcdc2 49
mbed_official 0:fd0d7bdfcdc2 50 param[0] = (unsigned long)pattern;
mbed_official 0:fd0d7bdfcdc2 51 param[1] = (unsigned long)strlen(pattern);
mbed_official 0:fd0d7bdfcdc2 52 param[2] = (unsigned long)info;
mbed_official 0:fd0d7bdfcdc2 53 param[3] = (unsigned long)sizeof(XFINFO);
emilmont 2:143cac498751 54
mbed_official 0:fd0d7bdfcdc2 55 return __semihost(USR_XFFIND, param);
mbed_official 0:fd0d7bdfcdc2 56 }
mbed_official 0:fd0d7bdfcdc2 57
mbed_official 0:fd0d7bdfcdc2 58 #define OPEN_R 0
mbed_official 0:fd0d7bdfcdc2 59 #define OPEN_B 1
mbed_official 0:fd0d7bdfcdc2 60 #define OPEN_PLUS 2
mbed_official 0:fd0d7bdfcdc2 61 #define OPEN_W 4
mbed_official 0:fd0d7bdfcdc2 62 #define OPEN_A 8
mbed_official 0:fd0d7bdfcdc2 63 #define OPEN_INVALID -1
mbed_official 0:fd0d7bdfcdc2 64
mbed_official 0:fd0d7bdfcdc2 65 int posix_to_semihost_open_flags(int flags) {
mbed_official 0:fd0d7bdfcdc2 66 /* POSIX flags -> semihosting open mode */
mbed_official 0:fd0d7bdfcdc2 67 int openmode;
mbed_official 0:fd0d7bdfcdc2 68 if (flags & O_RDWR) {
mbed_official 0:fd0d7bdfcdc2 69 /* a plus mode */
mbed_official 0:fd0d7bdfcdc2 70 openmode = OPEN_PLUS;
mbed_official 0:fd0d7bdfcdc2 71 if (flags & O_APPEND) {
mbed_official 0:fd0d7bdfcdc2 72 openmode |= OPEN_A;
mbed_official 0:fd0d7bdfcdc2 73 } else if (flags & O_TRUNC) {
mbed_official 0:fd0d7bdfcdc2 74 openmode |= OPEN_W;
mbed_official 0:fd0d7bdfcdc2 75 } else {
mbed_official 0:fd0d7bdfcdc2 76 openmode |= OPEN_R;
mbed_official 0:fd0d7bdfcdc2 77 }
mbed_official 0:fd0d7bdfcdc2 78 } else if (flags & O_WRONLY) {
mbed_official 0:fd0d7bdfcdc2 79 /* write or append */
mbed_official 0:fd0d7bdfcdc2 80 if (flags & O_APPEND) {
mbed_official 0:fd0d7bdfcdc2 81 openmode = OPEN_A;
mbed_official 0:fd0d7bdfcdc2 82 } else {
mbed_official 0:fd0d7bdfcdc2 83 openmode = OPEN_W;
mbed_official 0:fd0d7bdfcdc2 84 }
mbed_official 0:fd0d7bdfcdc2 85 } else if (flags == O_RDONLY) {
mbed_official 0:fd0d7bdfcdc2 86 /* read mode */
mbed_official 0:fd0d7bdfcdc2 87 openmode = OPEN_R;
mbed_official 0:fd0d7bdfcdc2 88 } else {
mbed_official 0:fd0d7bdfcdc2 89 /* invalid flags */
mbed_official 0:fd0d7bdfcdc2 90 openmode = OPEN_INVALID;
mbed_official 0:fd0d7bdfcdc2 91 }
emilmont 2:143cac498751 92
mbed_official 0:fd0d7bdfcdc2 93 return openmode;
mbed_official 0:fd0d7bdfcdc2 94 }
mbed_official 0:fd0d7bdfcdc2 95
mbed_official 0:fd0d7bdfcdc2 96 FILEHANDLE local_file_open(const char* name, int flags) {
mbed_official 0:fd0d7bdfcdc2 97 int openmode = posix_to_semihost_open_flags(flags);
mbed_official 0:fd0d7bdfcdc2 98 if (openmode == OPEN_INVALID) {
mbed_official 0:fd0d7bdfcdc2 99 return (FILEHANDLE)NULL;
mbed_official 0:fd0d7bdfcdc2 100 }
emilmont 2:143cac498751 101
mbed_official 0:fd0d7bdfcdc2 102 FILEHANDLE fh = semihost_open(name, openmode);
mbed_official 0:fd0d7bdfcdc2 103 if (fh == -1) {
mbed_official 0:fd0d7bdfcdc2 104 return (FILEHANDLE)NULL;
mbed_official 0:fd0d7bdfcdc2 105 }
emilmont 2:143cac498751 106
mbed_official 0:fd0d7bdfcdc2 107 return fh;
mbed_official 0:fd0d7bdfcdc2 108 }
mbed_official 0:fd0d7bdfcdc2 109
mbed_official 0:fd0d7bdfcdc2 110 LocalFileHandle::LocalFileHandle(FILEHANDLE fh) {
mbed_official 0:fd0d7bdfcdc2 111 _fh = fh;
mbed_official 0:fd0d7bdfcdc2 112 pos = 0;
mbed_official 0:fd0d7bdfcdc2 113 }
mbed_official 0:fd0d7bdfcdc2 114
mbed_official 0:fd0d7bdfcdc2 115 int LocalFileHandle::close() {
mbed_official 0:fd0d7bdfcdc2 116 int retval = semihost_close(_fh);
mbed_official 0:fd0d7bdfcdc2 117 delete this;
mbed_official 0:fd0d7bdfcdc2 118 return retval;
mbed_official 0:fd0d7bdfcdc2 119 }
mbed_official 0:fd0d7bdfcdc2 120
mbed_official 0:fd0d7bdfcdc2 121 ssize_t LocalFileHandle::write(const void *buffer, size_t length) {
mbed_official 0:fd0d7bdfcdc2 122 ssize_t n = semihost_write(_fh, (const unsigned char*)buffer, length, 0); // number of characters not written
mbed_official 0:fd0d7bdfcdc2 123 n = length - n; // number of characters written
mbed_official 0:fd0d7bdfcdc2 124 pos += n;
mbed_official 0:fd0d7bdfcdc2 125 return n;
mbed_official 0:fd0d7bdfcdc2 126 }
mbed_official 0:fd0d7bdfcdc2 127
mbed_official 0:fd0d7bdfcdc2 128 ssize_t LocalFileHandle::read(void *buffer, size_t length) {
mbed_official 0:fd0d7bdfcdc2 129 ssize_t n = semihost_read(_fh, (unsigned char*)buffer, length, 0); // number of characters not read
mbed_official 0:fd0d7bdfcdc2 130 n = length - n; // number of characters read
mbed_official 0:fd0d7bdfcdc2 131 pos += n;
mbed_official 0:fd0d7bdfcdc2 132 return n;
mbed_official 0:fd0d7bdfcdc2 133 }
mbed_official 0:fd0d7bdfcdc2 134
mbed_official 0:fd0d7bdfcdc2 135 int LocalFileHandle::isatty() {
mbed_official 0:fd0d7bdfcdc2 136 return semihost_istty(_fh);
mbed_official 0:fd0d7bdfcdc2 137 }
mbed_official 0:fd0d7bdfcdc2 138
mbed_official 0:fd0d7bdfcdc2 139 off_t LocalFileHandle::lseek(off_t position, int whence) {
mbed_official 0:fd0d7bdfcdc2 140 if (whence == SEEK_CUR) {
mbed_official 0:fd0d7bdfcdc2 141 position += pos;
mbed_official 0:fd0d7bdfcdc2 142 } else if (whence == SEEK_END) {
mbed_official 0:fd0d7bdfcdc2 143 position += semihost_flen(_fh);
mbed_official 0:fd0d7bdfcdc2 144 } /* otherwise SEEK_SET, so position is fine */
emilmont 2:143cac498751 145
mbed_official 0:fd0d7bdfcdc2 146 /* Always seems to return -1, so just ignore for now. */
mbed_official 0:fd0d7bdfcdc2 147 semihost_seek(_fh, position);
mbed_official 0:fd0d7bdfcdc2 148 pos = position;
mbed_official 0:fd0d7bdfcdc2 149 return position;
mbed_official 0:fd0d7bdfcdc2 150 }
mbed_official 0:fd0d7bdfcdc2 151
mbed_official 0:fd0d7bdfcdc2 152 int LocalFileHandle::fsync() {
mbed_official 0:fd0d7bdfcdc2 153 return semihost_ensure(_fh);
mbed_official 0:fd0d7bdfcdc2 154 }
mbed_official 0:fd0d7bdfcdc2 155
mbed_official 0:fd0d7bdfcdc2 156 off_t LocalFileHandle::flen() {
mbed_official 0:fd0d7bdfcdc2 157 return semihost_flen(_fh);
mbed_official 0:fd0d7bdfcdc2 158 }
mbed_official 0:fd0d7bdfcdc2 159
mbed_official 0:fd0d7bdfcdc2 160 class LocalDirHandle : public DirHandle {
mbed_official 0:fd0d7bdfcdc2 161
mbed_official 0:fd0d7bdfcdc2 162 public:
mbed_official 0:fd0d7bdfcdc2 163 struct dirent cur_entry;
mbed_official 0:fd0d7bdfcdc2 164 XFINFO info;
emilmont 2:143cac498751 165
mbed_official 0:fd0d7bdfcdc2 166 LocalDirHandle() {
mbed_official 0:fd0d7bdfcdc2 167 info.fileID = 0;
mbed_official 0:fd0d7bdfcdc2 168 }
emilmont 2:143cac498751 169
mbed_official 0:fd0d7bdfcdc2 170 virtual int closedir() {
mbed_official 0:fd0d7bdfcdc2 171 delete this;
mbed_official 0:fd0d7bdfcdc2 172 return 0;
mbed_official 0:fd0d7bdfcdc2 173 }
emilmont 2:143cac498751 174
mbed_official 0:fd0d7bdfcdc2 175 virtual struct dirent *readdir() {
mbed_official 0:fd0d7bdfcdc2 176 if (xffind("*", &info)!=0) {
mbed_official 0:fd0d7bdfcdc2 177 return NULL;
mbed_official 0:fd0d7bdfcdc2 178 }
mbed_official 0:fd0d7bdfcdc2 179 memcpy(cur_entry.d_name, info.name, sizeof(info.name));
mbed_official 0:fd0d7bdfcdc2 180 return &cur_entry;
mbed_official 0:fd0d7bdfcdc2 181 }
emilmont 2:143cac498751 182
mbed_official 0:fd0d7bdfcdc2 183 virtual void rewinddir() {
mbed_official 0:fd0d7bdfcdc2 184 info.fileID = 0;
mbed_official 0:fd0d7bdfcdc2 185 }
emilmont 2:143cac498751 186
mbed_official 0:fd0d7bdfcdc2 187 virtual off_t telldir() {
mbed_official 0:fd0d7bdfcdc2 188 return info.fileID;
mbed_official 0:fd0d7bdfcdc2 189 }
emilmont 2:143cac498751 190
emilmont 2:143cac498751 191 virtual void seekdir(off_t offset) {
mbed_official 0:fd0d7bdfcdc2 192 info.fileID = offset;
mbed_official 0:fd0d7bdfcdc2 193 }
mbed_official 0:fd0d7bdfcdc2 194 };
mbed_official 0:fd0d7bdfcdc2 195
mbed_official 0:fd0d7bdfcdc2 196 FileHandle *LocalFileSystem::open(const char* name, int flags) {
mbed_official 0:fd0d7bdfcdc2 197 /* reject filenames with / in them */
mbed_official 0:fd0d7bdfcdc2 198 for (const char *tmp = name; *tmp; tmp++) {
mbed_official 0:fd0d7bdfcdc2 199 if (*tmp == '/') {
mbed_official 0:fd0d7bdfcdc2 200 return NULL;
mbed_official 0:fd0d7bdfcdc2 201 }
mbed_official 0:fd0d7bdfcdc2 202 }
emilmont 2:143cac498751 203
mbed_official 0:fd0d7bdfcdc2 204 int openmode = posix_to_semihost_open_flags(flags);
mbed_official 0:fd0d7bdfcdc2 205 if (openmode == OPEN_INVALID) {
mbed_official 0:fd0d7bdfcdc2 206 return NULL;
mbed_official 0:fd0d7bdfcdc2 207 }
emilmont 2:143cac498751 208
mbed_official 0:fd0d7bdfcdc2 209 FILEHANDLE fh = semihost_open(name, openmode);
mbed_official 0:fd0d7bdfcdc2 210 if (fh == -1) {
mbed_official 0:fd0d7bdfcdc2 211 return NULL;
mbed_official 0:fd0d7bdfcdc2 212 }
mbed_official 0:fd0d7bdfcdc2 213 return new LocalFileHandle(fh);
mbed_official 0:fd0d7bdfcdc2 214 }
mbed_official 0:fd0d7bdfcdc2 215
mbed_official 0:fd0d7bdfcdc2 216 int LocalFileSystem::remove(const char *filename) {
mbed_official 0:fd0d7bdfcdc2 217 return semihost_remove(filename);
mbed_official 0:fd0d7bdfcdc2 218 }
mbed_official 0:fd0d7bdfcdc2 219
mbed_official 0:fd0d7bdfcdc2 220 DirHandle *LocalFileSystem::opendir(const char *name) {
mbed_official 0:fd0d7bdfcdc2 221 return new LocalDirHandle();
mbed_official 0:fd0d7bdfcdc2 222 }
mbed_official 0:fd0d7bdfcdc2 223
mbed_official 0:fd0d7bdfcdc2 224 } // namespace mbed
mbed_official 0:fd0d7bdfcdc2 225
mbed_official 0:fd0d7bdfcdc2 226 #endif