Nuvoton / Mbed OS NuMaker-mbed-SD-FileSystem-example
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2019 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed.h"
00017 #include <stdio.h>
00018 #include <errno.h>
00019 
00020 #include "NuSDBlockDevice.h"
00021 #include "FlashSimBlockDevice.h"
00022 
00023 
00024 // Maximum number of elements in buffer
00025 #define BUFFER_MAX_LEN 10
00026 
00027 // NUSD for block device
00028 NuSDBlockDevice *bd_ = new NuSDBlockDevice();
00029 // Add flash-simulate layer on top of NUSD not implementing "erase" characteristic
00030 FlashSimBlockDevice *bd = new FlashSimBlockDevice(bd_);
00031 
00032 // Instead of the default block device, you can define your own block device.
00033 // For example: HeapBlockDevice with size of 2048 bytes, read size 1, write size 1 and erase size 512.
00034 // #include "HeapBlockDevice.h"
00035 // BlockDevice *bd = new HeapBlockDevice(2048, 1, 1, 512);
00036 
00037 
00038 // This example uses FAT file system as the default.
00039 #include "FATFileSystem.h"
00040 FATFileSystem fs("fs");
00041 
00042 // Uncomment in the following two lines and comment out the previous two to use Little file system.
00043 //#include "LittleFileSystem.h"
00044 //LittleFileSystem fs("fs");
00045 
00046 
00047 // Set up the button to trigger an erase
00048 InterruptIn irq(BUTTON1);
00049 
00050 void erase() {
00051     printf("Initializing the block device... ");
00052     fflush(stdout);
00053     int err = bd->init();
00054     printf("%s\n", (err ? "Fail :(" : "OK"));
00055     if (err) {
00056         error("error: %s (%d)\n", strerror(-err), err);
00057     }
00058 
00059     printf("Erasing the block device... ");
00060     fflush(stdout);
00061     // Whole erase takes too long for SD/NUSD. Just erase the front so that
00062     // it will recognize as invalid file system format.
00063     //err = bd->erase(0, bd->size());
00064     err = bd->erase(0, 1024*64);
00065     printf("%s\n", (err ? "Fail :(" : "OK"));
00066     if (err) {
00067         error("error: %s (%d)\n", strerror(-err), err);
00068     }
00069 
00070     printf("Deinitializing the block device... ");
00071     fflush(stdout);
00072     err = bd->deinit();
00073     printf("%s\n", (err ? "Fail :(" : "OK"));
00074     if (err) {
00075         error("error: %s (%d)\n", strerror(-err), err);
00076     }
00077 }
00078 
00079 #if MBED_MAJOR_VERSION >= 6
00080 static auto erase_event = mbed_event_queue()->make_user_allocated_event(erase);
00081 #endif
00082 
00083 // Entry point for the example
00084 int main() {
00085 #ifdef MBED_MAJOR_VERSION
00086     printf("Mbed OS version %d.%d.%d\r\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
00087 #endif
00088     printf("--- Mbed OS filesystem example ---\n");
00089 
00090     // Setup the erase event on button press, use the event queue
00091     // to avoid running in interrupt context
00092 #if MBED_MAJOR_VERSION >= 6
00093     irq.fall(std::ref(erase_event));
00094 #else
00095     irq.fall(mbed_event_queue()->event(erase));
00096 #endif
00097 
00098     // Try to mount the filesystem
00099     printf("Mounting the filesystem... ");
00100     fflush(stdout);
00101     int err = fs.mount(bd);
00102     printf("%s\n", (err ? "Fail :(" : "OK"));
00103     if (err) {
00104         // Reformat if we can't mount the filesystem
00105         // this should only happen on the first boot
00106         printf("No filesystem found, formatting... ");
00107         fflush(stdout);
00108         err = fs.reformat(bd);
00109         printf("%s\n", (err ? "Fail :(" : "OK"));
00110         if (err) {
00111             error("error: %s (%d)\n", strerror(-err), err);
00112         }
00113     }
00114 
00115     // Open the numbers file
00116     printf("Opening \"/fs/numbers.txt\"... ");
00117     fflush(stdout);
00118     FILE *f = fopen("/fs/numbers.txt", "r+");
00119     printf("%s\n", (!f ? "Fail :(" : "OK"));
00120     if (!f) {
00121         // Create the numbers file if it doesn't exist
00122         printf("No file found, creating a new file... ");
00123         fflush(stdout);
00124         f = fopen("/fs/numbers.txt", "w+");
00125         printf("%s\n", (!f ? "Fail :(" : "OK"));
00126         if (!f) {
00127             error("error: %s (%d)\n", strerror(errno), -errno);
00128         }
00129 
00130         for (int i = 0; i < 10; i++) {
00131             printf("\rWriting numbers (%d/%d)... ", i, 10);
00132             fflush(stdout);
00133             err = fprintf(f, "    %d\n", i);
00134             if (err < 0) {
00135                 printf("Fail :(\n");
00136                 error("error: %s (%d)\n", strerror(errno), -errno);
00137             }
00138         }
00139         printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);
00140 
00141         printf("Seeking file... ");
00142         fflush(stdout);
00143         err = fseek(f, 0, SEEK_SET);
00144         printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00145         if (err < 0) {
00146             error("error: %s (%d)\n", strerror(errno), -errno);
00147         }
00148     }
00149 
00150     // Go through and increment the numbers
00151     for (int i = 0; i < 10; i++) {
00152         printf("\rIncrementing numbers (%d/%d)... ", i, 10);
00153         fflush(stdout);
00154 
00155         // Get current stream position
00156         long pos = ftell(f);
00157 
00158         // Parse out the number and increment
00159         char buf[BUFFER_MAX_LEN];
00160         if (!fgets(buf, BUFFER_MAX_LEN, f)) {
00161             error("error: %s (%d)\n", strerror(errno), -errno);
00162         }
00163         char *endptr;
00164         int32_t number = strtol(buf, &endptr, 10);
00165         if (
00166             (errno == ERANGE) || // The number is too small/large
00167             (endptr == buf) ||   // No character was read
00168             (*endptr && *endptr != '\n') // The whole input was not converted
00169         ) {
00170             continue;
00171         }
00172         number += 1;
00173 
00174         // Seek to beginning of number
00175         fseek(f, pos, SEEK_SET);
00176     
00177         // Store number
00178         fprintf(f, "    %d\n", (int)number);
00179     
00180         // Flush between write and read on same file
00181         fflush(f);
00182     }
00183     printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
00184 
00185     // Close the file which also flushes any cached writes
00186     printf("Closing \"/fs/numbers.txt\"... ");
00187     fflush(stdout);
00188     err = fclose(f);
00189     printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00190     if (err < 0) {
00191         error("error: %s (%d)\n", strerror(errno), -errno);
00192     }
00193     
00194     // Display the root directory
00195     printf("Opening the root directory... ");
00196     fflush(stdout);
00197     DIR *d = opendir("/fs/");
00198     printf("%s\n", (!d ? "Fail :(" : "OK"));
00199     if (!d) {
00200         error("error: %s (%d)\n", strerror(errno), -errno);
00201     }
00202 
00203     printf("root directory:\n");
00204     while (true) {
00205         struct dirent *e = readdir(d);
00206         if (!e) {
00207             break;
00208         }
00209 
00210         printf("    %s\n", e->d_name);
00211     }
00212 
00213     printf("Closing the root directory... ");
00214     fflush(stdout);
00215     err = closedir(d);
00216     printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00217     if (err < 0) {
00218         error("error: %s (%d)\n", strerror(errno), -errno);
00219     }
00220 
00221     // Display the numbers file
00222     printf("Opening \"/fs/numbers.txt\"... ");
00223     fflush(stdout);
00224     f = fopen("/fs/numbers.txt", "r");
00225     printf("%s\n", (!f ? "Fail :(" : "OK"));
00226     if (!f) {
00227         error("error: %s (%d)\n", strerror(errno), -errno);
00228     }
00229 
00230     printf("numbers:\n");
00231     while (!feof(f)) {
00232         int c = fgetc(f);
00233         printf("%c", c);
00234     }
00235 
00236     printf("\rClosing \"/fs/numbers.txt\"... ");
00237     fflush(stdout);
00238     err = fclose(f);
00239     printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00240     if (err < 0) {
00241         error("error: %s (%d)\n", strerror(errno), -errno);
00242     }
00243 
00244     // Tidy up
00245     printf("Unmounting... ");
00246     fflush(stdout);
00247     err = fs.unmount();
00248     printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00249     if (err < 0) {
00250         error("error: %s (%d)\n", strerror(-err), err);
00251     }
00252         
00253     printf("Mbed OS filesystem example done!\n");
00254 }
00255