GIGA - get empty space on the drive

Hi,
I am testing features and currently I have problems with:

  • how to read empty space on USB and own Flash, I need it to check if I can create new file or not.
  • I create an Flash drive but its size is 1MB, how to change it and how to get/read free space from it.
    My test code below.
    Regards
#include <DigitalOut.h>
#include <FATFileSystem.h>
#include <Arduino_USBHostMbed5.h>
#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include <PluggableUSBMSD.h>

QSPIFBlockDevice root;

mbed::MBRBlockDevice user_data(&root, 3);

mbed::FATFileSystem data_fs("fs");

USBMSD MassStorage(&root);



int flashSetup()
{
   int err = data_fs.mount(&root);
   return err;
}


void flashWrite(String fn)
{
    String fname="/fs/";
    fname.concat(fn);
    //fname.concat(".csv");
      mbed::fs_file_t file;
      struct dirent *ent;
      int dirIndex = 0;
      int res = 0;
      FILE *f = fopen(fname.c_str(), "w+");
      for (int i = 0; i < 10; i++) 
      {
        int err = fprintf(f, "%d\n", i);
      }
      int err = fclose(f);
}








int doesFileExist(String myfile)
{
          bool ex=false;
          char buf[256];
          int mresult=0;

          
          DIR* d = opendir("/fs/");
          if (!d) 
          {
              snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
              //Serial.print(buf);
          }
          //Serial.println("done.");

          //Serial.println("Root directory:");
          unsigned int count { 0 };
          while (true) 
          {
              struct dirent* e = readdir(d);
              if (!e) 
              {
                  break;
              }
              count++;
              snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
              //Serial.print(buf);
              String fn=String(e->d_name);
              if (fn==myfile)
              {
                    Serial.print("-----exist------");
                    Serial.println(e->d_name);
                    mresult=1;
              }
          }
          
          snprintf(buf, sizeof(buf), "Closing the root directory (fileExist)... ");
          //Serial.print(buf);
          fflush(stdout);
          int err = closedir(d);
          snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
          //Serial.print(buf);
          if (err < 0) {
              snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
              Serial.print(buf);
          }
          return mresult;
}


void FlashDir()
{
    Serial.println("Starting Flash Dir List example...");
    Serial.print("Mounting Flash device... ");
    
    Serial.println("done.");

    char buf[256];

    // Display the root directory
    Serial.print("Opening the Flash root directory... ");
    DIR* d = opendir("/fs/");
    Serial.println(!d ? "Fail :(" : "Done");
    if (!d) 
    {
        snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
        Serial.print(buf);
    }
    Serial.println("done.");

    Serial.println("Root directory:");
    unsigned int count { 0 };
    while (true) 
    {
        struct dirent* e = readdir(d);
        if (!e) {
            break;
        }
        count++;
        snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
        Serial.print(buf);
        
    }
    Serial.print(count);
    Serial.println(" files found!");

    snprintf(buf, sizeof(buf), "Closing the Flash root directory... ");
    Serial.print(buf);
    fflush(stdout);
    int err = closedir(d);
    snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
    Serial.print(buf);
    if (err < 0) 
    {
        snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
        Serial.print(buf);
    }
}



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

    flashSetup();
    flashWrite("test11NR.csv");
    
    FlashDir();

    Serial.print("file exist=");
    Serial.println(doesFileExist("test11NR.csv"));
}

void loop()
{
}

Hi, you are mounting &root when you should be mounting &user_data. I suspect it's actually mounting the 1MB WiFi partition.

There's a member function statvfs for FAT that may work (not all functionality is implemented)

update: The code for statvfs appears to be implemented.

int FATFileSystem::statvfs(const char *path, struct statvfs *buf)
{

    memset(buf, 0, sizeof(struct statvfs));
    FATFS *fs;
    DWORD fre_clust;

    lock();
    FRESULT res = f_getfree(_fsid, &fre_clust, &fs);
    if (res != FR_OK) {
        unlock();
        return fat_error_remap(res);
    }

    buf->f_bsize = fs->ssize;
    buf->f_frsize = fs->ssize;
    buf->f_blocks = (fs->n_fatent - 2) * fs->csize;
    buf->f_bfree = fre_clust * fs->csize;
    buf->f_bavail = buf->f_bfree;
#if FF_USE_LFN
    buf->f_namemax = FF_LFN_BUF;
#else
    buf->f_namemax = FF_SFN_BUF;
#endif

    unlock();
    return 0;
}

Here is an updated version of the 'DirList.ino' sketch that demonstrates what @steve9 mentioned above.

