Search code examples
loggingarduinoavrarduino-c++teensy

Globally defined RingBuf does not work inside the loop() function


I can use a RingBuf from the SdFat library only inside the setup() function and I don't understand why. Can RingBuf and File32 be defined as global and configured only once during the setup? I'm working on Teensy 4.1.

For instance, this code works

#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");

      delay(800);
}

But this code does not work, without retrieving any kind of compiler errors, warnings etc

#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);
}

Solution

  • I have found the problem. The SdFat32 object is defined inside the setup() function so it is inaccessible inside the loop() function. Likely, it is not directly called neither by the RingBuf or the File32 object so it does not retrieve any error, however it is not possible to save data on SD while the SdFat32 object is not accessible.

    In my opinion this behaviour should be fixed, I think an error or warning should be raised.