NuMaker SPI flash-backed file system

Committer:
ccli8
Date:
Thu Jan 11 14:39:17 2018 +0800
Revision:
1:772d0adf75cc
Child:
3:977ed4dda7da
Support NUC472/M453/M487/NANO130

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 1:772d0adf75cc 30
ccli8 1:772d0adf75cc 31 // Physical block device, can be any device that supports the BlockDevice API
ccli8 1:772d0adf75cc 32 #if MBED_CONF_APP_ONBOARD_SPIF
ccli8 1:772d0adf75cc 33 /* Some targets, e.g. NUMAKER_PFM_M487 support on-board SPI flash. */
ccli8 1:772d0adf75cc 34 SPIFBlockDevice bd(MBED_CONF_APP_ONBOARD_SPI_MOSI,
ccli8 1:772d0adf75cc 35 MBED_CONF_APP_ONBOARD_SPI_MISO,
ccli8 1:772d0adf75cc 36 MBED_CONF_APP_ONBOARD_SPI_CLK,
ccli8 1:772d0adf75cc 37 MBED_CONF_APP_ONBOARD_SPI_CS);
ccli8 1:772d0adf75cc 38
ccli8 1:772d0adf75cc 39 #if defined(TARGET_NUMAKER_PFM_M487)
ccli8 1:772d0adf75cc 40 /* We needn't write-protect and hold functions. Configure /WP and /HOLD pins to high. */
ccli8 1:772d0adf75cc 41 DigitalOut onboard_spi_wp(PC_5, 1);
ccli8 1:772d0adf75cc 42 DigitalOut onboard_spi_hold(PC_4, 1);
ccli8 1:772d0adf75cc 43 #endif
ccli8 1:772d0adf75cc 44 #else
ccli8 1:772d0adf75cc 45 /* Externally attached SPI flash */
ccli8 1:772d0adf75cc 46 SPIFBlockDevice bd(MBED_CONF_APP_SPI_MOSI,
ccli8 1:772d0adf75cc 47 MBED_CONF_APP_SPI_MISO,
ccli8 1:772d0adf75cc 48 MBED_CONF_APP_SPI_CLK,
ccli8 1:772d0adf75cc 49 MBED_CONF_APP_SPI_CS);
ccli8 1:772d0adf75cc 50 #endif
ccli8 1:772d0adf75cc 51
ccli8 1:772d0adf75cc 52 // File system declaration
ccli8 1:772d0adf75cc 53 LittleFileSystem fs("fs");
ccli8 1:772d0adf75cc 54
ccli8 1:772d0adf75cc 55
ccli8 1:772d0adf75cc 56 // Set up the button to trigger an erase
ccli8 1:772d0adf75cc 57 InterruptIn irq(BUTTON1);
ccli8 1:772d0adf75cc 58 void erase() {
ccli8 1:772d0adf75cc 59 printf("Initializing the block device... ");
ccli8 1:772d0adf75cc 60 fflush(stdout);
ccli8 1:772d0adf75cc 61 int err = bd.init();
ccli8 1:772d0adf75cc 62 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 63 if (err) {
ccli8 1:772d0adf75cc 64 error("error: %s (%d)\n", strerror(-err), err);
ccli8 1:772d0adf75cc 65 }
ccli8 1:772d0adf75cc 66
ccli8 1:772d0adf75cc 67 printf("Erasing the block device... ");
ccli8 1:772d0adf75cc 68 fflush(stdout);
ccli8 1:772d0adf75cc 69 err = bd.erase(0, bd.size());
ccli8 1:772d0adf75cc 70 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 71 if (err) {
ccli8 1:772d0adf75cc 72 error("error: %s (%d)\n", strerror(-err), err);
ccli8 1:772d0adf75cc 73 }
ccli8 1:772d0adf75cc 74
ccli8 1:772d0adf75cc 75 printf("Deinitializing the block device... ");
ccli8 1:772d0adf75cc 76 fflush(stdout);
ccli8 1:772d0adf75cc 77 err = bd.deinit();
ccli8 1:772d0adf75cc 78 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 79 if (err) {
ccli8 1:772d0adf75cc 80 error("error: %s (%d)\n", strerror(-err), err);
ccli8 1:772d0adf75cc 81 }
ccli8 1:772d0adf75cc 82 }
ccli8 1:772d0adf75cc 83
ccli8 1:772d0adf75cc 84
ccli8 1:772d0adf75cc 85 // Entry point for the example
ccli8 1:772d0adf75cc 86 int main() {
ccli8 1:772d0adf75cc 87 printf("--- Mbed OS filesystem example ---\n");
ccli8 1:772d0adf75cc 88
ccli8 1:772d0adf75cc 89 // Setup the irq in case we want to use it
ccli8 1:772d0adf75cc 90 irq.fall(erase);
ccli8 1:772d0adf75cc 91
ccli8 1:772d0adf75cc 92 // Try to mount the filesystem
ccli8 1:772d0adf75cc 93 printf("Mounting the filesystem... ");
ccli8 1:772d0adf75cc 94 fflush(stdout);
ccli8 1:772d0adf75cc 95 int err = fs.mount(&bd);
ccli8 1:772d0adf75cc 96 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 97 if (err) {
ccli8 1:772d0adf75cc 98 // Reformat if we can't mount the filesystem
ccli8 1:772d0adf75cc 99 // this should only happen on the first boot
ccli8 1:772d0adf75cc 100 printf("No filesystem found, formatting... ");
ccli8 1:772d0adf75cc 101 fflush(stdout);
ccli8 1:772d0adf75cc 102 err = fs.reformat(&bd);
ccli8 1:772d0adf75cc 103 printf("%s\n", (err ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 104 if (err) {
ccli8 1:772d0adf75cc 105 error("error: %s (%d)\n", strerror(-err), err);
ccli8 1:772d0adf75cc 106 }
ccli8 1:772d0adf75cc 107 }
ccli8 1:772d0adf75cc 108
ccli8 1:772d0adf75cc 109 // Open the numbers file
ccli8 1:772d0adf75cc 110 printf("Opening \"/fs/numbers.txt\"... ");
ccli8 1:772d0adf75cc 111 fflush(stdout);
ccli8 1:772d0adf75cc 112 FILE *f = fopen("/fs/numbers.txt", "r+");
ccli8 1:772d0adf75cc 113 printf("%s\n", (!f ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 114 if (!f) {
ccli8 1:772d0adf75cc 115 // Create the numbers file if it doesn't exist
ccli8 1:772d0adf75cc 116 printf("No file found, creating a new file... ");
ccli8 1:772d0adf75cc 117 fflush(stdout);
ccli8 1:772d0adf75cc 118 f = fopen("/fs/numbers.txt", "w+");
ccli8 1:772d0adf75cc 119 printf("%s\n", (!f ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 120 if (!f) {
ccli8 1:772d0adf75cc 121 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 122 }
ccli8 1:772d0adf75cc 123
ccli8 1:772d0adf75cc 124 for (int i = 0; i < 10; i++) {
ccli8 1:772d0adf75cc 125 printf("\rWriting numbers (%d/%d)... ", i, 10);
ccli8 1:772d0adf75cc 126 fflush(stdout);
ccli8 1:772d0adf75cc 127 err = fprintf(f, " %d\n", i);
ccli8 1:772d0adf75cc 128 if (err < 0) {
ccli8 1:772d0adf75cc 129 printf("Fail :(\n");
ccli8 1:772d0adf75cc 130 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 131 }
ccli8 1:772d0adf75cc 132 }
ccli8 1:772d0adf75cc 133 printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);
ccli8 1:772d0adf75cc 134
ccli8 1:772d0adf75cc 135 printf("Seeking file... ");
ccli8 1:772d0adf75cc 136 fflush(stdout);
ccli8 1:772d0adf75cc 137 err = fseek(f, 0, SEEK_SET);
ccli8 1:772d0adf75cc 138 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 139 if (err < 0) {
ccli8 1:772d0adf75cc 140 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 141 }
ccli8 1:772d0adf75cc 142 }
ccli8 1:772d0adf75cc 143
ccli8 1:772d0adf75cc 144 // Go through and increment the numbers
ccli8 1:772d0adf75cc 145 for (int i = 0; i < 10; i++) {
ccli8 1:772d0adf75cc 146 printf("\rIncrementing numbers (%d/%d)... ", i, 10);
ccli8 1:772d0adf75cc 147 fflush(stdout);
ccli8 1:772d0adf75cc 148
ccli8 1:772d0adf75cc 149 // Get current stream position
ccli8 1:772d0adf75cc 150 long pos = ftell(f);
ccli8 1:772d0adf75cc 151
ccli8 1:772d0adf75cc 152 // Parse out the number and increment
ccli8 1:772d0adf75cc 153 int32_t number;
ccli8 1:772d0adf75cc 154 fscanf(f, "%d", &number);
ccli8 1:772d0adf75cc 155 number += 1;
ccli8 1:772d0adf75cc 156
ccli8 1:772d0adf75cc 157 // Seek to beginning of number
ccli8 1:772d0adf75cc 158 fseek(f, pos, SEEK_SET);
ccli8 1:772d0adf75cc 159
ccli8 1:772d0adf75cc 160 // Store number
ccli8 1:772d0adf75cc 161 fprintf(f, " %d\n", number);
ccli8 1:772d0adf75cc 162 }
ccli8 1:772d0adf75cc 163 printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
ccli8 1:772d0adf75cc 164
ccli8 1:772d0adf75cc 165 // Close the file which also flushes any cached writes
ccli8 1:772d0adf75cc 166 printf("Closing \"/fs/numbers.txt\"... ");
ccli8 1:772d0adf75cc 167 fflush(stdout);
ccli8 1:772d0adf75cc 168 err = fclose(f);
ccli8 1:772d0adf75cc 169 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 170 if (err < 0) {
ccli8 1:772d0adf75cc 171 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 172 }
ccli8 1:772d0adf75cc 173
ccli8 1:772d0adf75cc 174 // Display the root directory
ccli8 1:772d0adf75cc 175 printf("Opening the root directory... ");
ccli8 1:772d0adf75cc 176 fflush(stdout);
ccli8 1:772d0adf75cc 177 DIR *d = opendir("/fs/");
ccli8 1:772d0adf75cc 178 printf("%s\n", (!d ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 179 if (!d) {
ccli8 1:772d0adf75cc 180 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 181 }
ccli8 1:772d0adf75cc 182
ccli8 1:772d0adf75cc 183 printf("root directory:\n");
ccli8 1:772d0adf75cc 184 while (true) {
ccli8 1:772d0adf75cc 185 struct dirent *e = readdir(d);
ccli8 1:772d0adf75cc 186 if (!e) {
ccli8 1:772d0adf75cc 187 break;
ccli8 1:772d0adf75cc 188 }
ccli8 1:772d0adf75cc 189
ccli8 1:772d0adf75cc 190 printf(" %s\n", e->d_name);
ccli8 1:772d0adf75cc 191 }
ccli8 1:772d0adf75cc 192
ccli8 1:772d0adf75cc 193 printf("Closing the root directory... ");
ccli8 1:772d0adf75cc 194 fflush(stdout);
ccli8 1:772d0adf75cc 195 err = closedir(d);
ccli8 1:772d0adf75cc 196 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 197 if (err < 0) {
ccli8 1:772d0adf75cc 198 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 199 }
ccli8 1:772d0adf75cc 200
ccli8 1:772d0adf75cc 201 // Display the numbers file
ccli8 1:772d0adf75cc 202 printf("Opening \"/fs/numbers.txt\"... ");
ccli8 1:772d0adf75cc 203 fflush(stdout);
ccli8 1:772d0adf75cc 204 f = fopen("/fs/numbers.txt", "r");
ccli8 1:772d0adf75cc 205 printf("%s\n", (!f ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 206 if (!f) {
ccli8 1:772d0adf75cc 207 error("error: %s (%d)\n", strerror(errno), -errno);
ccli8 1:772d0adf75cc 208 }
ccli8 1:772d0adf75cc 209
ccli8 1:772d0adf75cc 210 printf("numbers:\n");
ccli8 1:772d0adf75cc 211 while (!feof(f)) {
ccli8 1:772d0adf75cc 212 int c = fgetc(f);
ccli8 1:772d0adf75cc 213 printf("%c", c);
ccli8 1:772d0adf75cc 214 }
ccli8 1:772d0adf75cc 215
ccli8 1:772d0adf75cc 216 printf("\rClosing \"/fs/numbers.txt\"... ");
ccli8 1:772d0adf75cc 217 fflush(stdout);
ccli8 1:772d0adf75cc 218 err = fclose(f);
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(errno), -errno);
ccli8 1:772d0adf75cc 222 }
ccli8 1:772d0adf75cc 223
ccli8 1:772d0adf75cc 224 // Tidy up
ccli8 1:772d0adf75cc 225 printf("Unmounting... ");
ccli8 1:772d0adf75cc 226 fflush(stdout);
ccli8 1:772d0adf75cc 227 err = fs.unmount();
ccli8 1:772d0adf75cc 228 printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
ccli8 1:772d0adf75cc 229 if (err < 0) {
ccli8 1:772d0adf75cc 230 error("error: %s (%d)\n", strerror(-err), err);
ccli8 1:772d0adf75cc 231 }
ccli8 1:772d0adf75cc 232
ccli8 1:772d0adf75cc 233 printf("Mbed OS filesystem example done!\n");
ccli8 1:772d0adf75cc 234 }
ccli8 1:772d0adf75cc 235