/*
  Portenta - DirList

  The sketch shows how to mount an usb storage device and how to
  get a list of the existing folders and files.

  The circuit:
   - Portenta H7

  This example code is in the public domain.
*/

#include <DigitalOut.h>
#include <FATFileSystem.h>
#include <Arduino_USBHostMbed5.h>

USBHostMSD msd;
mbed::FATFileSystem usb("usb");

// If you are using a Portenta Machine Control uncomment the following line
// mbed::DigitalOut otg(PB_14, 0);

//*************************************************
// Create vfs stat buffer                         *
//*************************************************
struct statvfs vfsbuf;

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

    Serial.println("Starting USB Dir List example...");

    // if you are using a Max Carrier uncomment the following line
    // start_hub();

    while (!msd.connect()) {
        //while (!port.connected()) {
        delay(1000);
    }

    Serial.print("Mounting USB device... ");
    int err = usb.mount(&msd);
    if (err) {
        Serial.print("Error mounting USB device ");
        Serial.println(err);
        while (1);
    }
    Serial.println("done.");

    char buf[256];

    // Display the root directory
    Serial.print("Opening the root directory... ");
    DIR* d = opendir("/usb/");
    Serial.println(!d ? "Fail :(" : "Done");
    if (!d) {
        snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
        Serial.print(buf);
    }
    Serial.println("done.");

    Serial.println("Root directory:");
    unsigned int count { 0 };
    while (true) {
        struct dirent* e = readdir(d);
        if (!e) {
            break;
        }
        count++;
        snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
        Serial.print(buf);
    }
    Serial.print(count);
    Serial.println(" files found!");

//*************************************************
// Print out total size in bytes off volume.      *
//*************************************************
    Serial.print("\nTotal Size of Volume: ");
    Serial.println(totalSize("/usb/"),DEC);

//*************************************************
// Print out available size in bytes off volume.  *
//*************************************************
    Serial.print("Used Size of Volume:  ");
    Serial.println(usedSize("/usb/"),DEC);

//*************************************************
// Print out Bytes left on volume                 *
//*************************************************
    Serial.print("Bytes left on volume: ");
    Serial.println(bytesFree("/usb/"),DEC);

    snprintf(buf, sizeof(buf), "\nClosing the root directory... ");
    Serial.print(buf);
    fflush(stdout);
    err = closedir(d);
    snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
    Serial.print(buf);
    if (err < 0) {
        snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
        Serial.print(buf);
    }
}

void loop()
{
    delay(1000);
    // handle disconnection and reconnection
    if (!msd.connected()) {
        msd.connect();
    }
}

//******************************************************
// Total byte capacity of the volume.
//******************************************************
uint64_t totalSize(const char *ld) {
  usb.statvfs(ld,&vfsbuf);
  return (uint64_t)(vfsbuf.f_blocks * vfsbuf.f_bsize);
}

//********************************************************
// How much space in bytes currently used on the volume. *
//********************************************************
uint64_t usedSize(const char * ld) {
  usb.statvfs(ld,&vfsbuf);
  return (uint64_t)((vfsbuf.f_blocks * vfsbuf.f_bsize) -
                   (vfsbuf.f_bfree * vfsbuf.f_bsize));
}

//******************************************************
// How much space is left on a volume (Logical Drive). *
// Param ld: Pathname                                  *
//******************************************************
uint64_t bytesFree(const char *ld) {
  usb.statvfs(ld,&vfsbuf);
  return (uint64_t)(vfsbuf.f_bfree * vfsbuf.f_bsize);
}

It shows how to calculate the total size, used size and bytes available...

Hi,
thank you for your reply,
could you please let me know what I did wrong? code below, if I change mounting point it still show me 1M size I can access form PC but this code crash after 20-30s -> Red LED, does no matter what mounting point I use, works only with (&root)
I did not test yet code related to size recognition, that will be next step.
Regards

#include <DigitalOut.h>
#include <FATFileSystem.h>
#include <Arduino_USBHostMbed5.h>

#include "QSPIFBlockDevice.h"
#include "MBRBlockDevice.h"
#include "FATFileSystem.h"

#include <PluggableUSBMSD.h>

QSPIFBlockDevice root;

mbed::MBRBlockDevice ota_and_user_data(&root, 2);
mbed::MBRBlockDevice user_data(&root, 3);

mbed::FATFileSystem data_fs("fs");

USBMSD MassStorage(&root);



int flashSetup()
{
    int err = data_fs.mount(&ota_and_user_data);
   //int err = data_fs.mount(&user_data);
   return err;
}


