User | Revision | Line number | New contents of line |
sinrab |
0:5464d5e415e5
|
1
|
/* mbed Microcontroller Library
|
sinrab |
0:5464d5e415e5
|
2
|
* Copyright (c) 2006-2012 ARM Limited
|
sinrab |
0:5464d5e415e5
|
3
|
*
|
sinrab |
0:5464d5e415e5
|
4
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
sinrab |
0:5464d5e415e5
|
5
|
* of this software and associated documentation files (the "Software"), to deal
|
sinrab |
0:5464d5e415e5
|
6
|
* in the Software without restriction, including without limitation the rights
|
sinrab |
0:5464d5e415e5
|
7
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
sinrab |
0:5464d5e415e5
|
8
|
* copies of the Software, and to permit persons to whom the Software is
|
sinrab |
0:5464d5e415e5
|
9
|
* furnished to do so, subject to the following conditions:
|
sinrab |
0:5464d5e415e5
|
10
|
*
|
sinrab |
0:5464d5e415e5
|
11
|
* The above copyright notice and this permission notice shall be included in
|
sinrab |
0:5464d5e415e5
|
12
|
* all copies or substantial portions of the Software.
|
sinrab |
0:5464d5e415e5
|
13
|
*
|
sinrab |
0:5464d5e415e5
|
14
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
sinrab |
0:5464d5e415e5
|
15
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
sinrab |
0:5464d5e415e5
|
16
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
sinrab |
0:5464d5e415e5
|
17
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
sinrab |
0:5464d5e415e5
|
18
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
sinrab |
0:5464d5e415e5
|
19
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
sinrab |
0:5464d5e415e5
|
20
|
* SOFTWARE.
|
sinrab |
0:5464d5e415e5
|
21
|
*/
|
sinrab |
0:5464d5e415e5
|
22
|
#include "mbed.h"
|
sinrab |
0:5464d5e415e5
|
23
|
|
sinrab |
0:5464d5e415e5
|
24
|
#include "ffconf.h"
|
sinrab |
0:5464d5e415e5
|
25
|
#include "mbed_debug.h"
|
sinrab |
0:5464d5e415e5
|
26
|
|
sinrab |
0:5464d5e415e5
|
27
|
#include "FATFileSystem.h"
|
sinrab |
0:5464d5e415e5
|
28
|
#include "FATFileHandle.h"
|
sinrab |
0:5464d5e415e5
|
29
|
#include "FATDirHandle.h"
|
sinrab |
0:5464d5e415e5
|
30
|
|
sinrab |
0:5464d5e415e5
|
31
|
DWORD get_fattime(void) {
|
sinrab |
0:5464d5e415e5
|
32
|
time_t rawtime;
|
sinrab |
0:5464d5e415e5
|
33
|
time(&rawtime);
|
sinrab |
0:5464d5e415e5
|
34
|
struct tm *ptm = localtime(&rawtime);
|
sinrab |
0:5464d5e415e5
|
35
|
return (DWORD)(ptm->tm_year - 80) << 25
|
sinrab |
0:5464d5e415e5
|
36
|
| (DWORD)(ptm->tm_mon + 1 ) << 21
|
sinrab |
0:5464d5e415e5
|
37
|
| (DWORD)(ptm->tm_mday ) << 16
|
sinrab |
0:5464d5e415e5
|
38
|
| (DWORD)(ptm->tm_hour ) << 11
|
sinrab |
0:5464d5e415e5
|
39
|
| (DWORD)(ptm->tm_min ) << 5
|
sinrab |
0:5464d5e415e5
|
40
|
| (DWORD)(ptm->tm_sec/2 );
|
sinrab |
0:5464d5e415e5
|
41
|
}
|
sinrab |
0:5464d5e415e5
|
42
|
|
sinrab |
0:5464d5e415e5
|
43
|
FATFileSystem *FATFileSystem::_ffs[_VOLUMES] = {0};
|
sinrab |
0:5464d5e415e5
|
44
|
|
sinrab |
0:5464d5e415e5
|
45
|
FATFileSystem::FATFileSystem(const char* n) : FileSystemLike(n) {
|
sinrab |
0:5464d5e415e5
|
46
|
debug_if(FFS_DBG, "FATFileSystem(%s)\n", n);
|
sinrab |
0:5464d5e415e5
|
47
|
for(int i=0; i<_VOLUMES; i++) {
|
sinrab |
0:5464d5e415e5
|
48
|
if(_ffs[i] == 0) {
|
sinrab |
0:5464d5e415e5
|
49
|
_ffs[i] = this;
|
sinrab |
0:5464d5e415e5
|
50
|
_fsid = i;
|
sinrab |
0:5464d5e415e5
|
51
|
debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%d]\n", _name, _fsid);
|
sinrab |
0:5464d5e415e5
|
52
|
f_mount(i, &_fs);
|
sinrab |
0:5464d5e415e5
|
53
|
return;
|
sinrab |
0:5464d5e415e5
|
54
|
}
|
sinrab |
0:5464d5e415e5
|
55
|
}
|
sinrab |
0:5464d5e415e5
|
56
|
error("Couldn't create %s in FATFileSystem::FATFileSystem\n", n);
|
sinrab |
0:5464d5e415e5
|
57
|
}
|
sinrab |
0:5464d5e415e5
|
58
|
|
sinrab |
0:5464d5e415e5
|
59
|
FATFileSystem::~FATFileSystem() {
|
sinrab |
0:5464d5e415e5
|
60
|
for (int i=0; i<_VOLUMES; i++) {
|
sinrab |
0:5464d5e415e5
|
61
|
if (_ffs[i] == this) {
|
sinrab |
0:5464d5e415e5
|
62
|
_ffs[i] = 0;
|
sinrab |
0:5464d5e415e5
|
63
|
f_mount(i, NULL);
|
sinrab |
0:5464d5e415e5
|
64
|
}
|
sinrab |
0:5464d5e415e5
|
65
|
}
|
sinrab |
0:5464d5e415e5
|
66
|
}
|
sinrab |
0:5464d5e415e5
|
67
|
|
sinrab |
0:5464d5e415e5
|
68
|
FileHandle *FATFileSystem::open(const char* name, int flags) {
|
sinrab |
0:5464d5e415e5
|
69
|
debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%d]\n", name, _name, _fsid);
|
sinrab |
0:5464d5e415e5
|
70
|
char n[64];
|
sinrab |
0:5464d5e415e5
|
71
|
sprintf(n, "%d:/%s", _fsid, name);
|
sinrab |
0:5464d5e415e5
|
72
|
|
sinrab |
0:5464d5e415e5
|
73
|
/* POSIX flags -> FatFS open mode */
|
sinrab |
0:5464d5e415e5
|
74
|
BYTE openmode;
|
sinrab |
0:5464d5e415e5
|
75
|
if (flags & O_RDWR) {
|
sinrab |
0:5464d5e415e5
|
76
|
openmode = FA_READ|FA_WRITE;
|
sinrab |
0:5464d5e415e5
|
77
|
} else if(flags & O_WRONLY) {
|
sinrab |
0:5464d5e415e5
|
78
|
openmode = FA_WRITE;
|
sinrab |
0:5464d5e415e5
|
79
|
} else {
|
sinrab |
0:5464d5e415e5
|
80
|
openmode = FA_READ;
|
sinrab |
0:5464d5e415e5
|
81
|
}
|
sinrab |
0:5464d5e415e5
|
82
|
if(flags & O_CREAT) {
|
sinrab |
0:5464d5e415e5
|
83
|
if(flags & O_TRUNC) {
|
sinrab |
0:5464d5e415e5
|
84
|
openmode |= FA_CREATE_ALWAYS;
|
sinrab |
0:5464d5e415e5
|
85
|
} else {
|
sinrab |
0:5464d5e415e5
|
86
|
openmode |= FA_OPEN_ALWAYS;
|
sinrab |
0:5464d5e415e5
|
87
|
}
|
sinrab |
0:5464d5e415e5
|
88
|
}
|
sinrab |
0:5464d5e415e5
|
89
|
|
sinrab |
0:5464d5e415e5
|
90
|
FIL fh;
|
sinrab |
0:5464d5e415e5
|
91
|
FRESULT res = f_open(&fh, n, openmode);
|
sinrab |
0:5464d5e415e5
|
92
|
if (res) {
|
sinrab |
0:5464d5e415e5
|
93
|
debug_if(FFS_DBG, "f_open('w') failed: %d\n", res);
|
sinrab |
0:5464d5e415e5
|
94
|
return NULL;
|
sinrab |
0:5464d5e415e5
|
95
|
}
|
sinrab |
0:5464d5e415e5
|
96
|
if (flags & O_APPEND) {
|
sinrab |
0:5464d5e415e5
|
97
|
f_lseek(&fh, fh.fsize);
|
sinrab |
0:5464d5e415e5
|
98
|
}
|
sinrab |
0:5464d5e415e5
|
99
|
return new FATFileHandle(fh);
|
sinrab |
0:5464d5e415e5
|
100
|
}
|
sinrab |
0:5464d5e415e5
|
101
|
|
sinrab |
0:5464d5e415e5
|
102
|
int FATFileSystem::stat(const char * name, FILINFO * info)
|
sinrab |
0:5464d5e415e5
|
103
|
{
|
sinrab |
0:5464d5e415e5
|
104
|
char n[64];
|
sinrab |
0:5464d5e415e5
|
105
|
sprintf(n, "%d:/%s", _fsid, name);
|
sinrab |
0:5464d5e415e5
|
106
|
|
sinrab |
0:5464d5e415e5
|
107
|
FRESULT res = f_stat(n, info);
|
sinrab |
0:5464d5e415e5
|
108
|
if (res)
|
sinrab |
0:5464d5e415e5
|
109
|
{
|
sinrab |
0:5464d5e415e5
|
110
|
debug_if(FFS_DBG, "f_stat() failed: %d\n", res);
|
sinrab |
0:5464d5e415e5
|
111
|
return -1;
|
sinrab |
0:5464d5e415e5
|
112
|
}
|
sinrab |
0:5464d5e415e5
|
113
|
|
sinrab |
0:5464d5e415e5
|
114
|
return 0;
|
sinrab |
0:5464d5e415e5
|
115
|
}
|
sinrab |
0:5464d5e415e5
|
116
|
|
sinrab |
0:5464d5e415e5
|
117
|
int FATFileSystem::remove(const char *filename) {
|
sinrab |
0:5464d5e415e5
|
118
|
FRESULT res = f_unlink(filename);
|
sinrab |
0:5464d5e415e5
|
119
|
if (res) {
|
sinrab |
0:5464d5e415e5
|
120
|
debug_if(FFS_DBG, "f_unlink() failed: %d\n", res);
|
sinrab |
0:5464d5e415e5
|
121
|
return -1;
|
sinrab |
0:5464d5e415e5
|
122
|
}
|
sinrab |
0:5464d5e415e5
|
123
|
return 0;
|
sinrab |
0:5464d5e415e5
|
124
|
}
|
sinrab |
0:5464d5e415e5
|
125
|
|
sinrab |
0:5464d5e415e5
|
126
|
int FATFileSystem::format() {
|
sinrab |
0:5464d5e415e5
|
127
|
FRESULT res = f_mkfs(_fsid, 0, 512); // Logical drive number, Partitioning rule, Allocation unit size (bytes per cluster)
|
sinrab |
0:5464d5e415e5
|
128
|
if (res) {
|
sinrab |
0:5464d5e415e5
|
129
|
debug_if(FFS_DBG, "f_mkfs() failed: %d\n", res);
|
sinrab |
0:5464d5e415e5
|
130
|
return -1;
|
sinrab |
0:5464d5e415e5
|
131
|
}
|
sinrab |
0:5464d5e415e5
|
132
|
return 0;
|
sinrab |
0:5464d5e415e5
|
133
|
}
|
sinrab |
0:5464d5e415e5
|
134
|
|
sinrab |
0:5464d5e415e5
|
135
|
DirHandle *FATFileSystem::opendir(const char *name) {
|
sinrab |
0:5464d5e415e5
|
136
|
FATFS_DIR dir;
|
sinrab |
0:5464d5e415e5
|
137
|
FRESULT res = f_opendir(&dir, name);
|
sinrab |
0:5464d5e415e5
|
138
|
if (res != 0) {
|
sinrab |
0:5464d5e415e5
|
139
|
return NULL;
|
sinrab |
0:5464d5e415e5
|
140
|
}
|
sinrab |
0:5464d5e415e5
|
141
|
return new FATDirHandle(dir);
|
sinrab |
0:5464d5e415e5
|
142
|
}
|
sinrab |
0:5464d5e415e5
|
143
|
|
sinrab |
0:5464d5e415e5
|
144
|
int FATFileSystem::mkdir(const char *name, mode_t mode) {
|
sinrab |
0:5464d5e415e5
|
145
|
FRESULT res = f_mkdir(name);
|
sinrab |
0:5464d5e415e5
|
146
|
return res == 0 ? 0 : -1;
|
sinrab |
0:5464d5e415e5
|
147
|
}
|
sinrab |
0:5464d5e415e5
|
148
|
|