Skip to content

Commit ad983ad

Browse files
authored
Refactor Filesystem into a interface (#455)
* refactor Filesystem into a interface and the interface is now implemented by platform specific Adapters
1 parent 84be46c commit ad983ad

36 files changed

+393
-311
lines changed

sources/Adapters/picoTracker/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ add_subdirectory(utils)
99
add_subdirectory(midi)
1010
add_subdirectory(platform)
1111
add_subdirectory(usb)
12+
add_subdirectory(filesystem)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
add_library(platform_filesystem
2+
picoTrackerFileSystem.h picoTrackerFileSystem.cpp
3+
)
4+
5+
target_link_libraries(platform_filesystem
6+
PUBLIC system_filesystem
7+
PUBLIC system_errors
8+
PUBLIC sdfat
9+
PUBLIC platform_sdcard
10+
PUBLIC etl
11+
pico_multicore
12+
)
13+
14+
target_include_directories(platform_filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
15+
16+
include_directories(${PROJECT_SOURCE_DIR})

sources/System/FileSystem/PicoFileSystem.cpp renamed to sources/Adapters/picoTracker/filesystem/picoTrackerFileSystem.cpp

+47-68
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
#include "PicoFileSystem.h"
1+
#include "picoTrackerFileSystem.h"
22

33
#include "pico/multicore.h"
44

5+
// Global mutex for thread safety
56
Mutex mutex;
67

7-
PicoFileSystem::PicoFileSystem() {
8+
picoTrackerFileSystem::picoTrackerFileSystem() {
89
// init out access mutex
910
std::lock_guard<Mutex> lock(mutex);
1011

@@ -21,13 +22,13 @@ PicoFileSystem::PicoFileSystem() {
2122
}
2223
// Try to mount the whole card as FAT (without partition table)
2324
if (static_cast<FsVolume *>(&sd)->begin(sd.card(), true, 0)) {
24-
Trace::Log("PICOFILESYSTEM",
25+
Trace::Log("FILESYSTEM",
2526
"Mounted SD Card FAT Filesystem without partition table");
2627
return;
2728
}
2829
}
2930

30-
PI_File *PicoFileSystem::Open(const char *name, const char *mode) {
31+
I_File *picoTrackerFileSystem::Open(const char *name, const char *mode) {
3132
Trace::Log("FILESYSTEM", "Open file:%s, mode:%s", name, mode);
3233
std::lock_guard<Mutex> lock(mutex);
3334
oflag_t rmode;
@@ -47,17 +48,17 @@ PI_File *PicoFileSystem::Open(const char *name, const char *mode) {
4748
if (!cwd.openCwd()) {
4849
return nullptr;
4950
}
50-
PI_File *wFile = 0;
51+
I_File *wFile = 0;
5152
if (cwd.open(name, rmode)) {
52-
wFile = new PI_File(cwd);
53+
wFile = new picoTrackerFile(cwd);
5354
} else {
5455
Trace::Error("FILESYSTEM: Cannot open file:%s", name, mode);
5556
}
5657
return wFile;
5758
}
5859

59-
bool PicoFileSystem::chdir(const char *name) {
60-
Trace::Log("PICOFILESYSTEM", "chdir:%s", name);
60+
bool picoTrackerFileSystem::chdir(const char *name) {
61+
Trace::Log("FILESYSTEM", "chdir:%s", name);
6162
std::lock_guard<Mutex> lock(mutex);
6263

6364
sd.chvol();
@@ -66,12 +67,12 @@ bool PicoFileSystem::chdir(const char *name) {
6667
char buf[PFILENAME_SIZE];
6768
cwd.openCwd();
6869
cwd.getName(buf, 128);
69-
Trace::Log("PICOFILESYSTEM", "new CWD:%s\n", buf);
70+
Trace::Log("FILESYSTEM", "new CWD:%s\n", buf);
7071
cwd.close();
7172
return res;
7273
}
7374

74-
PicoFileType PicoFileSystem::getFileType(int index) {
75+
PicoFileType picoTrackerFileSystem::getFileType(int index) {
7576
std::lock_guard<Mutex> lock(mutex);
7677

7778
FsBaseFile cwd;
@@ -89,8 +90,8 @@ PicoFileType PicoFileSystem::getFileType(int index) {
8990
return isDir ? PFT_DIR : PFT_FILE;
9091
}
9192

92-
void PicoFileSystem::list(etl::ivector<int> *fileIndexes, const char *filter,
93-
bool subDirOnly) {
93+
void picoTrackerFileSystem::list(etl::ivector<int> *fileIndexes,
94+
const char *filter, bool subDirOnly) {
9495
std::lock_guard<Mutex> lock(mutex);
9596

9697
fileIndexes->clear();
@@ -104,7 +105,7 @@ void PicoFileSystem::list(etl::ivector<int> *fileIndexes, const char *filter,
104105
}
105106
char buffer[PFILENAME_SIZE];
106107
cwd.getName(buffer, PFILENAME_SIZE);
107-
Trace::Log("PICOFILESYSTEM", "LIST DIR:%s", buffer);
108+
Trace::Log("FILESYSTEM", "LIST DIR:%s", buffer);
108109

109110
if (!cwd.isDir()) {
110111
Trace::Error("Path is not a directory");
@@ -123,7 +124,7 @@ void PicoFileSystem::list(etl::ivector<int> *fileIndexes, const char *filter,
123124
if (strlen(filter) > 0) {
124125
tolowercase(buffer);
125126
matchesFilter = (strstr(buffer, filter) != nullptr);
126-
Trace::Log("PICOFILESYSTEM", "FILTER: %s=%s [%d]\n", buffer, filter,
127+
Trace::Log("FILESYSTEM", "FILTER: %s=%s [%d]\n", buffer, filter,
127128
matchesFilter);
128129
}
129130
// filter out "." and files that dont match filter if a filter is given
@@ -136,41 +137,39 @@ void PicoFileSystem::list(etl::ivector<int> *fileIndexes, const char *filter,
136137
} else {
137138
fileIndexes->push_back(index);
138139
}
139-
Trace::Log("PICOFILESYSTEM", "[%d] got file: %s", index, buffer);
140+
Trace::Log("FILESYSTEM", "[%d] got file: %s", index, buffer);
140141
count++;
141142
} else {
142-
Trace::Log("PICOFILESYSTEM", "skipped hidden: %s", buffer);
143+
Trace::Log("FILESYSTEM", "skipped hidden: %s", buffer);
143144
}
144145
entry.close();
145146
}
146147
cwd.close();
147-
Trace::Log("PICOFILESYSTEM", "scanned: %d, added file indexes:%d", count,
148+
Trace::Log("FILESYSTEM", "scanned: %d, added file indexes:%d", count,
148149
fileIndexes->size());
149150
}
150151

151-
void PicoFileSystem::getFileName(int index, char *name, int length) {
152+
void picoTrackerFileSystem::getFileName(int index, char *name, int length) {
152153
std::lock_guard<Mutex> lock(mutex);
153-
154-
FsFile cwd;
155-
char dirname[PFILENAME_SIZE];
154+
FsBaseFile cwd;
156155
if (!cwd.openCwd()) {
156+
char dirname[PFILENAME_SIZE];
157157
cwd.getName(dirname, PFILENAME_SIZE);
158158
Trace::Error("Failed to open cwd:%s", dirname);
159159
return;
160160
}
161-
FsFile entry;
161+
FsBaseFile entry;
162162
entry.open(index);
163163
entry.getName(name, length);
164164
entry.close();
165165
cwd.close();
166166
}
167167

168-
bool PicoFileSystem::isParentRoot() {
168+
bool picoTrackerFileSystem::isParentRoot() {
169169
std::lock_guard<Mutex> lock(mutex);
170-
171-
FsFile cwd;
172-
char dirname[PFILENAME_SIZE];
170+
FsBaseFile cwd;
173171
if (!cwd.openCwd()) {
172+
char dirname[PFILENAME_SIZE];
174173
cwd.getName(dirname, PFILENAME_SIZE);
175174
Trace::Error("Failed to open cwd:%s", dirname);
176175
return false;
@@ -189,37 +188,28 @@ bool PicoFileSystem::isParentRoot() {
189188
return result;
190189
}
191190

192-
bool PicoFileSystem::DeleteFile(const char *path) {
191+
bool picoTrackerFileSystem::DeleteFile(const char *path) {
193192
std::lock_guard<Mutex> lock(mutex);
194193
return sd.remove(path);
195194
}
196195

197-
// directory has to be empty
198-
bool PicoFileSystem::DeleteDir(const char *path) {
196+
bool picoTrackerFileSystem::DeleteDir(const char *path) {
199197
std::lock_guard<Mutex> lock(mutex);
200198
auto delDir = sd.open(path, O_READ);
201199
return delDir.rmdir();
202200
}
203201

204-
bool PicoFileSystem::exists(const char *path) {
202+
bool picoTrackerFileSystem::exists(const char *path) {
205203
std::lock_guard<Mutex> lock(mutex);
206204
return sd.exists(path);
207205
}
208206

209-
/**
210-
* Create a directory at the specified path.
211-
*
212-
* \param[in] path The path where the directory will be created.
213-
* \param[in] pFlag If true, create missing parent directories.
214-
*
215-
* \return true if the directory was successfully created, false otherwise.
216-
*/
217-
bool PicoFileSystem::makeDir(const char *path, bool pFlag) {
207+
bool picoTrackerFileSystem::makeDir(const char *path, bool pFlag) {
218208
std::lock_guard<Mutex> lock(mutex);
219209
return sd.mkdir(path, pFlag);
220210
}
221211

222-
uint64_t PicoFileSystem::getFileSize(const int index) {
212+
uint64_t picoTrackerFileSystem::getFileSize(const int index) {
223213
std::lock_guard<Mutex> lock(mutex);
224214
FsBaseFile cwd;
225215
FsBaseFile entry;
@@ -237,7 +227,8 @@ uint64_t PicoFileSystem::getFileSize(const int index) {
237227
return size;
238228
}
239229

240-
bool PicoFileSystem::CopyFile(const char *srcPath, const char *destPath) {
230+
bool picoTrackerFileSystem::CopyFile(const char *srcPath,
231+
const char *destPath) {
241232
std::lock_guard<Mutex> lock(mutex);
242233
auto fSrc = sd.open(srcPath, O_READ);
243234
auto fDest = sd.open(destPath, O_WRITE | O_CREAT);
@@ -262,37 +253,25 @@ bool PicoFileSystem::CopyFile(const char *srcPath, const char *destPath) {
262253
return true;
263254
}
264255

265-
void PicoFileSystem::tolowercase(char *temp) {
266-
// Convert to upper case
256+
void picoTrackerFileSystem::tolowercase(char *temp) {
257+
// Convert to lower case
267258
char *s = temp;
268259
while (*s != '\0') {
269260
*s = tolower((unsigned char)*s);
270261
s++;
271262
}
272263
}
273264

274-
PI_File::PI_File(FsBaseFile file) { file_ = file; };
275-
276-
/**
277-
* Read data from a file starting at the current position.
278-
*
279-
* \param[out] buf Pointer to the location that will receive the data.
280-
*
281-
* \param[in] size Maximum number of bytes to read.
282-
*
283-
* \return For success read() returns the number of bytes read.
284-
* A value less than \a count, including zero, will be returned
285-
* if end of file is reached.
286-
* If an error occurs, read() returns -1. Possible errors include
287-
* read() called before a file has been opened, corrupt file system
288-
* or an I/O error occurred.
289-
*/
290-
int PI_File::Read(void *ptr, int size) {
265+
// picoTrackerFile implementation
266+
267+
picoTrackerFile::picoTrackerFile(FsBaseFile file) { file_ = file; }
268+
269+
int picoTrackerFile::Read(void *ptr, int size) {
291270
std::lock_guard<Mutex> lock(mutex);
292271
return file_.read(ptr, size);
293272
}
294273

295-
void PI_File::Seek(long offset, int whence) {
274+
void picoTrackerFile::Seek(long offset, int whence) {
296275
std::lock_guard<Mutex> lock(mutex);
297276
switch (whence) {
298277
case SEEK_SET:
@@ -309,32 +288,32 @@ void PI_File::Seek(long offset, int whence) {
309288
}
310289
}
311290

312-
bool PI_File::DeleteFile() {
291+
bool picoTrackerFile::DeleteFile() {
313292
std::lock_guard<Mutex> lock(mutex);
314293
return file_.remove();
315294
}
316295

317-
int PI_File::GetC() {
296+
int picoTrackerFile::GetC() {
318297
std::lock_guard<Mutex> lock(mutex);
319298
return file_.read();
320299
}
321300

322-
int PI_File::Write(const void *ptr, int size, int nmemb) {
301+
int picoTrackerFile::Write(const void *ptr, int size, int nmemb) {
323302
std::lock_guard<Mutex> lock(mutex);
324303
return file_.write(ptr, size * nmemb);
325304
}
326305

327-
long PI_File::Tell() {
306+
long picoTrackerFile::Tell() {
328307
std::lock_guard<Mutex> lock(mutex);
329308
return file_.curPosition();
330309
}
331310

332-
int PI_File::Error() {
311+
int picoTrackerFile::Error() {
333312
std::lock_guard<Mutex> lock(mutex);
334313
return file_.getError();
335314
}
336315

337-
bool PI_File::Close() {
316+
bool picoTrackerFile::Close() {
338317
std::lock_guard<Mutex> lock(mutex);
339318
return file_.close();
340-
}
319+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#ifndef _PICOTRACKER_FILESYSTEM_H_
2+
#define _PICOTRACKER_FILESYSTEM_H_
3+
4+
#include "Adapters/picoTracker/sdcard/sdcard.h"
5+
#include "Externals/SdFat/src/SdFat.h"
6+
#include "System/Console/Trace.h"
7+
#include "System/FileSystem/FileSystem.h"
8+
#include "System/FileSystem/I_File.h"
9+
#include "pico/sync.h"
10+
#include <mutex>
11+
12+
// Forward declaration
13+
class picoTrackerFile;
14+
15+
// This is the concrete implementation of the FileSystem interface for
16+
// picoTracker
17+
class picoTrackerFileSystem : public FileSystem {
18+
public:
19+
picoTrackerFileSystem();
20+
virtual ~picoTrackerFileSystem() {}
21+
22+
// FileSystem interface implementation
23+
virtual I_File *Open(const char *name, const char *mode) override;
24+
virtual bool chdir(const char *path) override;
25+
virtual void list(etl::ivector<int> *fileIndexes, const char *filter,
26+
bool subDirOnly) override;
27+
virtual void getFileName(int index, char *name, int length) override;
28+
virtual PicoFileType getFileType(int index) override;
29+
virtual bool isParentRoot() override;
30+
virtual bool DeleteFile(const char *name) override;
31+
virtual bool DeleteDir(const char *name) override;
32+
virtual bool exists(const char *path) override;
33+
virtual bool makeDir(const char *path, bool pFlag = false) override;
34+
virtual uint64_t getFileSize(int index) override;
35+
virtual bool CopyFile(const char *src, const char *dest) override;
36+
37+
private:
38+
SdFs sd;
39+
void tolowercase(char *temp);
40+
// buffer needs to be allocated here as too big for allocation as local
41+
// variable on the stack
42+
uint8_t fileBuffer_[512];
43+
};
44+
45+
// Concrete implementation of PI_File for picoTracker
46+
class picoTrackerFile : public I_File {
47+
public:
48+
picoTrackerFile(FsBaseFile file);
49+
virtual ~picoTrackerFile() {}
50+
51+
// PI_File interface implementation
52+
virtual int Read(void *ptr, int size) override;
53+
virtual int GetC() override;
54+
virtual int Write(const void *ptr, int size, int nmemb) override;
55+
virtual void Seek(long offset, int whence) override;
56+
virtual long Tell() override;
57+
virtual bool Close() override;
58+
virtual bool DeleteFile() override;
59+
virtual int Error() override;
60+
61+
private:
62+
FsBaseFile file_;
63+
};
64+
65+
// Mutex implementation for thread safety
66+
struct Mutex {
67+
Mutex() { mutex_init(&mutex); }
68+
void lock() { mutex_enter_blocking(&mutex); }
69+
void unlock() { mutex_exit(&mutex); }
70+
Mutex(const Mutex &) = delete;
71+
Mutex &operator=(const Mutex &) = delete;
72+
73+
private:
74+
mutex_t mutex;
75+
};
76+
77+
#endif // _PICOTRACKER_FILESYSTEM_H_

0 commit comments

Comments
 (0)