Skip to content

Document LittleFS path length limitation #42

Open
@aliphys

Description

@aliphys

Following testing with both Renesas configurations (Portenta C33 with Vision Shield & Breakout) as well as mbed (Portenta H7 + Vision Shield), it is observed that the maximum path length is 255 characters. This limitation is present for LittleFS partitions on internal storage, SD and USB.

This limitation, if part of design, should be documented.

This is demonstrated through the test sketches below which creates a 255/256 character file (including the extension) and then reads it. As a representative example, the following two sketches are provided for the Portenta H7 with the Vision Shield and internal storage. Similar observations are made for the Portenta C33 as well as USB and SD storage.

255 Character Filename - PASS

Sketch
#include "Arduino_UnifiedStorage.h"
#include "CRC.h" // https://github.com/RobTillaart/CRC

InternalStorage storage;
CRC8 crc;

const char testCaseID[] = "AUS_SPIS_FNBLFS_009";

void setup() {
  Serial.begin(115200);
  while (!Serial);

  Serial.println("---");
  Serial.print("Test Case ID: ");
  Serial.println(testCaseID);
  Serial.println("---");

  Arduino_UnifiedStorage::debuggingModeEnabled = false;  
  if (Arduino_UnifiedStorage::debuggingModeEnabled) {
    Serial.println("Arduino_UnifiedStorage debug messages ON.");
  }

  storage = InternalStorage();
  storage.format(FS_LITTLEFS);
  if(!storage.begin()){
    Serial.println("Error mounting storage device.");
  }

  // specify Test strings & CRC
  const char testContent[] = "Hello World!";
  for (int i = 0; i < strlen(testContent); i++) {
    crc.add(testContent[i]);
  }
  uint8_t testContentCRC8 = crc.calc();
  crc.reset();
  Serial.println("testContent value:" + String(testContent) + ". With CRC value:" + String(testContentCRC8));

  const char testFilename[] = "255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255.txt";
  for (int i = 0; i < strlen(testFilename); i++) {
    crc.add(testFilename[i]);
  }
  uint8_t testFilenameCRC8 = crc.calc();
  crc.reset();
  Serial.println("testFilename value:" + String(testFilename) + ". With CRC value:" + String(testFilenameCRC8));

  // Create empty file and set to WRITE mode
  Folder root = storage.getRootFolder();
  UFile file1 = root.createFile(testFilename, FileMode::WRITE);
 
  file1.write(testContent);
  file1.changeMode(FileMode::READ);

  file1.seek(0);
  String dataRead = "";
  while (file1.available()) {
    char data = file1.read();
    crc.add(data);
    dataRead += data;
  }
  Serial.println();

  uint8_t dataReadCRC = crc.calc();

  Serial.println("Files found:");
  std::vector<UFile> files = root.getFiles();
  // Print files
  for (UFile file : files) {
    Serial.print("[F] ");
    Serial.println(file.getPath());
  }

  Serial.println("Data read was " + dataRead + " with CRC value " + String(dataReadCRC));

}

void loop() {

}

Serial Monitor

---
Test Case ID: AUS_SPIS_FNBLFS_009
---
testContent value:Hello World!. With CRC value:28
testFilename value:255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255.txt. With CRC value:127

Files found:
[F] /internal/255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255chars255.txt
Data read was Hello World! with CRC value 28

256 Character Filename - FAIL

Sketch
  #include "Arduino_UnifiedStorage.h"
#include "CRC.h" // https://github.com/RobTillaart/CRC

InternalStorage storage;
CRC8 crc;

const char testCaseID[] = "AUS_SPIS_FNBLFS_010";

void setup() {
  Serial.begin(115200);
  while (!Serial);

  Serial.println("---");
  Serial.print("Test Case ID: ");
  Serial.println(testCaseID);
  Serial.println("---");

  Arduino_UnifiedStorage::debuggingModeEnabled = false;  
  if (Arduino_UnifiedStorage::debuggingModeEnabled) {
    Serial.println("Arduino_UnifiedStorage debug messages ON.");
  }

  storage = InternalStorage();
  storage.format(FS_LITTLEFS);
  if(!storage.begin()){
    Serial.println("Error mounting storage device.");
  }

  // specify Test strings & CRC
  const char testContent[] = "Hello World!";
  for (int i = 0; i < strlen(testContent); i++) {
    crc.add(testContent[i]);
  }
  uint8_t testContentCRC8 = crc.calc();
  crc.reset();
  Serial.println("testContent value:" + String(testContent) + ". With CRC value:" + String(testContentCRC8));

  const char testFilename[] = "256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256c.txt";
  for (int i = 0; i < strlen(testFilename); i++) {
    crc.add(testFilename[i]);
  }
  uint8_t testFilenameCRC8 = crc.calc();
  crc.reset();
  Serial.println("testFilename value:" + String(testFilename) + ". With CRC value:" + String(testFilenameCRC8));

  // Create empty file and set to WRITE mode
  Folder root = storage.getRootFolder();
  UFile file1 = root.createFile(testFilename, FileMode::WRITE);
 
  file1.write(testContent);
  file1.changeMode(FileMode::READ);

  file1.seek(0);
  String dataRead = "";
  while (file1.available()) {
    char data = file1.read();
    crc.add(data);
    dataRead += data;
  }
  Serial.println();

  uint8_t dataReadCRC = crc.calc();

  Serial.println("Files found:");
  std::vector<UFile> files = root.getFiles();
  // Print files
  for (UFile file : files) {
    Serial.print("[F] ");
    Serial.println(file.getPath());
  }

  Serial.println("Data read was " + dataRead + " with CRC value " + String(dataReadCRC));

}

void loop() {

}

Serial Monitor
---
Test Case ID: AUS_SPIS_FNBLFS_010
---
testContent value:Hello World!. With CRC value:28
testFilename value:256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256chars256c.txt. With CRC value:182

Files found:
[F] /internal/
Data read was  with CRC value 0

Additional information

On the Renasas core (Portenta C33), the LittleFS driver sets the maximum character length to 255 characters via LFS_NAME_MAX.

// Maximum name size in bytes, may be redefined to reduce the size of the
// info struct. Limited to <= 1022. Stored in superblock and must be
// respected by other littlefs drivers.
#ifndef LFS_NAME_MAX
#define LFS_NAME_MAX 255
#endif

On the mbed core (Portenta H7), the LittleFS driver also sets the maximum character length to 255 characters via LFS_NAME_MAX.


// Max name size in bytes
#ifndef LFS_NAME_MAX
#define LFS_NAME_MAX 255
#endif

In both cases for both the mbed and Renasas core, a lfs_info structure adds an addtion byte LFS_NAME_MAX+1 to account for a null terminated string that corresponds to the test outcome.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions