Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TUKS-COURSE-TIMER by
LocalFileSystem.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "drivers/LocalFileSystem.h" 00017 00018 #if DEVICE_LOCALFILESYSTEM 00019 00020 #include "platform/semihost_api.h" 00021 #include <string.h> 00022 #include <stdio.h> 00023 00024 namespace mbed { 00025 00026 /* Extension to FINFO type defined in RTL.h (in Keil RL) - adds 'create time'. */ 00027 typedef struct { 00028 unsigned char hr; /* Hours [0..23] */ 00029 unsigned char min; /* Minutes [0..59] */ 00030 unsigned char sec; /* Seconds [0..59] */ 00031 unsigned char day; /* Day [1..31] */ 00032 unsigned char mon; /* Month [1..12] */ 00033 unsigned short year; /* Year [1980..2107] */ 00034 } FTIME; 00035 00036 typedef struct { /* File Search info record */ 00037 char name[32]; /* File name */ 00038 long size; /* File size in bytes */ 00039 int fileID; /* System File Identification */ 00040 FTIME create_time; /* Date & time file was created */ 00041 FTIME write_time; /* Date & time of last write */ 00042 } XFINFO; 00043 00044 #define RESERVED_FOR_USER_APPLICATIONS (0x100) /* 0x100 - 0x1ff */ 00045 #define USR_XFFIND (RESERVED_FOR_USER_APPLICATIONS + 0) 00046 00047 static int xffind (const char *pattern, XFINFO *info) { 00048 unsigned param[4]; 00049 00050 param[0] = (unsigned long)pattern; 00051 param[1] = (unsigned long)strlen(pattern); 00052 param[2] = (unsigned long)info; 00053 param[3] = (unsigned long)sizeof(XFINFO); 00054 00055 return __semihost(USR_XFFIND, param); 00056 } 00057 00058 #define OPEN_R 0 00059 #define OPEN_B 1 00060 #define OPEN_PLUS 2 00061 #define OPEN_W 4 00062 #define OPEN_A 8 00063 #define OPEN_INVALID -1 00064 00065 int posix_to_semihost_open_flags(int flags) { 00066 /* POSIX flags -> semihosting open mode */ 00067 int openmode; 00068 if (flags & O_RDWR) { 00069 /* a plus mode */ 00070 openmode = OPEN_PLUS; 00071 if (flags & O_APPEND) { 00072 openmode |= OPEN_A; 00073 } else if (flags & O_TRUNC) { 00074 openmode |= OPEN_W; 00075 } else { 00076 openmode |= OPEN_R; 00077 } 00078 } else if (flags & O_WRONLY) { 00079 /* write or append */ 00080 if (flags & O_APPEND) { 00081 openmode = OPEN_A; 00082 } else { 00083 openmode = OPEN_W; 00084 } 00085 } else if (flags == O_RDONLY) { 00086 /* read mode */ 00087 openmode = OPEN_R; 00088 } else { 00089 /* invalid flags */ 00090 openmode = OPEN_INVALID; 00091 } 00092 00093 return openmode; 00094 } 00095 00096 FILEHANDLE local_file_open(const char* name, int flags) { 00097 int openmode = posix_to_semihost_open_flags(flags); 00098 if (openmode == OPEN_INVALID) { 00099 return (FILEHANDLE)NULL; 00100 } 00101 00102 FILEHANDLE fh = semihost_open(name, openmode); 00103 if (fh == -1) { 00104 return (FILEHANDLE)NULL; 00105 } 00106 00107 return fh; 00108 } 00109 00110 LocalFileHandle::LocalFileHandle(FILEHANDLE fh) : _fh(fh), pos(0) { 00111 // No lock needed in constructor 00112 } 00113 00114 int LocalFileHandle::close() { 00115 int retval = semihost_close(_fh); 00116 delete this; 00117 return retval; 00118 } 00119 00120 ssize_t LocalFileHandle::write(const void *buffer, size_t length) { 00121 lock(); 00122 ssize_t n = semihost_write(_fh, (const unsigned char*)buffer, length, 0); // number of characters not written 00123 n = length - n; // number of characters written 00124 pos += n; 00125 unlock(); 00126 return n; 00127 } 00128 00129 ssize_t LocalFileHandle::read(void *buffer, size_t length) { 00130 lock(); 00131 ssize_t n = semihost_read(_fh, (unsigned char*)buffer, length, 0); // number of characters not read 00132 n = length - n; // number of characters read 00133 pos += n; 00134 unlock(); 00135 return n; 00136 } 00137 00138 int LocalFileHandle::isatty() { 00139 lock(); 00140 int ret = semihost_istty(_fh); 00141 unlock(); 00142 return ret; 00143 } 00144 00145 off_t LocalFileHandle::lseek(off_t position, int whence) { 00146 lock(); 00147 if (whence == SEEK_CUR) { 00148 position += pos; 00149 } else if (whence == SEEK_END) { 00150 position += semihost_flen(_fh); 00151 } /* otherwise SEEK_SET, so position is fine */ 00152 00153 /* Always seems to return -1, so just ignore for now. */ 00154 semihost_seek(_fh, position); 00155 pos = position; 00156 unlock(); 00157 return position; 00158 } 00159 00160 int LocalFileHandle::fsync() { 00161 lock(); 00162 int ret = semihost_ensure(_fh); 00163 unlock(); 00164 return ret; 00165 } 00166 00167 off_t LocalFileHandle::flen() { 00168 lock(); 00169 off_t off = semihost_flen(_fh); 00170 unlock(); 00171 return off; 00172 } 00173 00174 void LocalFileHandle::lock() { 00175 _mutex.lock(); 00176 } 00177 00178 void LocalFileHandle::unlock() { 00179 _mutex.unlock(); 00180 } 00181 00182 class LocalDirHandle : public DirHandle { 00183 00184 public: 00185 struct dirent cur_entry; 00186 XFINFO info; 00187 00188 LocalDirHandle() : cur_entry(), info() { 00189 } 00190 00191 virtual int closedir() { 00192 // No lock can be used in destructor 00193 delete this; 00194 return 0; 00195 } 00196 00197 virtual struct dirent *readdir() { 00198 lock(); 00199 if (xffind("*", &info)!=0) { 00200 unlock(); 00201 return NULL; 00202 } 00203 memcpy(cur_entry.d_name, info.name, sizeof(info.name)); 00204 unlock(); 00205 return &cur_entry; 00206 } 00207 00208 virtual void rewinddir() { 00209 lock(); 00210 info.fileID = 0; 00211 unlock(); 00212 } 00213 00214 virtual off_t telldir() { 00215 lock(); 00216 int fileId = info.fileID; 00217 unlock(); 00218 return fileId; 00219 } 00220 00221 virtual void seekdir(off_t offset) { 00222 lock(); 00223 info.fileID = offset; 00224 unlock(); 00225 } 00226 00227 protected: 00228 PlatformMutex _mutex; 00229 00230 virtual void lock() { 00231 _mutex.lock(); 00232 } 00233 00234 virtual void unlock() { 00235 _mutex.unlock(); 00236 } 00237 }; 00238 00239 FileHandle *LocalFileSystem::open(const char* name, int flags) { 00240 // No global state modified so function is thread safe 00241 00242 /* reject filenames with / in them */ 00243 for (const char *tmp = name; *tmp; tmp++) { 00244 if (*tmp == '/') { 00245 return NULL; 00246 } 00247 } 00248 00249 int openmode = posix_to_semihost_open_flags(flags); 00250 if (openmode == OPEN_INVALID) { 00251 return NULL; 00252 } 00253 00254 FILEHANDLE fh = semihost_open(name, openmode); 00255 if (fh == -1) { 00256 return NULL; 00257 } 00258 return new LocalFileHandle(fh); 00259 } 00260 00261 int LocalFileSystem::remove(const char *filename) { 00262 // No global state modified so function is thread safe 00263 00264 return semihost_remove(filename); 00265 } 00266 00267 DirHandle *LocalFileSystem::opendir(const char *name) { 00268 // No global state modified so function is thread safe 00269 00270 return new LocalDirHandle(); 00271 } 00272 00273 } // namespace mbed 00274 00275 #endif
Generated on Tue Jul 12 2022 17:38:48 by
