customized mbed library sources for nrf51822

Dependents:   Grove_Node Potentiometer BLE_Beacon I2C_Scanner

Committer:
yihui
Date:
Tue Nov 04 07:38:53 2014 +0000
Revision:
0:700cadd8b708
customized mbed-src library for nrf51822

Who changed what in which revision?

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