example FatFS, LittleFileSystem, BlockDevice

Revision:
0:08256a8320ed
diff -r 000000000000 -r 08256a8320ed main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jan 22 18:01:37 2022 +0000
@@ -0,0 +1,255 @@
+/* Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// https://github.com/ARMmbed/mbed-os-example-filesystem/blob/master/main.cpp
+// LittleFileSystem OK!
+// FATFileSystem    OK! 
+
+#include "mbed.h"
+#include <stdio.h>
+#include <errno.h>
+#include <functional>
+#include "BlockDevice.h"
+
+// Maximum number of elements in buffer
+#define BUFFER_MAX_LEN 10
+#define FORCE_REFORMAT true
+// This will take the system's default block device
+BlockDevice *bd = BlockDevice::get_default_instance();// OK
+
+// Можно создать файловую систему в ОЗУ(куча, heap)
+// Instead of the default block device, you can define your own block device.
+// For example: HeapBlockDevice with size of 2048 bytes, read size 1, write size 1 and erase size 512.
+//#include "HeapBlockDevice.h"
+//BlockDevice *bd = new HeapBlockDevice(2048, 1, 1, 512);//OK! создает, но 2048 будет мало для эксперимента
+//BlockDevice *bd = new HeapBlockDevice(1024*72, 1, 1, 512);//32kByte хватает для создания небольшой ФС в ОЗУ! (LittleFS, для FATFS - мало, 72kB - OK )
+
+// This example uses LittleFileSystem as the default file system
+//#include "LittleFileSystem.h"
+//LittleFileSystem fs("fs");//  OK!!
+
+// Uncomment the following two lines and comment the previous two to use FAT file system.
+#include "FATFileSystem.h"
+FATFileSystem fs("fs");
+
+// Set up the button to trigger an erase
+InterruptIn irq(BUTTON1);//OK повесим прерывание на пользовательскую кнопку
+void erase() {
+    printf("Initializing the block device... ");
+    fflush(stdout);
+    int err = bd->init();
+    printf("%s\n", (err ? "Fail :(" : "OK"));
+    if (err) {
+        error("error: %s (%d)\n", strerror(-err), err);
+    }
+
+    printf("Erasing the block device... ");
+    fflush(stdout);
+    err = bd->erase(0, bd->size());
+    printf("%s\n", (err ? "Fail :(" : "OK"));
+    if (err) {
+        error("error: %s (%d)\n", strerror(-err), err);
+    }
+
+    printf("Deinitializing the block device... ");
+    fflush(stdout);
+    err = bd->deinit();
+    printf("%s\n", (err ? "Fail :(" : "OK"));
+    if (err) {
+        error("error: %s (%d)\n", strerror(-err), err);
+    }
+}
+
+static auto erase_event = mbed_event_queue()->make_user_allocated_event(erase);//OK
+
+
+DigitalOut led(LED1);
+
+#define WAIT_MS      1000
+void wait(int ms){
+    wait_us(ms*WAIT_MS);
+}
+
+int main()
+{
+    printf("START_default_1\n");
+    //========================================================================================//
+    printf("--- Mbed OS filesystem example ---\n");
+
+    // Setup the erase event on button press, use the event queue
+    // to avoid running in interrupt context
+    irq.fall(std::ref(erase_event));
+
+    // Try to mount the filesystem
+    printf("Mounting the filesystem... ");
+    fflush(stdout);
+    int err = fs.mount(bd);
+    printf("%s\n", (err ? "Fail :(" : "OK"));
+    if (err || FORCE_REFORMAT) {
+        // Reformat if we can't mount the filesystem
+        printf("No filesystem found, formatting... ");
+        fflush(stdout);
+        err = fs.reformat(bd);
+        printf("%s\n", (err ? "Fail :(" : "OK"));
+        if (err) {
+            error("error: %s (%d)\n", strerror(-err), err);
+        }
+    }
+
+    // Open the numbers file
+    printf("Opening \"/fs/numbers.txt\"... ");
+    fflush(stdout);
+    FILE *f = fopen("/fs/numbers.txt", "r+");
+    printf("%s\n", (!f ? "Fail :(" : "OK"));
+    if (!f) {
+        // Create the numbers file if it doesn't exist
+        printf("No file found, creating a new file... ");
+        fflush(stdout);
+        f = fopen("/fs/numbers.txt", "w+");
+        printf("%s\n", (!f ? "Fail :(" : "OK"));
+        if (!f) {
+            error("error: %s (%d)\n", strerror(errno), -errno);
+        }
+
+        for (int i = 0; i < 10; i++) {
+            printf("\rWriting numbers (%d/%d)... ", i, 10);
+            fflush(stdout);
+            err = fprintf(f, "    %d\n", i);
+            if (err < 0) {
+                printf("Fail :(\n");
+                error("error: %s (%d)\n", strerror(errno), -errno);
+            }
+        }
+        printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);
+
+        printf("Seeking file... ");
+        fflush(stdout);
+        err = fseek(f, 0, SEEK_SET);
+        printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
+        if (err < 0) {
+            error("error: %s (%d)\n", strerror(errno), -errno);
+        }
+    }
+
+    // Go through and increment the numbers
+    for (int i = 0; i < 10; i++) {
+        printf("\rIncrementing numbers (%d/%d)... ", i, 10);
+        fflush(stdout);
+
+        // Get current stream position
+        long pos = ftell(f);
+
+        // Parse out the number and increment
+        char buf[BUFFER_MAX_LEN];
+        if (!fgets(buf, BUFFER_MAX_LEN, f)) {
+            error("error: %s (%d)\n", strerror(errno), -errno);
+        }
+        char *endptr;
+        int32_t number = strtol(buf, &endptr, 10);
+        if (
+            (errno == ERANGE) || // The number is too small/large
+            (endptr == buf) ||   // No character was read
+            (*endptr && *endptr != '\n') // The whole input was not converted
+        ) {
+            continue;
+        }
+        number += 1;
+
+        // Seek to beginning of number
+        fseek(f, pos, SEEK_SET);
+    
+        // Store number
+        fprintf(f, "    %d\n", number);
+
+        // Flush between write and read on same file
+        fflush(f);
+    }
+    printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
+
+    // Close the file which also flushes any cached writes
+    printf("Closing \"/fs/numbers.txt\"... ");
+    fflush(stdout);
+    err = fclose(f);
+    printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
+    if (err < 0) {
+        error("error: %s (%d)\n", strerror(errno), -errno);
+    }
+    
+    // Display the root directory
+    printf("Opening the root directory... ");
+    fflush(stdout);
+    DIR *d = opendir("/fs/");
+    printf("%s\n", (!d ? "Fail :(" : "OK"));
+    if (!d) {
+        error("error: %s (%d)\n", strerror(errno), -errno);
+    }
+
+    printf("root directory:\n");
+    while (true) {
+        struct dirent *e = readdir(d);
+        if (!e) {
+            break;
+        }
+
+        printf("    %s\n", e->d_name);
+    }
+
+    printf("Closing the root directory... ");
+    fflush(stdout);
+    err = closedir(d);
+    printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
+    if (err < 0) {
+        error("error: %s (%d)\n", strerror(errno), -errno);
+    }
+
+    // Display the numbers file
+    printf("Opening \"/fs/numbers.txt\"... ");
+    fflush(stdout);
+    f = fopen("/fs/numbers.txt", "r");
+    printf("%s\n", (!f ? "Fail :(" : "OK"));
+    if (!f) {
+        error("error: %s (%d)\n", strerror(errno), -errno);
+    }
+
+    printf("numbers:\n");
+    while (!feof(f)) {
+        int c = fgetc(f);
+        printf("%c", c);
+    }
+
+    printf("\rClosing \"/fs/numbers.txt\"... ");
+    fflush(stdout);
+    err = fclose(f);
+    printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
+    if (err < 0) {
+        error("error: %s (%d)\n", strerror(errno), -errno);
+    }
+
+    // Tidy up
+    printf("Unmounting... ");
+    fflush(stdout);
+    err = fs.unmount();
+    printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
+    if (err < 0) {
+        error("error: %s (%d)\n", strerror(-err), err);
+    }
+        
+    printf("Mbed OS filesystem example done!\n");
+
+    //========================================================================================//
+    while(1) {     
+       // моргаем встроенным светодиодом
+        led = !led;
+        wait(100);
+    }
+}
+