Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Wrapper of LittleFS for Arduino MBED Portenta_H7 boards. This library facilitates your usage of LittleFS for the onboard flash. LittleFS supports power fail safety and high performance

License

Notifications You must be signed in to change notification settings

khoih-prog/LittleFS_Portenta_H7

Repository files navigation

LittleFS_Portenta_H7 Library

arduino-library-badge GitHub release GitHub contributions welcome GitHub issues

Donate to my libraries using BuyMeACoffee



Table of Contents



Important Notes for Portenta_H7

The LittleFS of the new Portenta_H7 board currently tested OK with only maximum 8 files. The files, from 9 and up, somehow strangely can't be written and / or read. This is possibly a bug in the ArduinoCore-mbed mbed_portenta core. The same behaviour is observed from core v2.0.0 up to v2.6.1.

If LittleFS size is reduced to 1024KB, test is OK with only maximum 4 files.

Beware and keep checking for updates.



Why do we need this LittleFS_Portenta_H7 library

Features

This library is just a simple LittleFS wrapper to facilitate your usage of LittleFS for the onboard flash on MBED Portenta_H7, using ArduinoCore-mbed mbed_portenta core

The filesystem access uses normal POSIX APIs or mbed FileSystem APIs


Currently supported Boards

  1. Portenta_H7 boards such as Portenta_H7 Rev2 ABX00042, etc., using ArduinoCore-mbed mbed_portenta core


Prerequisites

  1. Arduino IDE 1.8.19+ for Arduino. GitHub release
  2. ArduinoCore-mbed mbed_portenta core 3.4.1+ for Arduino Portenta_H7 boards, such as Portenta_H7 Rev2 ABX00042, etc.. GitHub release


Installation

Use Arduino Library Manager

The best and easiest way is to use Arduino Library Manager. Search for LittleFS_Portenta_H7, then select / install the latest version. You can also use this link arduino-library-badge for more detailed instructions.

Manual Install

Another way to install is to:

  1. Navigate to LittleFS_Portenta_H7 page.
  2. Download the latest release LittleFS_Portenta_H7-main.zip.
  3. Extract the zip file to LittleFS_Portenta_H7-main directory
  4. Copy whole LittleFS_Portenta_H7-main folder to Arduino libraries' directory such as ~/Arduino/libraries/.

VS Code & PlatformIO

  1. Install VS Code
  2. Install PlatformIO
  3. Install LittleFS_Portenta_H7 library by using Library Manager. Search for LittleFS_Portenta_H7 in Platform.io Author's Libraries
  4. Use included platformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at Project Configuration File


Packages' Patches

1. For Portenta_H7 boards using Arduino IDE in Linux

To be able to upload firmware to Portenta_H7 using Arduino IDE in Linux (Ubuntu, etc.), you have to copy the file portenta_post_install.sh into mbed_portenta directory (~/.arduino15/packages/arduino/hardware/mbed_portenta/3.4.1/portenta_post_install.sh).

Then run the following command using sudo

$ cd ~/.arduino15/packages/arduino/hardware/mbed_portenta/3.4.1
$ chmod 755 portenta_post_install.sh
$ sudo ./portenta_post_install.sh

This will create the file /etc/udev/rules.d/49-portenta_h7.rules as follows:

# Portenta H7 bootloader mode UDEV rules

SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="035b", GROUP="plugdev", MODE="0666"

Supposing the ArduinoCore-mbed core version is 3.4.1. Now only one file must be copied into the directory:

  • ~/.arduino15/packages/arduino/hardware/mbed_portenta/3.4.1/portenta_post_install.sh

Whenever a new version is installed, remember to copy this files into the new version directory. For example, new version is x.yy.zz

This file must be copied into the directory:

  • ~/.arduino15/packages/arduino/hardware/mbed_portenta/x.yy.zz/portenta_post_install.sh


Examples

  1. LittleFS_Counting
  2. LittleFS_test


