mbed.h library with any bug fixes AV finds.

Dependents:   micromouse4_encoder_testing PID_Test Lab1_Test WorkingPID ... more

Committer:
aravindsv
Date:
Mon Nov 02 02:26:59 2015 +0000
Revision:
0:ba7650f404af
Reduced HSE_STARTUP_TIMEOUT to 500 ms, fixed some compiler warnings

Who changed what in which revision?

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