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 mbed-src 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 "LocalFileSystem.h" 00017 00018 #if DEVICE_LOCALFILESYSTEM 00019 00020 #include "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) { 00111 _fh = fh; 00112 pos = 0; 00113 } 00114 00115 int LocalFileHandle::close() { 00116 int retval = semihost_close(_fh); 00117 delete this; 00118 return retval; 00119 } 00120 00121 ssize_t LocalFileHandle::write(const void *buffer, size_t length) { 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 return n; 00126 } 00127 00128 ssize_t LocalFileHandle::read(void *buffer, size_t length) { 00129 ssize_t n = semihost_read(_fh, (unsigned char*)buffer, length, 0); // number of characters not read 00130 n = length - n; // number of characters read 00131 pos += n; 00132 return n; 00133 } 00134 00135 int LocalFileHandle::isatty() { 00136 return semihost_istty(_fh); 00137 } 00138 00139 off_t LocalFileHandle::lseek(off_t position, int whence) { 00140 if (whence == SEEK_CUR) { 00141 position += pos; 00142 } else if (whence == SEEK_END) { 00143 position += semihost_flen(_fh); 00144 } /* otherwise SEEK_SET, so position is fine */ 00145 00146 /* Always seems to return -1, so just ignore for now. */ 00147 semihost_seek(_fh, position); 00148 pos = position; 00149 return position; 00150 } 00151 00152 int LocalFileHandle::fsync() { 00153 return semihost_ensure(_fh); 00154 } 00155 00156 off_t LocalFileHandle::flen() { 00157 return semihost_flen(_fh); 00158 } 00159 00160 class LocalDirHandle : public DirHandle { 00161 00162 public: 00163 struct dirent cur_entry; 00164 XFINFO info; 00165 00166 LocalDirHandle() { 00167 info.fileID = 0; 00168 } 00169 00170 virtual int closedir() { 00171 delete this; 00172 return 0; 00173 } 00174 00175 virtual struct dirent *readdir() { 00176 if (xffind("*", &info)!=0) { 00177 return NULL; 00178 } 00179 memcpy(cur_entry.d_name, info.name, sizeof(info.name)); 00180 return &cur_entry; 00181 } 00182 00183 virtual void rewinddir() { 00184 info.fileID = 0; 00185 } 00186 00187 virtual off_t telldir() { 00188 return info.fileID; 00189 } 00190 00191 virtual void seekdir(off_t offset) { 00192 info.fileID = offset; 00193 } 00194 }; 00195 00196 FileHandle *LocalFileSystem::open(const char* name, int flags) { 00197 /* reject filenames with / in them */ 00198 for (const char *tmp = name; *tmp; tmp++) { 00199 if (*tmp == '/') { 00200 return NULL; 00201 } 00202 } 00203 00204 int openmode = posix_to_semihost_open_flags(flags); 00205 if (openmode == OPEN_INVALID) { 00206 return NULL; 00207 } 00208 00209 FILEHANDLE fh = semihost_open(name, openmode); 00210 if (fh == -1) { 00211 return NULL; 00212 } 00213 return new LocalFileHandle(fh); 00214 } 00215 00216 int LocalFileSystem::remove(const char *filename) { 00217 return semihost_remove(filename); 00218 } 00219 00220 DirHandle *LocalFileSystem::opendir(const char *name) { 00221 return new LocalDirHandle(); 00222 } 00223 00224 } // namespace mbed 00225 00226 #endif
Generated on Tue Jul 12 2022 21:21:33 by