#define LFS_MBED_PORTENTA_H7_VERSION_MIN_TARGET "LittleFS_Portenta_H7 v1.2.0"
#define LFS_MBED_PORTENTA_H7_VERSION_MIN 1002000
#define _LFS_LOGLEVEL_ 1
#define FORCE_REFORMAT false
#include <LittleFS_Portenta_H7.h>
LittleFS_MBED *myFS;
uint32_t FILE_SIZE_KB = 64;
void readCharsFromFile(const char * path)
{
Serial.print("readCharsFromFile: "); Serial.print(path);
FILE *file = fopen(path, "r");
if (file)
{
Serial.println(" => Open OK");
}
else
{
Serial.println(" => Open Failed");
return;
}
char c;
while (true)
{
c = fgetc(file);
if ( feof(file) )
{
break;
}
else
Serial.print(c);
}
fclose(file);
}
void readFile(const char * path)
{
Serial.print("Reading file: "); Serial.print(path);
FILE *file = fopen(path, "r");
if (file)
{
Serial.println(" => Open OK");
}
else
{
Serial.println(" => Open Failed");
return;
}
char c;
uint32_t numRead = 1;
while (numRead)
{
numRead = fread((uint8_t *) &c, sizeof(c), 1, file);
if (numRead)
Serial.print(c);
}
fclose(file);
}
void writeFile(const char * path, const char * message, size_t messageSize)
{
Serial.print("Writing file: "); Serial.print(path);
FILE *file = fopen(path, "w");
if (file)
{
Serial.println(" => Open OK");
}
else
{
Serial.println(" => Open Failed");
return;
}
if (fwrite((uint8_t *) message, 1, messageSize, file))
{
Serial.println("* Writing OK");
}
else
{
Serial.println("* Writing failed");
}
fclose(file);
}
void appendFile(const char * path, const char * message, size_t messageSize)
{
Serial.print("Appending file: "); Serial.print(path);
FILE *file = fopen(path, "a");
if (file)
{
Serial.println(" => Open OK");
}
else
{
Serial.println(" => Open Failed");
return;
}
if (fwrite((uint8_t *) message, 1, messageSize, file))
{
Serial.println("* Appending OK");
}
else
{
Serial.println("* Appending failed");
}
fclose(file);
}
void deleteFile(const char * path)
{
Serial.print("Deleting file: "); Serial.print(path);
if (remove(path) == 0)
{
Serial.println(" => OK");
}
else
{
Serial.println(" => Failed");
return;
}
}
void renameFile(const char * path1, const char * path2)
{
Serial.print("Renaming file: "); Serial.print(path1);
Serial.print(" to: "); Serial.print(path2);
if (rename(path1, path2) == 0)
{
Serial.println(" => OK");
}
else
{
Serial.println(" => Failed");
return;
}
}
void testFileIO(const char * path)
{
Serial.print("Testing file I/O with: "); Serial.print(path);
#define BUFF_SIZE 512
static uint8_t buf[BUFF_SIZE];
FILE *file = fopen(path, "w");
if (file)
{
Serial.println(" => Open OK");
}
else
{
Serial.println(" => Open Failed");
return;
}
size_t i;
Serial.println("- writing" );
uint32_t start = millis();
size_t result = 0;
// Write a file with FILE_SIZE_KB
for (i = 0; i < FILE_SIZE_KB * 2; i++)
{
result = fwrite(buf, BUFF_SIZE, 1, file);
if ( result != 1)
{
Serial.print("Write result = "); Serial.println(result);
Serial.print("Write error, i = "); Serial.println(i);
break;
}
}
Serial.println("");
uint32_t end = millis() - start;
Serial.print(i / 2);
Serial.print(" Kbytes written in (ms) ");
Serial.println(end);
fclose(file);
printLine();
/////////////////////////////////
file = fopen(path, "r");
start = millis();
end = start;
i = 0;
if (file)
{
start = millis();
Serial.println("- reading" );
result = 0;
fseek(file, 0, SEEK_SET);
// Read a file with FILE_SIZE_KB
for (i = 0; i < FILE_SIZE_KB * 2; i++)
{
result = fread(buf, BUFF_SIZE, 1, file);
if ( result != 1 )
{
Serial.print("Read result = "); Serial.println(result);
Serial.print("Read error, i = "); Serial.println(i);
break;
}
}
Serial.println("");
end = millis() - start;
Serial.print((i * BUFF_SIZE) / 1024);
Serial.print(" Kbytes read in (ms) ");
Serial.println(end);
fclose(file);
}
else
{
Serial.println("- failed to open file for reading");
}
}
void printLine()
{
Serial.println("====================================================");
}
void setup()
{
Serial.begin(115200);
while (!Serial)
delay(1000);
Serial.print("\nStart LittleFS_Test on "); Serial.println(BOARD_NAME);
Serial.println(LFS_MBED_PORTENTA_H7_VERSION);
#if defined(LFS_MBED_PORTENTA_H7_VERSION_MIN)
if (LFS_MBED_PORTENTA_H7_VERSION_INT < LFS_MBED_PORTENTA_H7_VERSION_MIN)
{
Serial.print("Warning. Must use this example on Version equal or later than : ");
Serial.println(LFS_MBED_PORTENTA_H7_VERSION_MIN_TARGET);
}
#endif
myFS = new LittleFS_MBED();
if (!myFS->init())
{
Serial.println("LITTLEFS Mount Failed");
return;
}
char fileName1[] = MBED_LITTLEFS_FILE_PREFIX "/hello1.txt";
char fileName2[] = MBED_LITTLEFS_FILE_PREFIX "/hello2.txt";
char message[] = "Hello from " BOARD_NAME "\n";
printLine();
writeFile(fileName1, message, sizeof(message));
printLine();
readFile(fileName1);
printLine();
appendFile(fileName1, message, sizeof(message));
printLine();
readFile(fileName1);
printLine();
renameFile(fileName1, fileName2);
printLine();
readCharsFromFile(fileName2);
printLine();
deleteFile(fileName2);
printLine();
readFile(fileName2);
printLine();
testFileIO(fileName1);
printLine();
testFileIO(fileName2);
printLine();
deleteFile(fileName1);
printLine();
deleteFile(fileName2);
printLine();
Serial.println( "\nTest complete" );
}
void loop()
{
}



