Demo to read and write to both SD and USB File System
Example (more detailed example in the main.cpp file):
#include "mbed.h" #include "MSCFileSystem.h" #include "SDFileSystem.h" MSCFileSystem fs("fs"); SDFileSystem sd(p5, p6, p7, p8, "sd", p11, SDFileSystem::SWITCH_NEG_NO, 15000000); // CAUTION: Return values should ALWAYS be checked. Not shown here for brevity. int main() { ... FileHandle * sdfile = sd.open("test.txt", O_WRONLY | O_CREAT | O_TRUNC); sdfile->write("hello", 6); sdfile->close(); ... FILE * file = fopen("nextest.txt", "w"); fwrite(buffer, 1, sizeof(buffer), file); fclose(file); ... mkdir("/sd/sd_dir", 0777); mkdir("/fs/fs_dir", 0777); remove("/sd/sdfinal.log"); rename("/sd/sdfinal.txt", "/sd/sdfinal.log"); ... }
main.cpp
- Committer:
- WiredHome
- Date:
- 2016-03-13
- Revision:
- 6:ea80c5a132b6
- Parent:
- 4:be096a44f789
File content as of revision 6:ea80c5a132b6:
/// /// MultiFileSystem /// /// This supports both USB and SD File systems both being mounted at the same time. /// /// Untested: /// * live plug/unplug of either/both /// * Concurrent access (e.g. copy from one to the other). /// #include "mbed.h" #include "MSCFileSystem.h" #include "SDFileSystem.h" MSCFileSystem fs("fs"); SDFileSystem sd(p5, p6, p7, p8, "sd", p11, SDFileSystem::SWITCH_NEG_NO, 15000000); Timer timer; char buffer[4096]; // someplace to stuff random data. #define TESTSIZE 1048576 //#define TESTSIZE 100 void SDWriteTest(const char * fname) { printf("\r\n"); printf("SDWriteTest : writing %d B using %d B buffer into %s...\r\n", TESTSIZE, sizeof(buffer), fname); FileHandle* file = sd.open(fname, O_WRONLY | O_CREAT | O_TRUNC); if (file != NULL) { timer.start(); for (int i = 0; i < (TESTSIZE / sizeof(buffer)); i++) { if (file->write(buffer, sizeof(buffer)) != sizeof(buffer)) { timer.stop(); printf(" write error!\r\n"); timer.reset(); return; } } timer.stop(); if (file->close()) printf(" failed to close file!\r\n"); else printf(" Result: %.2f KB/s\r\n", 1024 / (timer.read_us() / 1000000.0)); timer.reset(); } else { printf(" failed to create file!\r\n"); } } void SDReadTest(const char * fname) { printf("\r\n"); printf("SDReadTest : reading %d B using %d B buffer from %s...\r\n", TESTSIZE, sizeof(buffer), fname); FileHandle* file = sd.open(fname, O_RDONLY); if (file != NULL) { timer.start(); int iterations = 0; while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)) iterations++; timer.stop(); if (iterations != (TESTSIZE / sizeof(buffer))) printf(" read error!\r\n"); else if (file->close()) printf(" failed to close file!\r\n"); else if (sd.remove(fname)) printf(" failed to delete file!\r\n"); else printf(" Result: %.2f KB/s\r\n", 1024 / (timer.read_us() / 1000000.0)); timer.reset(); } else { printf(" failed to open file!\n"); } } // ==================================================== void STDIOWriteTest(const char * fqfname) { printf("\r\n"); printf("STDIOWriteTest: writing %d B using %d B buffer into %s...\r\n", TESTSIZE, sizeof(buffer), fqfname); FILE * file = fopen(fqfname, "w"); if (file != NULL) { timer.start(); for (int i = 0; i < (TESTSIZE / sizeof(buffer)); i++) { if (fwrite(buffer, 1, sizeof(buffer), file) != sizeof(buffer)) { timer.stop(); printf(" write error!\r\n"); timer.reset(); return; } } timer.stop(); if (fclose(file)) printf(" failed to close file!\r\n"); else printf(" Result: %.2f KB/s\r\n", 1024 / (timer.read_us() / 1000000.0)); timer.reset(); } else { printf(" failed to create file!\r\n"); } } void STDIOReadTest(const char * fqfname) { printf("\r\n"); printf("STDIOReadTest : reading %d B using %d B buffer from %s...\r\n", TESTSIZE, sizeof(buffer), fqfname); FILE * fh = fopen(fqfname, "r"); if (fh) { timer.start(); int iterations = 0; while (fread(buffer, 1, sizeof(buffer), fh) == sizeof(buffer)) iterations++; timer.stop(); if (iterations != (TESTSIZE / sizeof(buffer))) printf(" read error! on iteration %d\r\n", iterations); else if (fclose(fh)) printf(" failed to close file!\r\n"); else if (remove(fqfname)) printf(" failed to delete file!\r\n"); else printf(" Result: %.2f KB/s\r\n", 1024 / (timer.read_us() / 1000000.0)); timer.reset(); } else { printf(" failed to open file!\r\n"); } } void ShowDir(char *dir, int depth = 0) { DIR *dp; struct dirent *dirp; dp = opendir(dir); if (dp) { printf("\r\nDirectory %s\r\n", dir); ++depth; while((dirp = readdir(dp)) != NULL) { printf("%*s %s\r\n", (depth < 10) ? depth : 10, "", dirp->d_name); ShowDir(dirp->d_name, depth); } closedir(dp); } } // ==================================================== int main() { printf("\r\n\r\n\r\n\r\n"); printf("FileSys-Multi Test. Build " __DATE__ " " __TIME__ "\r\n"); //Configure CRC, large frames, and write validation sd.crc(true); sd.large_frames(true); sd.write_validation(true); //Fill the buffer with random data for the write test srand(time(NULL)); for (int i = 0; i < sizeof(buffer); i++) buffer[i] = rand(); bool success = false; do { wait(0.5); if (!sd.card_present()) { printf("\r\nNo SD card present!\r\n"); continue; } printf("\r\nMounting SD card...\r\n"); if (sd.mount() != 0) { printf("failed to mount SD!\r\n"); continue; } printf(" success!\r\n"); printf("\tCard type: "); SDFileSystem::CardType cardType = sd.card_type(); if (cardType == SDFileSystem::CARD_NONE) printf("None\r\n"); else if (cardType == SDFileSystem::CARD_MMC) printf("MMC\r\n"); else if (cardType == SDFileSystem::CARD_SD) printf("SD\r\n"); else if (cardType == SDFileSystem::CARD_SDHC) printf("SDHC\r\n"); else printf("Unknown\r\n"); printf("\r\nMounting FS card...\r\n"); if (fs.mount() != 0) { printf("failed to mount FS!\r\n"); continue; } printf(" success!\r\n"); //Display the card capacity printf("\tSectors: %u\r\n", sd.disk_sectors()); printf("\tCapacity: %.1fMB\r\n", sd.disk_sectors() / 2048.0); STDIOWriteTest("/fs/fsfile1.bin"); STDIOReadTest("/fs/fsfile1.bin"); STDIOWriteTest("/sd/sdfile1.bin"); STDIOReadTest("/sd/sdfile1.bin"); SDWriteTest("sdfile2.bin"); SDReadTest("sdfile2.bin"); STDIOWriteTest("/fs/fsfile2.bin"); STDIOReadTest("/fs/fsfile2.bin"); STDIOWriteTest("/fs/fsfinal.txt"); STDIOWriteTest("/sd/sdfinal.txt"); /// * mkdir mkdir("/sd/sd_dir", 0777); // @TODO check the permissions mask. ignored? mkdir("/fs/fs_dir", 0777); // @TODO check the permissions mask. ignored? STDIOWriteTest("/sd/sd_dir/sdfile3.bin"); STDIOWriteTest("/fs/fs_dir/fsfile3.bin"); /// * opendir ShowDir("/sd"); ShowDir("/fs"); /// * rename starts with an unlink printf("\r\nrename:\r\n"); remove("/sd/sdfinal.log"); int rn = rename("/sd/sdfinal.txt", "/sd/sdfinal.log"); printf(" rename(%s,%s) returned %d\r\n", "/sd/sdfinal.txt", "/sd/sdfinal.log", rn); remove("/fs/fsfinal.log"); rn = rename("/fs/fsfinal.txt", "/fs/fsfinal.log"); printf(" rename(%s,%s) returned %d\r\n", "/fs/fsfinal.txt", "/fs/fsfinal.log", rn); /// * live plug/unplug of either/both /// * Concurrent access (e.g. copy from one to the other). #if 0 /// * fstat can be run against a specific object (e.g. sd.fstat) /// but it will require deeper hooks into mbed library to get /// the generalized form of fstat(file, &info); printf("fstat(%s):\r\n", "sdfinal.txt"); FILINFO info; if (sd.fstat("sdfinal.txt", &info) == 0) { printf(" size: %d\r\n", info.fsize); printf(" date: %d\r\n", info.fdate); printf(" time: %d\r\n", info.ftime); printf(" attr: %X\r\n", info.fattrib); printf(" name: %s\r\n", info.fname); } // scraps that can have value... printf("Timestamp: %u/%02u/%02u, %02u:%02u\n", (info.fdate >> 9) + 1980, info.fdate >> 5 & 15, info.fdate & 31, info.ftime >> 11, info.ftime >> 5 & 63); printf("Attributes: %c%c%c%c%c\n", (info.fattrib & AM_DIR) ? 'D' : '-', (info.fattrib & AM_RDO) ? 'R' : '-', (info.fattrib & AM_HID) ? 'H' : '-', (info.fattrib & AM_SYS) ? 'S' : '-', (info.fattrib & AM_ARC) ? 'A' : '-'); #endif //Unmount the SD card printf("\r\nunmounting all now...\r\n"); sd.unmount(); fs.unmount(); success = true; } while (!success); }