SdFat icon indicating copy to clipboard operation
SdFat copied to clipboard

Error management when SD instance is out-of-scope and RingBuf is not initialized

Open AlbertBrandl opened this issue 4 years ago • 1 comments

IMHO, when the instance of the SdFat32 object is out of scope (e.g. defined in the setup() function while trying to save in the loop() function), an error should be raised. For example, the following code tries to write on the RingBuf and on the File32 in the loop() function but the sdCard instance of the SdFat32 is defined inside the setup() function (making it unaccessible). The code hangs but the compiler does not retrieves any error. This is a mistake which is quite difficult to find and an error could be of great help. The same applies if the begin() method of the RingBuf class is not called, an error might be retrieved if trying to using the write() method without having called the begin() method.

#include "sdios.h"
#include "SdFat.h"
#include "RingBuf.h"

#define SD_CONFIG  SdioConfig(FIFO_SDIO)        // Use Teensy SDIO

File32  stateFile;
RingBuf<File32, 5> outRingBuff;

// SETUP function
void setup() {
  SdFat32 sdCard;
  bool retValBool;
  
  Serial.begin(9600);                 // Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored

  Serial.println("Initialization SD card START");

  // SD Initialization
  if (!sdCard.begin(SD_CONFIG)) {
    sdCard.initErrorHalt(&Serial);
    Serial.println("ERROR SD Initialization failed!");
  } else {
    Serial.println("Initialization SD card DONE");

    // Output file opening
    retValBool = stateFile.open("aa.csv", O_RDWR | O_CREAT | O_TRUNC);

    // Output file opening
    if (retValBool) {
      outRingBuff.begin(&stateFile);
      
      outRingBuff.write(',');
      outRingBuff.write(',');
      outRingBuff.write(',');
      outRingBuff.write(',');

      size_t numBytes = outRingBuff.writeOut(4);

      Serial.println(numBytes);

      outRingBuff.sync();
      stateFile.sync();
      stateFile.truncate();
    }
  }
}

// LOOP function
void loop() {
      Serial.print("loop");
      
      outRingBuff.write('A');
      outRingBuff.write('A');
      outRingBuff.write('A');
      outRingBuff.write('A');

      size_t numBytes = outRingBuff.writeOut(4);

      Serial.println(numBytes);
      
      outRingBuff.sync();
      stateFile.sync();
      stateFile.truncate();
      
      delay(800);
}

AlbertBrandl avatar May 11 '21 15:05 AlbertBrandl

Yes SdFat is not designed to handle the case where a file instance is at global scope and the SD volume is on the stack.

The stateFile.open() call places a pointer to the instance of SdFat32 in stateFile so any file operations with stateFile after sdcard goes out of scope will likely cause a crash.

greiman avatar May 11 '21 17:05 greiman