Examples please for LittleFS

I was pleased to read on the Arduino GIGA R1 Cheat Sheet that:

The GIGA firmware has full support for FATFS and littleFS.

Please can someone point me to any examples showing how to write data and read it back using LittleFS, preferably using the 16MB External Flash Storage.

I suggest you:

  • G oogle "littleFS"
  • The first hit you see will be to github. Click on that link and read away...

Thanks for the reply. Sorry, I didn't explain clearly enough:

I already have code that works with LittleFS on other platforms (Teensy40/41, Raspberry Pi Pico, ESP32), but I can't get it to work on the GIGA, and I was hoping for a working example on that platform.

OK, Have you been able to get anything working on the GiGa? If not I suggest the venerable "blink without delay" example in the IDE file/examples. This will prove you have the proper board driver installed.
Otherwise, please state what you mean but "can't get it to work". Compile? operate etc. Can you get the SD to work with the SD.h or SDFat.h libraries?

Here's a LittleFS test program that works fine on the IMXRT1062-based Teensy 4.0. It writes four bytes to a file "Test" on LittleFS and then reads them back:

#include <LittleFS.h>
LittleFS_Program LittleFS;
  
void setup() {
  Serial.begin(9600);
  delay(3000);
  LittleFS.begin(1024);
}

void loop() {
  File file;
  uint8_t u8[4] = {12, 34, 56, 78};
  Serial.println("Write");
  file = LittleFS.open("Test", FILE_WRITE_BEGIN);
  if (file.write(u8, 4) != 4) Serial.println("Not enough room");
  else Serial.println("Success");
  file.close();
  //
  Serial.println("Read");
  file = LittleFS.open("Test", FILE_READ);
  file.read(u8, 4);
  if (u8[0]==12 && u8[1]==34 && u8[2]==56 && u8[3]==78) Serial.println("Success");
  file.close();
  for(;;);
}

Running it on the GIGA produces the following error:

LittleFS.h: No such file or directory

Looking in the GIGA core I suspect it should be:

#include <LittleFileSystem.h>

I then get a large number of further errors, including:

error: 'LittleFS' was not declared in this scope
error: 'File' was not declared in this scope

Any suggestions?

I would reply on git hub. I tired a different example that called lfs.h but still had some function that were not defined. BTW I tried to compile on the Pro mini thinking this was the most "vanilla" platform.

OK, thanks!

I just bought the Arduino Giga R1 WiFi board. I too am looking for examples of how to use the board.... it said it has full support for FATS and litteFS.

Hi @johnsondavies and @tom2020. The support comes from the open source Mbed OS operating system upon which the GIGA R1 WiFi's core is built. So you can find information in the Mbed OS documentation:

https://os.mbed.com/docs/mbed-os/v6.16/apis/littlefilesystem.html

Here is a demonstration sketch:

// See: https://os.mbed.com/docs/mbed-os/v6.16/apis/littlefilesystem.html
#include <BlockDevice.h>
#include <LittleFileSystem.h>

// See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_block_device.html#a273b2bb1fbb436880f0a8b064d585c40
mbed::BlockDevice *blockDevice = mbed::BlockDevice::get_default_instance();

// See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#abb1dbb2aff57c38d30d3d9aa1261b927
mbed::LittleFileSystem fs("fs");

