NuMaker SD-File-System with SD mode

Committer:
ccli8
Date:
Mon Nov 18 17:37:29 2019 +0800
Revision:
21:dfd65207a645
Parent:
16:9a672dc5274c
Child:
23:036c20fd7064
Synchronize to mbed-os-example-filesystem

1. Change filesystem to LittleFS
2. Support 'format filesystem' via button

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ccli8 21:dfd65207a645 1 /* mbed Microcontroller Library
ccli8 21:dfd65207a645 2 * Copyright (c) 2006-2019 ARM Limited
ccli8 21:dfd65207a645 3 *
ccli8 21:dfd65207a645 4 * Licensed under the Apache License, Version 2.0 (the "License");
ccli8 21:dfd65207a645 5 * you may not use this file except in compliance with the License.
ccli8 21:dfd65207a645 6 * You may obtain a copy of the License at
ccli8 21:dfd65207a645 7 *
ccli8 21:dfd65207a645 8 * http://www.apache.org/licenses/LICENSE-2.0
ccli8 21:dfd65207a645 9 *
ccli8 21:dfd65207a645 10 * Unless required by applicable law or agreed to in writing, software
ccli8 21:dfd65207a645 11 * distributed under the License is distributed on an "AS IS" BASIS,
ccli8 21:dfd65207a645 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ccli8 21:dfd65207a645 13 * See the License for the specific language governing permissions and
ccli8 21:dfd65207a645 14 * limitations under the License.
ccli8 21:dfd65207a645 15 */
ccli8 21:dfd65207a645 16 #include "mbed.h"
ccli8 21:dfd65207a645 17 #include <stdio.h>
ccli8 21:dfd65207a645 18 #include <errno.h>
ccli8 21:dfd65207a645 19
ccli8 21:dfd65207a645 20 #include "NuSDBlockDevice.h"
ccli8 21:dfd65207a645 21
ccli8 21:dfd65207a645 22 // Maximum number of elements in buffer
ccli8 21:dfd65207a645 23 #define BUFFER_MAX_LEN 10
ccli8 21:dfd65207a645 24
ccli8 21:dfd65207a645 25 // NUSD for block device
ccli8 21:dfd65207a645 26 NuSDBlockDevice *bd = new NuSDBlockDevice();
ccli8 21:dfd65207a645 27
ccli8 21:dfd65207a645 28 // Instead of the default block device, you can define your own block device.
ccli8 21:dfd65207a645 29 // For example: HeapBlockDevice with size of 2048 bytes, read size 1, write size 1 and erase size 512.
ccli8 21:dfd65207a645 30 // #include "HeapBlockDevice.h"
ccli8 21:dfd65207a645 31 // BlockDevice *bd = new HeapBlockDevice(2048, 1, 1, 512);
ccli8 21:dfd65207a645 32
ccli8 21:dfd65207a645 33
ccli8 21:dfd65207a645 34 // This example uses LittleFileSystem as the default file system
ccli8 21:dfd65207a645 35 #include "LittleFileSystem.h"
ccli8 21:dfd65207a645 36 LittleFileSystem fs("fs");
ccli8 21:dfd65207a645 37
ccli8 21:dfd65207a645 38 // Uncomment the following two lines and comment the previous two to use FAT file system.
ccli8 21:dfd65207a645 39 // #include "FATFileSystem.h"
ccli8 21:dfd65207a645 40 // FATFileSystem fs("fs");
ccli8 21:dfd65207a645 41
ccli8 21:dfd65207a645 42
ccli8 21:dfd65207a645 43 // Set up the button to trigger an erase
ccli8 21:dfd65207a645 44 InterruptIn irq(BUTTON1);
ccli8 21:dfd65207a645 45 void erase() {
ccli8 21:dfd65207a645 46 printf("Initializing the block device... ");
ccli8 21:dfd65207a645 47 fflush(stdout);
ccli8 21:dfd65207a645 48 int err = bd->init();
ccli8 21:dfd65207a645 49 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 50 if (err) {
ccli8 21:dfd65207a645 51 error("error: %s (%d)\n", strerror(-err), err);
ccli8 21:dfd65207a645 52 }
ccli8 21:dfd65207a645 53
ccli8 21:dfd65207a645 54 printf("Erasing the block device... ");
ccli8 21:dfd65207a645 55 fflush(stdout);
ccli8 21:dfd65207a645 56 err = bd->erase(0, bd->size());
ccli8 21:dfd65207a645 57 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 58 if (err) {
ccli8 21:dfd65207a645 59 error("error: %s (%d)\n", strerror(-err), err);
ccli8 21:dfd65207a645 60 }
ccli8 21:dfd65207a645 61
ccli8 21:dfd65207a645 62 printf("Deinitializing the block device... ");
ccli8 21:dfd65207a645 63 fflush(stdout);
ccli8 21:dfd65207a645 64 err = bd->deinit();
ccli8 21:dfd65207a645 65 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 66 if (err) {
ccli8 21:dfd65207a645 67 error("error: %s (%d)\n", strerror(-err), err);
ccli8 21:dfd65207a645 68 }
ccli8 21:dfd65207a645 69 }
ccli8 21:dfd65207a645 70
ccli8 21:dfd65207a645 71
ccli8 21:dfd65207a645 72 // Entry point for the example
ccli8 21:dfd65207a645 73 int main() {
ccli8 21:dfd65207a645 74 printf("--- Mbed OS filesystem example ---\n");
ccli8 21:dfd65207a645 75
ccli8 21:dfd65207a645 76 // Setup the erase event on button press, use the event queue
ccli8 21:dfd65207a645 77 // to avoid running in interrupt context
ccli8 21:dfd65207a645 78 irq.fall(mbed_event_queue()->event(erase));
ccli8 21:dfd65207a645 79
ccli8 21:dfd65207a645 80 // Try to mount the filesystem
ccli8 21:dfd65207a645 81 printf("Mounting the filesystem... ");
ccli8 21:dfd65207a645 82 fflush(stdout);
ccli8 21:dfd65207a645 83 int err = fs.mount(bd);
ccli8 21:dfd65207a645 84 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 85 if (err) {
ccli8 21:dfd65207a645 86 // Reformat if we can't mount the filesystem
ccli8 21:dfd65207a645 87 // this should only happen on the first boot
ccli8 21:dfd65207a645 88 printf("No filesystem found, formatting... ");
ccli8 21:dfd65207a645 89 fflush(stdout);
ccli8 21:dfd65207a645 90 err = fs.reformat(bd);
ccli8 21:dfd65207a645 91 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 92 if (err) {
ccli8 21:dfd65207a645 93 error("error: %s (%d)\n", strerror(-err), err);
ccli8 21:dfd65207a645 94 }
ccli8 21:dfd65207a645 95 }
ccli8 21:dfd65207a645 96
ccli8 21:dfd65207a645 97 // Open the numbers file
ccli8 21:dfd65207a645 98 printf("Opening \"/fs/numbers.txt\"... ");
ccli8 21:dfd65207a645 99 fflush(stdout);
ccli8 21:dfd65207a645 100 FILE *f = fopen("/fs/numbers.txt", "r+");
ccli8 21:dfd65207a645 101 printf("%s\n", (!f ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 102 if (!f) {
ccli8 21:dfd65207a645 103 // Create the numbers file if it doesn't exist
ccli8 21:dfd65207a645 104 printf("No file found, creating a new file... ");
ccli8 21:dfd65207a645 105 fflush(stdout);
ccli8 21:dfd65207a645 106 f = fopen("/fs/numbers.txt", "w+");
ccli8 21:dfd65207a645 107 printf("%s\n", (!f ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 108 if (!f) {
ccli8 21:dfd65207a645 109 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 110 }
ccli8 21:dfd65207a645 111
ccli8 21:dfd65207a645 112 for (int i = 0; i < 10; i++) {
ccli8 21:dfd65207a645 113 printf("\rWriting numbers (%d/%d)... ", i, 10);
ccli8 21:dfd65207a645 114 fflush(stdout);
ccli8 21:dfd65207a645 115 err = fprintf(f, " %d\n", i);
ccli8 21:dfd65207a645 116 if (err < 0) {
ccli8 21:dfd65207a645 117 printf("Fail :(\n");
ccli8 21:dfd65207a645 118 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 119 }
ccli8 21:dfd65207a645 120 }
ccli8 21:dfd65207a645 121 printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);
ccli8 21:dfd65207a645 122
ccli8 21:dfd65207a645 123 printf("Seeking file... ");
ccli8 21:dfd65207a645 124 fflush(stdout);
ccli8 21:dfd65207a645 125 err = fseek(f, 0, SEEK_SET);
ccli8 21:dfd65207a645 126 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 127 if (err < 0) {
ccli8 21:dfd65207a645 128 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 129 }
ccli8 21:dfd65207a645 130 }
ccli8 21:dfd65207a645 131
ccli8 21:dfd65207a645 132 // Go through and increment the numbers
ccli8 21:dfd65207a645 133 for (int i = 0; i < 10; i++) {
ccli8 21:dfd65207a645 134 printf("\rIncrementing numbers (%d/%d)... ", i, 10);
ccli8 21:dfd65207a645 135 fflush(stdout);
ccli8 21:dfd65207a645 136
ccli8 21:dfd65207a645 137 // Get current stream position
ccli8 21:dfd65207a645 138 long pos = ftell(f);
ccli8 21:dfd65207a645 139
ccli8 21:dfd65207a645 140 // Parse out the number and increment
ccli8 21:dfd65207a645 141 char buf[BUFFER_MAX_LEN];
ccli8 21:dfd65207a645 142 if (!fgets(buf, BUFFER_MAX_LEN, f)) {
ccli8 21:dfd65207a645 143 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 144 }
ccli8 21:dfd65207a645 145 char *endptr;
ccli8 21:dfd65207a645 146 int32_t number = strtol(buf, &endptr, 10);
ccli8 21:dfd65207a645 147 if (
ccli8 21:dfd65207a645 148 (errno == ERANGE) || // The number is too small/large
ccli8 21:dfd65207a645 149 (endptr == buf) || // No character was read
ccli8 21:dfd65207a645 150 (*endptr && *endptr != '\n') // The whole input was not converted
ccli8 21:dfd65207a645 151 ) {
ccli8 21:dfd65207a645 152 continue;
ccli8 21:dfd65207a645 153 }
ccli8 21:dfd65207a645 154 number += 1;
ccli8 21:dfd65207a645 155
ccli8 21:dfd65207a645 156 // Seek to beginning of number
ccli8 21:dfd65207a645 157 fseek(f, pos, SEEK_SET);
ccli8 21:dfd65207a645 158
ccli8 21:dfd65207a645 159 // Store number
ccli8 21:dfd65207a645 160 fprintf(f, " %d\n", number);
ccli8 21:dfd65207a645 161
ccli8 21:dfd65207a645 162 // Flush between write and read on same file
ccli8 21:dfd65207a645 163 fflush(f);
ccli8 21:dfd65207a645 164 }
ccli8 21:dfd65207a645 165 printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
ccli8 21:dfd65207a645 166
ccli8 21:dfd65207a645 167 // Close the file which also flushes any cached writes
ccli8 21:dfd65207a645 168 printf("Closing \"/fs/numbers.txt\"... ");
ccli8 21:dfd65207a645 169 fflush(stdout);
ccli8 21:dfd65207a645 170 err = fclose(f);
ccli8 21:dfd65207a645 171 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 172 if (err < 0) {
ccli8 21:dfd65207a645 173 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 174 }
ccli8 21:dfd65207a645 175
ccli8 21:dfd65207a645 176 // Display the root directory
ccli8 21:dfd65207a645 177 printf("Opening the root directory... ");
ccli8 21:dfd65207a645 178 fflush(stdout);
ccli8 21:dfd65207a645 179 DIR *d = opendir("/fs/");
ccli8 21:dfd65207a645 180 printf("%s\n", (!d ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 181 if (!d) {
ccli8 21:dfd65207a645 182 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 183 }
ccli8 21:dfd65207a645 184
ccli8 21:dfd65207a645 185 printf("root directory:\n");
ccli8 21:dfd65207a645 186 while (true) {
ccli8 21:dfd65207a645 187 struct dirent *e = readdir(d);
ccli8 21:dfd65207a645 188 if (!e) {
ccli8 21:dfd65207a645 189 break;
ccli8 21:dfd65207a645 190 }
ccli8 21:dfd65207a645 191
ccli8 21:dfd65207a645 192 printf(" %s\n", e->d_name);
ccli8 21:dfd65207a645 193 }
ccli8 21:dfd65207a645 194
ccli8 21:dfd65207a645 195 printf("Closing the root directory... ");
ccli8 21:dfd65207a645 196 fflush(stdout);
ccli8 21:dfd65207a645 197 err = closedir(d);
ccli8 21:dfd65207a645 198 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 199 if (err < 0) {
ccli8 21:dfd65207a645 200 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 201 }
ccli8 21:dfd65207a645 202
ccli8 21:dfd65207a645 203 // Display the numbers file
ccli8 21:dfd65207a645 204 printf("Opening \"/fs/numbers.txt\"... ");
ccli8 21:dfd65207a645 205 fflush(stdout);
ccli8 21:dfd65207a645 206 f = fopen("/fs/numbers.txt", "r");
ccli8 21:dfd65207a645 207 printf("%s\n", (!f ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 208 if (!f) {
ccli8 21:dfd65207a645 209 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 210 }
ccli8 21:dfd65207a645 211
ccli8 21:dfd65207a645 212 printf("numbers:\n");
ccli8 21:dfd65207a645 213 while (!feof(f)) {
ccli8 21:dfd65207a645 214 int c = fgetc(f);
ccli8 21:dfd65207a645 215 printf("%c", c);
ccli8 21:dfd65207a645 216 }
ccli8 21:dfd65207a645 217
ccli8 21:dfd65207a645 218 printf("\rClosing \"/fs/numbers.txt\"... ");
ccli8 21:dfd65207a645 219 fflush(stdout);
ccli8 21:dfd65207a645 220 err = fclose(f);
ccli8 21:dfd65207a645 221 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 222 if (err < 0) {
ccli8 21:dfd65207a645 223 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 21:dfd65207a645 224 }
ccli8 21:dfd65207a645 225
ccli8 21:dfd65207a645 226 // Tidy up
ccli8 21:dfd65207a645 227 printf("Unmounting... ");
ccli8 21:dfd65207a645 228 fflush(stdout);
ccli8 21:dfd65207a645 229 err = fs.unmount();
ccli8 21:dfd65207a645 230 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 21:dfd65207a645 231 if (err < 0) {
ccli8 21:dfd65207a645 232 error("error: %s (%d)\n", strerror(-err), err);
ccli8 21:dfd65207a645 233 }
ccli8 21:dfd65207a645 234
ccli8 21:dfd65207a645 235 printf("Mbed OS filesystem example done!\n");
ccli8 21:dfd65207a645 236 }
ccli8 21:dfd65207a645 237