void flashWrite(String fn)
{
    String fname="/fs/";
    fname.concat(fn);
    //fname.concat(".csv");
      mbed::fs_file_t file;
      struct dirent *ent;
      int dirIndex = 0;
      int res = 0;
      FILE *f = fopen(fname.c_str(), "w+");
      for (int i = 0; i < 10; i++) 
      {
        int err = fprintf(f, "%d\n", i);
      }
      int err = fclose(f);
}





int doesFileExist(String myfile)
{
          bool ex=false;
          char buf[256];
          int mresult=0;

          
          DIR* d = opendir("/fs/");
          if (!d) 
          {
              snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
              //Serial.print(buf);
          }
          //Serial.println("done.");

          //Serial.println("Root directory:");
          unsigned int count { 0 };
          while (true) 
          {
              struct dirent* e = readdir(d);
              if (!e) 
              {
                  break;
              }
              count++;
              snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
              //Serial.print(buf);
              String fn=String(e->d_name);
              if (fn==myfile)
              {
                    Serial.print("-----exist------");
                    Serial.println(e->d_name);
                    mresult=1;
              }
          }
          
          snprintf(buf, sizeof(buf), "Closing the root directory (fileExist)... ");
          //Serial.print(buf);
          fflush(stdout);
          int err = closedir(d);
          snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
          //Serial.print(buf);
          if (err < 0) {
              snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
              Serial.print(buf);
          }
          return mresult;
}


void FlashDir()
{
    Serial.println("Starting Flash Dir List example...");
    Serial.print("Mounting Flash device... ");
    
    Serial.println("done.");

    char buf[256];

    // Display the root directory
    Serial.print("Opening the Flash root directory... ");
    DIR* d = opendir("/fs/");
    Serial.println(!d ? "Fail :(" : "Done");
    if (!d) 
    {
        snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
        Serial.print(buf);
    }
    Serial.println("done.");

    Serial.println("Root directory:");
    unsigned int count { 0 };
    while (true) 
    {
        struct dirent* e = readdir(d);
        if (!e) {
            break;
        }
        count++;
        snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
        Serial.print(buf);
        
    }
    Serial.print(count);
    Serial.println(" files found!");

    snprintf(buf, sizeof(buf), "Closing the Flash root directory... ");
    Serial.print(buf);
    fflush(stdout);
    int err = closedir(d);
    snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
    Serial.print(buf);
    if (err < 0) 
    {
        snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
        Serial.print(buf);
    }
}



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

    flashSetup();
    flashWrite("test11NR.csv");
    
    FlashDir();

    Serial.print("file exist=");
    Serial.println(doesFileExist("test11NR.csv"));
}

void loop()
{
}

Hi,
I tested also @wwatson function on USB and it works only partially.
Where total size/capacity is right, both Used Size and Bytes Left are very wrong, example:
Left code / right correct value:
Total Size of Volume: 15 463 923 712 vs 15 463 923 712 bytes

Used Size of Volume: 13 484 146 688 vs 10 105 955 264 bytes

Bytes left on volume: 1 979 777 024 vs 5 357 928 448 bytes

Regards

Could you run the QSPIReadPartitions sketch from the STM32H747_System folder in the IDE examples and post the results. Thanks

Hi,
I already have partitions, and can relocate space between them.
you ask for:

Looking for Partitions on the Flash Memory... MBR Found
Boot Signature: 0x55AA

Printing Partitions Table and Info...
================================
Partition: 1
Bootable: No
Type: 0x0B
Size [KBytes]: 1020
Start [C/H/S]: 0/2/0
Stop [C/H/S]: 4/0/0

================================
Partition: 2
Bootable: No
Type: 0x0B
Size [KBytes]: 13312
Start [C/H/S]: 4/1/0
Stop [C/H/S]: 56/0/0

================================
Partition: 3
Bootable: No
Type: 0x0B
Size [KBytes]: 0
Start [C/H/S]: 56/1/0
Stop [C/H/S]: 56/0/0

================================
Partition: 4
Bootable: No
Type: 0x00

No more partitions are present.

Total Space [KBytes]:         16384
Allocated Space [KBytes]:     14332
Unallocated Space [KBytes]:   2052

I am still not able to see properly occupied and free space on USB or Flash drive
and one more I did not found any function to copy files for example between USB and Flash, I can open one file create new and read/write by byte but this is work around.
Regards

I ran your code on my GIGA and the Serial output was:

