Go Down

Topic: FAT32 volume label? (Read 1 time) previous topic - next topic

bkw

Hello!

How can I read the volume label from a fat32 fs on an sd card?

I have *almost* got it, in a way, but I'm hoping there is a better way.

I'm using SdFat, and I temporarily hacked DIR_IS_FILE_OR_SUBDIR() in FatStructs.h like so:

Code: [Select]

static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
  //return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;  // return anything but volume label?
  return dir->attributes & DIR_ATT_VOLUME_ID;  // return only volume label?
}


This totally breaks openNext() and openNextFile() for normal use, but it causes openNextFile() to return the entries it used to exlude.

That obviously borken hack, plus this sketch:

Code: [Select]

#include <SdFat.h>
SdFatSdioEX sd;

File root;
File entry;

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

  while(!initCard());
 
  printVolumeLabel();
}

void loop() {
}

bool initCard () {
  Serial.print("sd.open(): ");
  if (sd.begin()) {
    Serial.print("OK\r\n");
  } else {
    Serial.print("FAILED\r\n");
    delay (500);
    return false;
  }
  sd.chvol();
  return true;
}

void printVolumeLabel() {
  char fileName[32] = "";

  Serial.print("---[ begin / ]---\r\n");
  Serial.print("fileName\t\tfileAttr\r\n");
  root = sd.open("/");
  while (true) {
    entry = root.openNextFile();
    if (!entry) break;
    entry.getName(fileName,32);
    Serial.print("\"");
    Serial.print(fileName);
    Serial.print("\"\t\t");
    Serial.print(entry.fileAttr(),HEX);
    Serial.print("\r\n");
    entry.close();
  }
  root.close();
  Serial.print("---[ end / ]---\r\n");
}



Produces:

Code: [Select]

sd.open(): OK
---[ begin / ]---
fileName fileAttr
"M_100" 8
"AG" F
---[ end / ]---



That "M_100" is the volume label.
I don't know what that "AG" is, perhaps a deleted entry? I'm not worried about that. I'm sure I can filter it later by looking at fileAttr() or something.

I took a clean new card, formatted fat32 with no label, and assigned a label of "VOLUMELABEL" (which happens to exactly fill all the characters allowed)

That card produces:

Code: [Select]

sd.open(): OK
---[ begin / ]---
fileName fileAttr
"VOLUMELA.BEL" 8
---[ end / ]---


OK! So, clearly it is physically attainable!

However the way I got it is terrible. Is there some better way?

I'm ok with ignoring FAT12,  FAT16, and exFAT.

At this point I'm looking at I guess copying openNextFile() and openNext() to make openNextFile_r() and openNext_r() "raw" versions that don't exlude anything, so that you can do your own filtering for the type of entry you want, but it seems kind of ungainly, and I suspect there might already be a way to get the info using interfaces that already exist, just not normally used, like fileAttr() etc.

Thank you

bkw

Ughh, trying to make a hacked copy of openNext() that just omits or changes DIR_IS_FILE_OR_SUBDIR(), requires hacking not only openNext(), but open() itself, and I quickly got out of my depth.

PaulS

Why are you trying to modify existing methods? Just add a method to return dir->attributes on the root directory, and mask that to extract just what you want.
The art of getting good answers lies in asking good questions.

bkw

Because I can just about spell c++ much less actually code in it. I don't actually know exactly how to do what you just said, and definitely didn't know that was the sane direction to look until you provided the clue. But now that you at least gave me a direction to go, I will try it. Thank you.

bkw

I never actually wanted to modify open() or openNext(), it was just the only way I could start was by starting with somethung that already existed that someone else wrote that worked. All I really want is any possible way to read the volume label, preferably using existing fuctions, prefferably from either core or sdfat libraries without having to either include an entire other fat library, or switch to some other fat library. I don't care if it's by using raw sector access instead of any of the filesystem functions. I just want to read the volume label once each time I run sd.begin() to init a card, either on power-up or after ejecting and switching cards, so I can include that in a display which shows which card is inserted.

OMOTS

The code I posted in https://forum.arduino.cc/index.php?topic=568452.0 is derived from code written by the designer of the SD library, and it goes through SD card directory blocks in the manner you need to do it. And it's written in C, so your lack of C++ expertise won't be an issue.

Go Up