Description
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.