06:43:19.586 -> Starting Flash Dir List example...
06:43:19.586 -> Mounting Flash device... done.
06:43:19.586 -> Opening the Flash root directory... Done
06:43:19.586 -> done.
06:43:19.586 -> Root directory:
06:43:19.586 ->     System Volume Information
06:43:19.586 ->     UPDATE.BIN
06:43:19.586 ->     test11NR.csv
06:43:19.586 -> 3 files found!
06:43:19.586 -> Closing the Flash root directory... OK
06:43:19.586 -> file exist=-----exist------test11NR.csv
06:43:19.586 -> 1

I have 4 partitions:
image

Your code successfully created the test file on my OTA partition(2)

image

I also ran the sketch provided by @wwatson

07:03:18.005 -> Starting USB Dir List example...
07:03:20.351 -> Mounting USB device... done.
07:03:20.589 -> Opening the root directory... Done
07:03:20.589 -> done.
07:03:20.589 -> Root directory:
07:03:20.589 ->     System Volume Information
07:03:20.589 ->     BBA05741.TXT
07:03:20.589 ->     BBA05742.TXT
07:03:20.589 ->     BBA05743.TXT
07:03:20.589 ->     BBA05744.TXT
07:03:20.589 ->     BBA05745.TXT
07:03:20.589 ->     BBA05746.TXT
07:03:20.589 ->     BBA05747.TXT
07:03:20.589 ->     BBA05748.TXT
07:03:20.589 ->     BBA05749.TXT
07:03:20.589 ->     BBA05750.TXT
07:03:20.589 ->     BBA05751.TXT
07:03:20.589 ->     BBA05752.TXT
07:03:20.589 ->     BBA05753.TXT
07:03:20.589 ->     BBA05754.TXT
07:03:20.589 ->     BBA05755.TXT
07:03:20.589 ->     BBA05756.TXT
07:03:20.589 ->     BBA05757.TXT
07:03:20.589 ->     BBA05758.TXT
07:03:20.589 ->     BBA05759.TXT
07:03:20.589 ->     BBA05760.TXT
07:03:20.589 ->     BBA05761.TXT
07:03:20.589 ->     BBA05762.TXT
07:03:20.589 ->     BBA05763.TXT
07:03:20.589 ->     BBA05764.TXT
07:03:20.589 ->     BBA05765.TXT
07:03:20.589 -> 26 files found!
07:03:20.589 -> 
07:03:20.589 -> Total Size of Volume: 61964943360
07:03:20.589 -> Used Size of Volume:  3473408
07:03:20.589 -> Bytes left on volume: 61961469952
07:03:20.589 -> 
07:03:20.589 -> Closing the root directory... OK

Which correctly reported file count, usage, free space and total capacity

There is a function to copy within filesystems but the method you describe is what is needed for copies between systems.
I don't know what to suggest in your situation other than wipe the flash and re-partition, load wifi and try again.

Are you reformatting after repartitioning?

Hi,
sorry for confusing explanation from my side:

  • I was not able to get any access to Flash until I run first time partitioning example, then all works as expected.
  • in my case @wwatson code does not provide right optput:
    Starting USB Dir List example...
    Mounting USB device... done.
    Opening the root directory... Done
    done.
    Root directory:
    System Volume Information
    ...
    20 files found!

Total Size of Volume: 15463923712
Used Size of Volume: 13484244992
Bytes left on volume: 1979678720

Closing the root directory... OK

and

Another USB:
Starting USB Dir List example...
Mounting USB device... done.
Opening the root directory... Done
done.
Root directory:
System Volume Information
NewAlice3.0
al1.jpg
123.csv
123.txt
124.txt
124779.txt
09125793.txt
147885.txt
324324.csv
0123.csv
433.csv
log.txt
numbers.txt
data.txt
15 files found!

Total Size of Volume: 15707734016
Used Size of Volume: 690487296
Bytes left on volume: 15017246720

Closing the root directory... OK
and:

I still have few problems to solve:

  • how to manage files/delete from flash?
  • check free space on Flash
    Regards

I already solve checking free space on Flash but still did not found solution for deleting files from Flash drive.
Seems that I already solve size and deleting problems.
One a bit confusing thing:

  • GIGA is plugged to my PC where I see what happens on Flash drive, if I create file or delete file it does not appear immediately, I have to do reset of GIGA to see it, but GIGA itself see them already.

Try adding MassStorage.process(); inside your loop()

Hi,
if I add:
MassStorage.process(); inside main loop() it stop whole system = does not react for any touch either not execute any other function, but no RED LED :slight_smile:
Regards