SdFat RAM usage on ATMega328

Hello Storage Forum!

I have a question about RAM usage while implementing SdFat instance.

Here is my test code

/* Print the free RAM after initializing SdFat in bare minimum program */
#include <MemoryFree.h>
#include <SdFat.h>
void setup()
{
	Serial.begin(9600);

	Serial.println(freeMemory());

	SdFat card;

	Serial.println(freeMemory());

	pinMode(10, OUTPUT);
	card.begin(10, SPI_FULL_SPEED);

	Serial.println(freeMemory());
	Serial.println( F("End of setup!") );
}
void loop()
{
	Serial.println(freeMemory());
	delay(1000);
}

And here is the output via Serial monitor, showing freeMemory() calls (in bytes).

1235
1235
1235
End of setup!
1296
1296
1296
1296
1296
1296
1296

I wonder why the code above shows 1235B free before the SdFat instance is initialized??
Without the SdFat calls I see 1823B free inside of setup() and 1825B free inside of loop().

And I wonder why the RAM used by SdFat instance is not cleared after setup() returns?

I appreciate your time. -ted

SD cards are block devices with 512 byte blocks so SdFat requires a 512 byte block cache. This cache is a global array and the linker will allocate the cache if any call accesses the cache.

This call causes the cache array to be allocated.

  card.begin(10, SPI_FULL_SPEED);

And I wonder why the RAM used by SdFat instance is not cleared after setup() returns?

The cache is not on the stack by default.

You can edit SdFatConfig.h and set USE_MULTIPLE_CARDS nonzero to move the cache to your instance of SdFat.

/**
 * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
 *
 * Using multiple cards costs about 200  bytes of flash.
 *
 * Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
 */
#define USE_MULTIPLE_CARDS 1

The result is then:

1235
1235
1235
End of setup!
1820
1820
1820
1820
1820

When SdFat was developed five years ago, only one instance was allowed and using a global array saved substantial flash. The AVR compiler has improved and less flash is saved with a global cache. I may make the default a cache in each instance of SdFat instead of a global static.

One note, there is no need to make the SD chip select pin an output. This statement is not needed, SdFat handles all SPI pins and SD chip select.

  pinMode(10, OUTPUT);

You do need to disable any other devices on the SPI bus like this:

  pinMode(otherCSPin, OUTOUT);
  digitalWrite(otherCSPin, LOW);

The forum and example code have lots of confusion on sharing the SPI bus.

fat16lib,
That was the perfect explanation for a perfect solution! Thank you for taking the time,

Making the change to the constant, USE_MULTIPLE_CARDS, does free the cache RAM and it's just what the project needed to move forward,

Also thanks for the note on the SPI bus - I've updated my setup routines.

Ted