greiman / SdFat

Arduino FAT16/FAT32 exFAT Library
MIT License
1.08k stars 509 forks source link

Compile fails after update v2.0.2 -> v2.0.3 #237

Open gicking opened 3 years ago

gicking commented 3 years ago

hello,

after updating from v2.0.1 to v2.0.3 I cannot compile a code for Arduino Due any more. Specifically v2.0.2 v2.0.3 fail to compile with below error message, while v2.0.1 compiles successfully. Also Arduino Mega compiles successfully for all v2.0.x.

Here is the error message I get for v2.0.2 and v2.0.3:

Arduino: 1.8.13 (Linux), Board: "Arduino Due (Programming Port)"

libraries/muDuino_SW/utility/muDuino_SD.cpp: In function 'uint8_t mD_SD_Wipe()':
libraries/muDuino_SW/utility/muDuino_SD.cpp:65:15: error: 'SdFat' has no member named 'format'
  return _card.format(NULL) && mD_SD_Setup();
               ^
libraries/muDuino_SW/utility/muDuino_SD.cpp: In function 'File mD_SD_File_open(const char*, int8_t)':
libraries/muDuino_SW/utility/muDuino_SD.cpp:75:11: error: 'File' has no member named 'isFile'
  if(_file.isFile())
           ^
libraries/muDuino_SW/utility/muDuino_SD.cpp: In function 'uint16_t mD_SD_Dir_Folder_cnt(const char*)':
libraries/muDuino_SW/utility/muDuino_SD.cpp:120:6: error: 'File' has no member named 'openRoot'
  dir.openRoot(&_card);
      ^
exit status 1
greiman commented 3 years ago

The problem is a change to the default type for SdFat in SdFatConfig.h. Users convinced me that ARM processors should default to SdFat supporting FAT16/FAT32/exFAT. I forgot to make format available in the underlying SdFs class.

I will fix it but temporally you can edit SdFatConfig.h and change SDFAT_FILE_TYPE to one for ARM.

//------------------------------------------------------------------------------
/**
 * File types for SdFat, File, SdFile, SdBaseFile, fstream,
 * ifstream, and ofstream.
 *
 * Set SDFAT_FILE_TYPE to:
 *
 * 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
 */
#if defined(__AVR__) && FLASHEND < 0X8000
// 32K AVR boards.
#define SDFAT_FILE_TYPE 1
#elif defined(__arm__)
// ARM boards usually have plenty of memory
#define SDFAT_FILE_TYPE 3
#else  // defined(__AVR__) && FLASHEND < 0X8000
// All other boards.
#define SDFAT_FILE_TYPE 1
#endif  // defined(__AVR__) && FLASHEND < 0X8000
gicking commented 3 years ago

Hi Bill,

thanks a lot for your fast response and the quick fix! I will keep this issue open as a reminder and close it after the upcoming update has been confirmed. Thanks again and have a Happy New Year! :-)

Georg

greiman commented 3 years ago

Try V2.0.4 I fixed SdFs::format(). I tested it with one of my apps. Could you try it with the default SDFAT_FILE_TYPE of 3?

gicking commented 3 years ago

Hi Bill,

just tried to compile for Arduino Due with a fresh v2.0.4 installation, i.e. no modifications:

Georg

greiman commented 3 years ago

Could you try this code and see if anything else is missing in SdFs.

// Insert this at about line 157 of SdFat/src/FsLib/FsFile.cpp
//------------------------------------------------------------------------------
bool FsBaseFile::openRoot(FsVolume* vol) {
  if (!vol) {
    return false;
  }
  close();
  if (vol->m_fVol) {
    m_fFile = new (m_fileMem) FatFile;
    if (m_fFile && m_fFile->openRoot(vol->m_fVol)) {
      return true;
    }
    m_fFile = nullptr;
    return false;
  } else if (vol->m_xVol) {
    m_xFile = new (m_fileMem) ExFatFile;
    if (m_xFile && m_xFile->openRoot(vol->m_xVol)) {
      return true;
    }
    m_xFile = nullptr;
  }
  return false;
}

// Insert these in SdFat/src/FsLib/FsFile.h
// Anywhere  after 
//  class FsBaseFile {
//  public:
  /** \return True if this is a normal file. */
  bool isFile() const {
    return m_fFile ? m_fFile->isFile() :
           m_xFile ? m_xFile->isFile() : false;
  }  
  /** Open a volume's root directory.
   *
   * \param[in] vol The SdFs volume containing the root directory to be opened.
   *
   * \return true for success or false for failure.
   */  
  bool openRoot(FsVolume* vol);

I tested the above with this program on FAT and exFAT SDs.

#include "SdFat.h"
const uint8_t CS_PIN = SS;
SdFs sd;
FsFile root;
FsFile file;
void setup() {
 Serial.begin(9600);
 if (!sd.begin(CS_PIN)) {
   Serial.println("sd.begin failed");
   return;
 }
 if (!root.openRoot(&sd)) {
   Serial.println("root.openRoot failed");
   return;
 }
 if (!file.open(&root, "TestOpenRoot.txt", O_RDWR | O_CREAT)) {
  Serial.println("file.open failed");
  return;
 }
 if (!file.isFile() || root.isFile()) {
  Serial.println("isFile failed");
  return;
 }
 root.ls();
 file.remove();
 root.close();
 Serial.println("Done");
}
void loop() {}
gicking commented 3 years ago

I tested SdFat with the above changes and extFAT & FAT32. All tests passed for Arduino Mega & Due :-)

Out of curiosity: why did the library compile for Mega even without the above changes?

greiman commented 3 years ago

Thanks for testing these additions. I will check for other missing functions in SdFs and release this soon.

Only ARM boards are are enable to support both FAT and exFAT by default. Here is the section of SdFatConfig.h.

//------------------------------------------------------------------------------
/**
 * File types for SdFat, File, SdFile, SdBaseFile, fstream,
 * ifstream, and ofstream.
 *
 * Set SDFAT_FILE_TYPE to:
 *
 * 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
 */
#if defined(__AVR__) && FLASHEND < 0X8000
// 32K AVR boards.
#define SDFAT_FILE_TYPE 1
#elif defined(__arm__)
// ARM boards usually have plenty of memory
#define SDFAT_FILE_TYPE 3
#else  // defined(__AVR__) && FLASHEND < 0X8000
// All other boards.
#define SDFAT_FILE_TYPE 1
#endif  // defined(__AVR__) && FLASHEND < 0X8000
gicking commented 3 years ago

:-) now it's clear, thanks!

gicking commented 3 years ago

Hi Bill,

is this issue already closed in v2.0.5? If yes, I would close the issue. For your feedback thanks a lot in advance!

Have a great day :-)

Georg