Modified for BG96

Fork of mbed-dev by mbed official

Committer:
WaleedElmughrabi
Date:
Thu Sep 20 16:11:23 2018 +0000
Revision:
188:60408c49b6d4
Parent:
187:0387e8f68319
Fork modified for BG96 error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 167:e84263d55307 1 /* mbed Microcontroller Library
AnnaBridge 167:e84263d55307 2 * Copyright (c) 2006-2013 ARM Limited
AnnaBridge 167:e84263d55307 3 *
AnnaBridge 167:e84263d55307 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 167:e84263d55307 5 * you may not use this file except in compliance with the License.
AnnaBridge 167:e84263d55307 6 * You may obtain a copy of the License at
AnnaBridge 167:e84263d55307 7 *
AnnaBridge 167:e84263d55307 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 167:e84263d55307 9 *
AnnaBridge 167:e84263d55307 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 167:e84263d55307 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 167:e84263d55307 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 167:e84263d55307 13 * See the License for the specific language governing permissions and
AnnaBridge 167:e84263d55307 14 * limitations under the License.
AnnaBridge 167:e84263d55307 15 */
AnnaBridge 167:e84263d55307 16 #include "platform/LocalFileSystem.h"
AnnaBridge 167:e84263d55307 17
AnnaBridge 167:e84263d55307 18 #if DEVICE_LOCALFILESYSTEM
AnnaBridge 167:e84263d55307 19
AnnaBridge 167:e84263d55307 20 #include "platform/mbed_semihost_api.h"
AnnaBridge 167:e84263d55307 21 #include <string.h>
AnnaBridge 167:e84263d55307 22 #include <stdio.h>
AnnaBridge 167:e84263d55307 23 #include <errno.h>
AnnaBridge 167:e84263d55307 24
AnnaBridge 167:e84263d55307 25 namespace mbed {
AnnaBridge 167:e84263d55307 26
AnnaBridge 167:e84263d55307 27 /* Extension to FINFO type defined in RTL.h (in Keil RL) - adds 'create time'. */
AnnaBridge 167:e84263d55307 28 typedef struct {
AnnaBridge 167:e84263d55307 29 unsigned char hr; /* Hours [0..23] */
AnnaBridge 167:e84263d55307 30 unsigned char min; /* Minutes [0..59] */
AnnaBridge 167:e84263d55307 31 unsigned char sec; /* Seconds [0..59] */
AnnaBridge 167:e84263d55307 32 unsigned char day; /* Day [1..31] */
AnnaBridge 167:e84263d55307 33 unsigned char mon; /* Month [1..12] */
AnnaBridge 167:e84263d55307 34 unsigned short year; /* Year [1980..2107] */
AnnaBridge 167:e84263d55307 35 } FTIME;
AnnaBridge 167:e84263d55307 36
AnnaBridge 167:e84263d55307 37 typedef struct { /* File Search info record */
AnnaBridge 167:e84263d55307 38 char name[32]; /* File name */
AnnaBridge 167:e84263d55307 39 long size; /* File size in bytes */
AnnaBridge 167:e84263d55307 40 int fileID; /* System File Identification */
AnnaBridge 167:e84263d55307 41 FTIME create_time; /* Date & time file was created */
AnnaBridge 167:e84263d55307 42 FTIME write_time; /* Date & time of last write */
AnnaBridge 167:e84263d55307 43 } XFINFO;
AnnaBridge 167:e84263d55307 44
AnnaBridge 167:e84263d55307 45 #define RESERVED_FOR_USER_APPLICATIONS (0x100) /* 0x100 - 0x1ff */
AnnaBridge 167:e84263d55307 46 #define USR_XFFIND (RESERVED_FOR_USER_APPLICATIONS + 0)
AnnaBridge 167:e84263d55307 47
AnnaBridge 187:0387e8f68319 48 static int xffind(const char *pattern, XFINFO *info)
AnnaBridge 187:0387e8f68319 49 {
AnnaBridge 167:e84263d55307 50 unsigned param[4];
AnnaBridge 167:e84263d55307 51
AnnaBridge 167:e84263d55307 52 param[0] = (unsigned long)pattern;
AnnaBridge 167:e84263d55307 53 param[1] = (unsigned long)strlen(pattern);
AnnaBridge 167:e84263d55307 54 param[2] = (unsigned long)info;
AnnaBridge 167:e84263d55307 55 param[3] = (unsigned long)sizeof(XFINFO);
AnnaBridge 167:e84263d55307 56
AnnaBridge 167:e84263d55307 57 return __semihost(USR_XFFIND, param);
AnnaBridge 167:e84263d55307 58 }
AnnaBridge 167:e84263d55307 59
AnnaBridge 167:e84263d55307 60 #define OPEN_R 0
AnnaBridge 167:e84263d55307 61 #define OPEN_B 1
AnnaBridge 167:e84263d55307 62 #define OPEN_PLUS 2
AnnaBridge 167:e84263d55307 63 #define OPEN_W 4
AnnaBridge 167:e84263d55307 64 #define OPEN_A 8
AnnaBridge 167:e84263d55307 65 #define OPEN_INVALID -1
AnnaBridge 167:e84263d55307 66
AnnaBridge 187:0387e8f68319 67 int posix_to_semihost_open_flags(int flags)
AnnaBridge 187:0387e8f68319 68 {
AnnaBridge 167:e84263d55307 69 /* POSIX flags -> semihosting open mode */
AnnaBridge 167:e84263d55307 70 int openmode;
AnnaBridge 167:e84263d55307 71 if (flags & O_RDWR) {
AnnaBridge 167:e84263d55307 72 /* a plus mode */
AnnaBridge 167:e84263d55307 73 openmode = OPEN_PLUS;
AnnaBridge 167:e84263d55307 74 if (flags & O_APPEND) {
AnnaBridge 167:e84263d55307 75 openmode |= OPEN_A;
AnnaBridge 167:e84263d55307 76 } else if (flags & O_TRUNC) {
AnnaBridge 167:e84263d55307 77 openmode |= OPEN_W;
AnnaBridge 167:e84263d55307 78 } else {
AnnaBridge 167:e84263d55307 79 openmode |= OPEN_R;
AnnaBridge 167:e84263d55307 80 }
AnnaBridge 167:e84263d55307 81 } else if (flags & O_WRONLY) {
AnnaBridge 167:e84263d55307 82 /* write or append */
AnnaBridge 167:e84263d55307 83 if (flags & O_APPEND) {
AnnaBridge 167:e84263d55307 84 openmode = OPEN_A;
AnnaBridge 167:e84263d55307 85 } else {
AnnaBridge 167:e84263d55307 86 openmode = OPEN_W;
AnnaBridge 167:e84263d55307 87 }
AnnaBridge 167:e84263d55307 88 } else if (flags == O_RDONLY) {
AnnaBridge 167:e84263d55307 89 /* read mode */
AnnaBridge 167:e84263d55307 90 openmode = OPEN_R;
AnnaBridge 167:e84263d55307 91 } else {
AnnaBridge 167:e84263d55307 92 /* invalid flags */
AnnaBridge 167:e84263d55307 93 openmode = OPEN_INVALID;
AnnaBridge 167:e84263d55307 94 }
AnnaBridge 167:e84263d55307 95
AnnaBridge 167:e84263d55307 96 return openmode;
AnnaBridge 167:e84263d55307 97 }
AnnaBridge 167:e84263d55307 98
AnnaBridge 187:0387e8f68319 99 FILEHANDLE local_file_open(const char *name, int flags)
AnnaBridge 187:0387e8f68319 100 {
AnnaBridge 167:e84263d55307 101 int openmode = posix_to_semihost_open_flags(flags);
AnnaBridge 167:e84263d55307 102 if (openmode == OPEN_INVALID) {
AnnaBridge 167:e84263d55307 103 return (FILEHANDLE)NULL;
AnnaBridge 167:e84263d55307 104 }
AnnaBridge 167:e84263d55307 105
AnnaBridge 167:e84263d55307 106 FILEHANDLE fh = semihost_open(name, openmode);
AnnaBridge 167:e84263d55307 107 if (fh == -1) {
AnnaBridge 167:e84263d55307 108 return (FILEHANDLE)NULL;
AnnaBridge 167:e84263d55307 109 }
AnnaBridge 167:e84263d55307 110
AnnaBridge 167:e84263d55307 111 return fh;
AnnaBridge 167:e84263d55307 112 }
AnnaBridge 167:e84263d55307 113
AnnaBridge 187:0387e8f68319 114 LocalFileHandle::LocalFileHandle(FILEHANDLE fh) : _fh(fh), pos(0)
AnnaBridge 187:0387e8f68319 115 {
AnnaBridge 167:e84263d55307 116 // No lock needed in constructor
AnnaBridge 167:e84263d55307 117 }
AnnaBridge 167:e84263d55307 118
AnnaBridge 187:0387e8f68319 119 int LocalFileHandle::close()
AnnaBridge 187:0387e8f68319 120 {
AnnaBridge 167:e84263d55307 121 int retval = semihost_close(_fh);
AnnaBridge 167:e84263d55307 122 delete this;
AnnaBridge 167:e84263d55307 123 return retval;
AnnaBridge 167:e84263d55307 124 }
AnnaBridge 167:e84263d55307 125
AnnaBridge 187:0387e8f68319 126 ssize_t LocalFileHandle::write(const void *buffer, size_t length)
AnnaBridge 187:0387e8f68319 127 {
AnnaBridge 167:e84263d55307 128 lock();
AnnaBridge 187:0387e8f68319 129 ssize_t n = semihost_write(_fh, (const unsigned char *)buffer, length, 0); // number of characters not written
AnnaBridge 167:e84263d55307 130 n = length - n; // number of characters written
AnnaBridge 167:e84263d55307 131 pos += n;
AnnaBridge 167:e84263d55307 132 unlock();
AnnaBridge 167:e84263d55307 133 return n;
AnnaBridge 167:e84263d55307 134 }
AnnaBridge 167:e84263d55307 135
AnnaBridge 187:0387e8f68319 136 ssize_t LocalFileHandle::read(void *buffer, size_t length)
AnnaBridge 187:0387e8f68319 137 {
AnnaBridge 167:e84263d55307 138 lock();
AnnaBridge 187:0387e8f68319 139 ssize_t n = semihost_read(_fh, (unsigned char *)buffer, length, 0); // number of characters not read
AnnaBridge 167:e84263d55307 140 n = length - n; // number of characters read
AnnaBridge 167:e84263d55307 141 pos += n;
AnnaBridge 167:e84263d55307 142 unlock();
AnnaBridge 167:e84263d55307 143 return n;
AnnaBridge 167:e84263d55307 144 }
AnnaBridge 167:e84263d55307 145
AnnaBridge 187:0387e8f68319 146 int LocalFileHandle::isatty()
AnnaBridge 187:0387e8f68319 147 {
AnnaBridge 167:e84263d55307 148 lock();
AnnaBridge 167:e84263d55307 149 int ret = semihost_istty(_fh);
AnnaBridge 167:e84263d55307 150 unlock();
AnnaBridge 167:e84263d55307 151 return ret;
AnnaBridge 167:e84263d55307 152 }
AnnaBridge 167:e84263d55307 153
AnnaBridge 187:0387e8f68319 154 off_t LocalFileHandle::seek(off_t position, int whence)
AnnaBridge 187:0387e8f68319 155 {
AnnaBridge 167:e84263d55307 156 lock();
AnnaBridge 167:e84263d55307 157 if (whence == SEEK_CUR) {
AnnaBridge 167:e84263d55307 158 position += pos;
AnnaBridge 167:e84263d55307 159 } else if (whence == SEEK_END) {
AnnaBridge 167:e84263d55307 160 position += semihost_flen(_fh);
AnnaBridge 167:e84263d55307 161 } /* otherwise SEEK_SET, so position is fine */
AnnaBridge 167:e84263d55307 162
AnnaBridge 167:e84263d55307 163 /* Always seems to return -1, so just ignore for now. */
AnnaBridge 167:e84263d55307 164 semihost_seek(_fh, position);
AnnaBridge 167:e84263d55307 165 pos = position;
AnnaBridge 167:e84263d55307 166 unlock();
AnnaBridge 167:e84263d55307 167 return position;
AnnaBridge 167:e84263d55307 168 }
AnnaBridge 167:e84263d55307 169
AnnaBridge 187:0387e8f68319 170 int LocalFileHandle::sync()
AnnaBridge 187:0387e8f68319 171 {
AnnaBridge 167:e84263d55307 172 lock();
AnnaBridge 167:e84263d55307 173 int ret = semihost_ensure(_fh);
AnnaBridge 167:e84263d55307 174 unlock();
AnnaBridge 167:e84263d55307 175 return ret;
AnnaBridge 167:e84263d55307 176 }
AnnaBridge 167:e84263d55307 177
AnnaBridge 187:0387e8f68319 178 off_t LocalFileHandle::size()
AnnaBridge 187:0387e8f68319 179 {
AnnaBridge 167:e84263d55307 180 lock();
AnnaBridge 167:e84263d55307 181 off_t off = semihost_flen(_fh);
AnnaBridge 167:e84263d55307 182 unlock();
AnnaBridge 167:e84263d55307 183 return off;
AnnaBridge 167:e84263d55307 184 }
AnnaBridge 167:e84263d55307 185
AnnaBridge 187:0387e8f68319 186 void LocalFileHandle::lock()
AnnaBridge 187:0387e8f68319 187 {
AnnaBridge 167:e84263d55307 188 _mutex.lock();
AnnaBridge 167:e84263d55307 189 }
AnnaBridge 167:e84263d55307 190
AnnaBridge 187:0387e8f68319 191 void LocalFileHandle::unlock()
AnnaBridge 187:0387e8f68319 192 {
AnnaBridge 167:e84263d55307 193 _mutex.unlock();
AnnaBridge 167:e84263d55307 194 }
AnnaBridge 167:e84263d55307 195
AnnaBridge 167:e84263d55307 196 class LocalDirHandle : public DirHandle {
AnnaBridge 167:e84263d55307 197
AnnaBridge 167:e84263d55307 198 public:
AnnaBridge 167:e84263d55307 199 XFINFO info;
AnnaBridge 167:e84263d55307 200
AnnaBridge 187:0387e8f68319 201 LocalDirHandle() : info()
AnnaBridge 187:0387e8f68319 202 {
AnnaBridge 167:e84263d55307 203 }
AnnaBridge 167:e84263d55307 204
AnnaBridge 187:0387e8f68319 205 virtual int close()
AnnaBridge 187:0387e8f68319 206 {
AnnaBridge 167:e84263d55307 207 // No lock can be used in destructor
AnnaBridge 167:e84263d55307 208 delete this;
AnnaBridge 167:e84263d55307 209 return 0;
AnnaBridge 167:e84263d55307 210 }
AnnaBridge 167:e84263d55307 211
AnnaBridge 187:0387e8f68319 212 virtual int read(struct dirent *ent)
AnnaBridge 187:0387e8f68319 213 {
AnnaBridge 167:e84263d55307 214 lock();
AnnaBridge 187:0387e8f68319 215 if (xffind("*", &info) != 0) {
AnnaBridge 167:e84263d55307 216 unlock();
AnnaBridge 167:e84263d55307 217 return 0;
AnnaBridge 167:e84263d55307 218 }
AnnaBridge 167:e84263d55307 219 memcpy(ent->d_name, info.name, sizeof(info.name));
AnnaBridge 167:e84263d55307 220 unlock();
AnnaBridge 167:e84263d55307 221 return 1;
AnnaBridge 167:e84263d55307 222 }
AnnaBridge 167:e84263d55307 223
AnnaBridge 187:0387e8f68319 224 virtual void rewind()
AnnaBridge 187:0387e8f68319 225 {
AnnaBridge 167:e84263d55307 226 lock();
AnnaBridge 167:e84263d55307 227 info.fileID = 0;
AnnaBridge 167:e84263d55307 228 unlock();
AnnaBridge 167:e84263d55307 229 }
AnnaBridge 167:e84263d55307 230
AnnaBridge 187:0387e8f68319 231 virtual off_t tell()
AnnaBridge 187:0387e8f68319 232 {
AnnaBridge 167:e84263d55307 233 lock();
AnnaBridge 167:e84263d55307 234 int fileId = info.fileID;
AnnaBridge 167:e84263d55307 235 unlock();
AnnaBridge 167:e84263d55307 236 return fileId;
AnnaBridge 167:e84263d55307 237 }
AnnaBridge 167:e84263d55307 238
AnnaBridge 187:0387e8f68319 239 virtual void seek(off_t offset)
AnnaBridge 187:0387e8f68319 240 {
AnnaBridge 167:e84263d55307 241 lock();
AnnaBridge 167:e84263d55307 242 info.fileID = offset;
AnnaBridge 167:e84263d55307 243 unlock();
AnnaBridge 167:e84263d55307 244 }
AnnaBridge 167:e84263d55307 245
AnnaBridge 167:e84263d55307 246 protected:
AnnaBridge 167:e84263d55307 247 PlatformMutex _mutex;
AnnaBridge 167:e84263d55307 248
AnnaBridge 187:0387e8f68319 249 virtual void lock()
AnnaBridge 187:0387e8f68319 250 {
AnnaBridge 167:e84263d55307 251 _mutex.lock();
AnnaBridge 167:e84263d55307 252 }
AnnaBridge 167:e84263d55307 253
AnnaBridge 187:0387e8f68319 254 virtual void unlock()
AnnaBridge 187:0387e8f68319 255 {
AnnaBridge 167:e84263d55307 256 _mutex.unlock();
AnnaBridge 167:e84263d55307 257 }
AnnaBridge 167:e84263d55307 258 };
AnnaBridge 167:e84263d55307 259
AnnaBridge 187:0387e8f68319 260 int LocalFileSystem::open(FileHandle **file, const char *name, int flags)
AnnaBridge 187:0387e8f68319 261 {
AnnaBridge 167:e84263d55307 262 // No global state modified so function is thread safe
AnnaBridge 167:e84263d55307 263
AnnaBridge 167:e84263d55307 264 /* reject filenames with / in them */
AnnaBridge 167:e84263d55307 265 for (const char *tmp = name; *tmp; tmp++) {
AnnaBridge 167:e84263d55307 266 if (*tmp == '/') {
AnnaBridge 167:e84263d55307 267 return -EINVAL;
AnnaBridge 167:e84263d55307 268 }
AnnaBridge 167:e84263d55307 269 }
AnnaBridge 167:e84263d55307 270
AnnaBridge 167:e84263d55307 271 int openmode = posix_to_semihost_open_flags(flags);
AnnaBridge 167:e84263d55307 272 if (openmode == OPEN_INVALID) {
AnnaBridge 167:e84263d55307 273 return -EINVAL;
AnnaBridge 167:e84263d55307 274 }
AnnaBridge 167:e84263d55307 275
AnnaBridge 167:e84263d55307 276 FILEHANDLE fh = semihost_open(name, openmode);
AnnaBridge 167:e84263d55307 277 if (fh == -1) {
AnnaBridge 167:e84263d55307 278 return -EIO;
AnnaBridge 167:e84263d55307 279 }
AnnaBridge 167:e84263d55307 280
AnnaBridge 167:e84263d55307 281 *file = new LocalFileHandle(fh);
AnnaBridge 167:e84263d55307 282 return 0;
AnnaBridge 167:e84263d55307 283 }
AnnaBridge 167:e84263d55307 284
AnnaBridge 187:0387e8f68319 285 int LocalFileSystem::remove(const char *filename)
AnnaBridge 187:0387e8f68319 286 {
AnnaBridge 167:e84263d55307 287 // No global state modified so function is thread safe
AnnaBridge 167:e84263d55307 288
AnnaBridge 167:e84263d55307 289 return semihost_remove(filename);
AnnaBridge 167:e84263d55307 290 }
AnnaBridge 167:e84263d55307 291
AnnaBridge 187:0387e8f68319 292 int LocalFileSystem::open(DirHandle **dir, const char *name)
AnnaBridge 187:0387e8f68319 293 {
AnnaBridge 167:e84263d55307 294 // No global state modified so function is thread safe
AnnaBridge 167:e84263d55307 295
AnnaBridge 167:e84263d55307 296 *dir = new LocalDirHandle();
AnnaBridge 167:e84263d55307 297 return 0;
AnnaBridge 167:e84263d55307 298 }
AnnaBridge 167:e84263d55307 299
AnnaBridge 167:e84263d55307 300 } // namespace mbed
AnnaBridge 167:e84263d55307 301
AnnaBridge 167:e84263d55307 302 #endif