void setup() {
  Serial.begin(9600);
  while (!Serial) {}

  Serial.println("Mounting the filesystem...");
  // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#af010c3cc72199df51974f4547f088180
  int mountError = fs.mount(blockDevice);
  if (mountError) {
    Serial.println("Mounting failed. Reformatting...");
    // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#a167b7a8d9704e9370090231e92f37144
    int reformatError = fs.reformat(blockDevice);
    if (reformatError) {
      Serial.print("Reformatting failed: ");
      // See: https://cplusplus.com/reference/cstring/strerror/
      Serial.print(strerror(-reformatError));
      Serial.print(" (");
      Serial.print(reformatError);
      Serial.println(")");
      while (true) {}
    }
  }

  char filePath[] = "/fs/foo.txt";
  Serial.print("Opening \"");
  Serial.print(filePath);
  Serial.println("\"...");
  // See: https://cplusplus.com/reference/cstdio/FILE/
  FILE *fileStream = fopen(filePath, "w+");
  if (!fileStream) {
    Serial.print("Opening file failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  int writeValue = random(100);
  Serial.print("Writing random value ");
  Serial.print(writeValue);
  Serial.println(" to file...");
  // See: https://cplusplus.com/reference/cstdio/fprintf/
  int writeError = fprintf(fileStream, "%d", writeValue);
  if (writeError < 0) {
    Serial.print("Writing failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  Serial.println("Reading file...");
  // See: https://cplusplus.com/reference/cstdio/rewind/
  rewind(fileStream);
  int readValue;
  // See: https://cplusplus.com/reference/cstdio/fscanf/
  int readError = fscanf(fileStream, "%d", &readValue);
  if (readError < 0) {
    Serial.print("Read failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }
  Serial.print("Read value: ");
  Serial.println(readValue);

  Serial.print("Closing \"");
  Serial.print(filePath);
  Serial.println("\"...");
  int closeError = fclose(fileStream);
  if (closeError) {
    Serial.print("Closing failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  Serial.println("Unmounting the filesystem...");
  // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#a961e8d67f5128ba463e075889bcf03ed
  int unmountError = fs.unmount();
  if (unmountError) {
    Serial.print("Unmounting failed: ");
    Serial.print(strerror(-unmountError));
    Serial.print(" (");
    Serial.print(unmountError);
    Serial.println(")");
    while (true) {}
  }
}

void loop() {}
1 Like

Thank you for the example.
I have been trying to modify your code to write a string, read a string. I just can't get it to work. ... replaced %d. with %s..... changed readValue, writeValue to Strings.

It should work with C strings. However %s has an annoying behavior:

stopping at the first whitespace character found

So if the string written to the file is "Hello, world!", then you will only read "Hello,".

So I think that fgets will be more suitable for reading an arbitrary string from the file. Give this a try:

// See: https://os.mbed.com/docs/mbed-os/v6.16/apis/littlefilesystem.html
#include <BlockDevice.h>
#include <LittleFileSystem.h>

// See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_block_device.html#a273b2bb1fbb436880f0a8b064d585c40
mbed::BlockDevice *blockDevice = mbed::BlockDevice::get_default_instance();

// See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#abb1dbb2aff57c38d30d3d9aa1261b927
mbed::LittleFileSystem fs("fs");

void setup() {
  Serial.begin(9600);
  while (!Serial) {}

  Serial.println("Mounting the filesystem...");
  // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#af010c3cc72199df51974f4547f088180
  int mountError = fs.mount(blockDevice);
  if (mountError) {
    Serial.println("Mounting failed. Reformatting...");
    // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#a167b7a8d9704e9370090231e92f37144
    int reformatError = fs.reformat(blockDevice);
    if (reformatError) {
      Serial.print("Reformatting failed: ");
      // See: https://cplusplus.com/reference/cstring/strerror/
      Serial.print(strerror(-reformatError));
      Serial.print(" (");
      Serial.print(reformatError);
      Serial.println(")");
      while (true) {}
    }
  }

  char filePath[] = "/fs/foo.txt";
  Serial.print("Opening \"");
  Serial.print(filePath);
  Serial.println("\"...");
  // See: https://cplusplus.com/reference/cstdio/FILE/
  FILE *fileStream = fopen(filePath, "w+");
  if (!fileStream) {
    Serial.print("Opening file failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  char writeValue[] = "Hello, world!\n";
  Serial.print("Writing \"");
  Serial.print(writeValue);
  Serial.println("\" to file...");
  // See: https://cplusplus.com/reference/cstdio/fprintf/
  int writeError = fprintf(fileStream, "%s", writeValue);
  if (writeError < 0) {
    Serial.print("Writing failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  Serial.println("Reading file...");
  // See: https://cplusplus.com/reference/cstdio/rewind/
  rewind(fileStream);
  char readValue[42]; // Allocate a buffer large enough to hold the data to be read.
  // See: https://cplusplus.com/reference/cstdio/fgets/
  fgets(readValue, sizeof(readValue)-1, fileStream);
  Serial.print("Read value: ");
  Serial.println(readValue);

  Serial.print("Closing \"");
  Serial.print(filePath);
  Serial.println("\"...");
  int closeError = fclose(fileStream);
  if (closeError) {
    Serial.print("Closing failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  Serial.println("Unmounting the filesystem...");
  // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#a961e8d67f5128ba463e075889bcf03ed
  int unmountError = fs.unmount();
  if (unmountError) {
    Serial.print("Unmounting failed: ");
    Serial.print(strerror(-unmountError));
    Serial.print(" (");
    Serial.print(unmountError);
    Serial.println(")");
    while (true) {}
  }
}

void loop() {}

I recommend just using normal char arrays (C strings) instead of the Arduino String class.

thanks. That was quick!

Isn't file file system supposed to keep data from power on /power off?

I ran your code .... then I removed the "write code". The read code did NOT return "Hello World". I get a ? mark with black background.

I've made some minor adjustment to original code (post #9) by @ptillisch and now it functions correctly

Serial.println();
  Serial.println("Mounting the filesystem...");
  // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#af010c3cc72199df51974f4547f088180
  int mountError = fs.mount(blockDevice);
  if (mountError) {
    Serial.println("Mounting failed. Reformatting...");
    // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#a167b7a8d9704e9370090231e92f37144
    int reformatError = fs.reformat(blockDevice);
    if (reformatError) {
      Serial.print("Reformatting failed: ");
      // See: https://cplusplus.com/reference/cstring/strerror/
      Serial.print(strerror(-reformatError));
      Serial.print(" (");
      Serial.print(reformatError);
      Serial.println(")");
      while (true) {}
    }
  }

  char filePath[] = "/fs/foo.txt";
  Serial.print("Opening \"");
  Serial.print(filePath);
  Serial.println("\"...");
  // See: https://cplusplus.com/reference/cstdio/FILE/
  FILE *fileStream = fopen(filePath, "r+");
  if (!fileStream) {
    Serial.print("Opening file failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    fileStream = fopen(filePath, "w+");
    if (!fileStream) {
      Serial.print("Opening file failed: ");
      Serial.print(strerror(errno));
      Serial.print(" (");
      Serial.print(-errno);
      Serial.println(")");
      while (true) {}
    }
    int writeValue = random(100);
    Serial.print("Writing random value ");
    Serial.print(writeValue);
    Serial.println(" to file...");
    // See: https://cplusplus.com/reference/cstdio/fprintf/
    int writeError = fprintf(fileStream, "%d", writeValue);
    if (writeError < 0) {
      Serial.print("Writing failed: ");
      Serial.print(strerror(errno));
      Serial.print(" (");
      Serial.print(-errno);
      Serial.println(")");
      while (true) {}
    }
  } else {
    Serial.println("Reading file...");
    // See: https://cplusplus.com/reference/cstdio/rewind/
    rewind(fileStream);
    int readValue;
    // See: https://cplusplus.com/reference/cstdio/fscanf/
    int readError = fscanf(fileStream, "%d", &readValue);
    if (readError < 0) {
      Serial.print("Read failed: ");
      Serial.print(strerror(errno));
      Serial.print(" (");
      Serial.print(-errno);
      Serial.println(")");
      //while (true) {}
    } else {
      Serial.print("Read value: ");
      Serial.println(readValue);
    }
  }

  Serial.print("Closing \"");
  Serial.print(filePath);
  Serial.println("\"...");
  int closeError = fclose(fileStream);
  if (closeError) {
    Serial.print("Closing failed: ");
    Serial.print(strerror(errno));
    Serial.print(" (");
    Serial.print(-errno);
    Serial.println(")");
    while (true) {}
  }

  Serial.println("Unmounting the filesystem...");
  // See: https://os.mbed.com/docs/mbed-os/v6.16/mbed-os-api-doxy/classmbed_1_1_little_file_system.html#a961e8d67f5128ba463e075889bcf03ed
  int unmountError = fs.unmount();
  if (unmountError) {
    Serial.print("Unmounting failed: ");
    Serial.print(strerror(-unmountError));
    Serial.print(" (");
    Serial.print(unmountError);
    Serial.println(")");
    while (true) {}
  }

instead of immediately calling _type "w+" under function fopen(), you first use _type "r+" to check whether the file exist or not. If not exist, proceed use "w+" to create file and write data on to it. The next time you run the code or you cycle the power to the board, it'll read the previous data stored on the blocked flash.