uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
semifs.c
Go to the documentation of this file.
1 /* Copyright (c) 2010 James Snyder, eLua Project.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the right
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21 
22 #include <string.h>
23 #include <errno.h>
24 #include <stdint.h>
25 #ifdef USE_NEWLIB
26 #include <fcntl.h>
27 #endif
28 
29 #include <angel.h>
30 
31 #include "filesystem.h"
32 #include "fio.h"
33 #include "semifs.h"
34 #include "osdebug.h"
35 
36 struct semifs_fds_t {
37  uint32_t file;
38  uint32_t cursor;
39 };
40 
41 static struct semifs_fds_t semifs_fds[MAX_FDS];
42 
43 // These structures provided by Simon Ford of mbed
44 struct semifs_FTime {
45  uint8_t hr; // Hours [0..23]
46  uint8_t min; // Minutes [0..59]
47  uint8_t sec; // Seconds [0..59]
48  uint8_t day; // Day [1..31]
49  uint8_t mon; // Month [1..12]
50  uint16_t year; // Year [1980..2107]
51 };
52 
53 // File Search info record
55  char name[32]; // File - 32-bytes
56  uint32_t size; // File size in bytes - 4-bytes
57  uint16_t fileID; // System File Identification - 2-bytes
58  struct semifs_FTime create_time; // Date & time file was created
59  struct semifs_FTime write_time; // Date & time of last write
60 };
61 
63  const char *pattern;
65 };
66 
67 /*****************************************************************************/
68 
69 static int semifs_close(void * opaque) {
70  struct semifs_fds_t * f = (struct semifs_fds_t *) opaque;
71 // DBGOUT("semifs_close(%p)\r\n", opaque);
72 
73  return Semihost_SYS_CLOSE(&f->file);
74 }
75 
76 static ssize_t semifs_write(void * opaque, const void * ptr, size_t len) {
77  struct semifs_fds_t * f = (struct semifs_fds_t *) opaque;
78 // DBGOUT("semifs_write(%p, %p, %i)\r\n", opaque, ptr, len);
79 
80  uint32_t args[3];
81  args[0] = (uint32_t) f->file;
82  args[1] = (uint32_t) ptr;
83  args[2] = (uint32_t) len;
84 
85  // Perform write
86  int res = Semihost_SYS_WRITE(args);
87 // DBGOUT("semifs_read: Semihost_SYS_WRITE returned %i\r\n", res);
88  if (res == -1 || res == len)
89  return -1;
90 
91  // Update position
92  f->cursor += len - res;
93  return len - res;
94 }
95 
96 static ssize_t semifs_read(void * opaque, void * ptr, size_t len) {
97  struct semifs_fds_t * f = (struct semifs_fds_t *) opaque;
98 // DBGOUT("semifs_read(%p, %p, %i)\r\n", opaque, ptr, len);
99 
100  uint32_t args[3];
101  args[0] = (uint32_t) f->file;
102  args[1] = (uint32_t) ptr;
103  args[2] = (uint32_t) len;
104 
105  // Perform read
106  int res = Semihost_SYS_READ(args);
107 // DBGOUT("semifs_read: Semihost_SYS_READ returned %i\r\n", res);
108  if (res < 0)
109  return -1;
110 
111  // Update position
112  f->cursor += len - res;
113  return len - res;
114 }
115 
116 static off_t semifs_seek(void * opaque, off_t off, int whence) {
117  uint32_t args[2], len;
118  struct semifs_fds_t * f = (struct semifs_fds_t *) opaque;
119 // DBGOUT("semifs_seek(%p, %i, %i)\r\n", opaque, off, whence);
120 
121  switch (whence) {
122  case SEEK_CUR:
123  // seek from current position
124  off += f->cursor;
125  whence = SEEK_SET;
126  break;
127 
128  case SEEK_END:
129  // seek from end of file
130  args[0] = (uint32_t) f->file;
131  len = Semihost_SYS_FLEN(args);
132 // DBGOUT("semifs_seek: Semihost_SYS_FLEN returned %i\r\n", len);
133  off += len;
134  break;
135  }
136  // Do absolute seek
137  args[0] = (uint32_t) f->file;
138  args[1] = (uint32_t) off;
139  int res = Semihost_SYS_SEEK(args);
140 // DBGOUT("semifs_seek: Semihost_SYS_SEEK returned %i\r\n", res);
141 
142  if (res == 0)
143  f->cursor = off;
144 
145  /* This is expected to return the position in the file. */
146  return res == 0 ? off : -1;
147 }
148 
149 static int semifs_open(void * opaque, const char *path, int flags, int mode) {
150  int aflags = 0;
151  unsigned int fh;
152  uint32_t args[3];
153 // DBGOUT("semifs_open(%p, \"%s\", %i, %i)\r\n");
154 
155  if (flags & O_RDWR)
156  aflags |= 2;
157 
158  if (flags & O_CREAT)
159  aflags |= 4;
160 
161  if (flags & O_TRUNC)
162  aflags |= 4;
163 
164  if (flags & O_APPEND) {
165  aflags &= ~4; // Can't ask for w AND a; means just 'a'.
166  aflags |= 8;
167  }
168 
169  // Find file and open it (via semihosting call)
170  args[0] = (uint32_t) path;
171  args[1] = (uint32_t) aflags;
172  args[2] = (uint32_t) strlen(path);
173  fh = Semihost_SYS_OPEN(args);
174 // DBGOUT("Semihost_SYS_OPEN returns: %i\r\n", fh);
175 
176  if (fh >= 0) {
177  int fd = fio_open(semifs_read, semifs_write, semifs_seek, semifs_close, (void *) fh);
178 // DBGOUT("semifs_open: fio_open returned %i\r\n", fd);
179  if (fd < 0)
180  Semihost_SYS_CLOSE((uint32_t *) &fd);
181  semifs_fds[fd].file = fh;
182  semifs_fds[fd].cursor = 0;
183  fio_set_opaque(fd, semifs_fds + fd);
184  return fd;
185  }
186  return -1;
187 }
188 
190 // DBGOUT("Registering semihost fs\r\n");
191  register_fs("host", semifs_open, NULL);
192 }