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