Nothing Special / mbed-STM32F103C8

Fork of mbed-STM32F103C8_org by Nothing Special

Committer:
mega64
Date:
Thu Mar 16 06:15:53 2017 +0000
Revision:
146:03e976389d16
fully rebuild, now based on mbed-dev v160

Who changed what in which revision?

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