NuMaker SPI flash-backed file system

Committer:
ccli8
Date:
Mon Nov 04 18:40:57 2019 +0800
Revision:
4:df65a888a785
Parent:
3:977ed4dda7da
Child:
5:af8e8a91a373
Support NUMAKER_IOT_M487

Who changed what in which revision?

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