Debug Terminal Output Samples

1. LittleFS_Counting on PORTENTA_H7_M7

The following is the sample terminal output when running example LittleFS_Counting on MBED PORTENTA_H7_M7

1.1 First run
Start LittleFS_Counting on PORTENTA_H7_M7
LittleFS_Portenta_H7 v1.2.0
[LFS] Flash Size: (KB) = 2048.00
[LFS] FlashIAP Start Address: = 0x0x8080000
[LFS] LittleFS size (KB) = 1536.00
[LFS] LittleFS Mount OK
Times have been run = 1
 => Open to write OK
1.2 After reset
Start LittleFS_Counting on PORTENTA_H7_M7
LittleFS_Portenta_H7 v1.2.0
[LFS] Flash Size: (KB) = 2048.00
[LFS] FlashIAP Start Address: = 0x0x8080000
[LFS] LittleFS size (KB) = 1536.00
[LFS] LittleFS Mount OK
 => Open to read OK
Times have been run = 2
 => Open to write OK

2. LittleFS_Test on PORTENTA_H7_M7

The following is the sample terminal output when running example LittleFS_Test on MBED PORTENTA_H7_M7

Start LittleFS_Test on PORTENTA_H7_M7
LittleFS_Portenta_H7 v1.2.0
[LFS] Flash Size: (KB) = 2048.00
[LFS] FlashIAP Start Address: = 0x0x8080000
[LFS] LittleFS size (KB) = 1536.00
[LFS] LittleFS Mount OK
====================================================
Writing file: /littlefs/hello1.txt => Open OK
* Writing OK
====================================================
Reading file: /littlefs/hello1.txt => Open OK
Hello from PORTENTA_H7_M7
====================================================
Appending file: /littlefs/hello1.txt => Open OK
* Appending OK
====================================================
Reading file: /littlefs/hello1.txt => Open OK
Hello from PORTENTA_H7_M7
Hello from PORTENTA_H7_M7
====================================================
Renaming file: /littlefs/hello1.txt to: /littlefs/hello2.txt => OK
====================================================
readCharsFromFile: /littlefs/hello2.txt => Open OK
Hello from PORTENTA_H7_M7
Hello from PORTENTA_H7_M7
====================================================
Deleting file: /littlefs/hello2.txt => OK
====================================================
Reading file: /littlefs/hello2.txt => Open Failed
====================================================
Testing file I/O with: /littlefs/hello1.txt => Open OK
- writing

64 Kbytes written in (ms) 1077
====================================================
- reading

384 Kbytes read in (ms) 0
====================================================
Testing file I/O with: /littlefs/hello2.txt => Open OK
- writing

64 Kbytes written in (ms) 1003
====================================================
- reading

64 Kbytes read in (ms) 0
====================================================
Deleting file: /littlefs/hello1.txt => OK
====================================================
Deleting file: /littlefs/hello2.txt => OK
====================================================


Debug

Debug is enabled by default on Serial.

You can also change the debugging level (LFS_LOGLEVEL) from 0 to 4

#define LFS_DEBUG_OUTPUT    Serial

// These define's must be placed at the beginning before #include "LittleFS_Portenta_H7.h"
// _LFS_LOGLEVEL_ from 0 to 4
#define _LFS_LOGLEVEL_      0

Troubleshooting

If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards.

Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions.



Issues

Submit issues to: LittleFS_Portenta_H7 issues


TO DO

  1. Search for bug and improvement.

DONE

  1. Basic LittleFS wrapper for Portenta_H7, using ArduinoCore-mbed mbed_portenta core
  2. Add Version String
  3. Add Table of Contents
  4. Reduce LittleFS size to 1024KB
  5. Fix multiple-definitions linker error
  6. Add astyle using allman style. Restyle the library


Contributions and Thanks

Many thanks for everyone for bug reporting, new feature suggesting, testing and contributing to the development of this library.


Contributing

If you want to contribute to this project:

  • Report bugs and errors
  • Ask for enhancements
  • Create issues and pull requests
  • Tell other people about this library

License

  • The library is licensed under GPLv3

Copyright

Copyright (c) 2021- Khoi Hoang