SD Card File stream 'append' overwrites previous data

I’m using an STM32L475 (DISCO L475VG IoT board), Mbed OS 6, and an SPI SD card reader breakout board. Below is my code, it’s a simplified and slightly modified version of the example code linked in the header. I want the uC to append whatever printf phrase I assign it to the end of the text file on the SD card, such that when the system is powered off and on it will always add new data rather than overwrite old data. In the use case of the final product we are developing, the system will frequently be powered cycled and have new, different data to add to the text log.

Currently, it seems to overwrite part or all of the previous data depending on the length of the new test phrase. Is there something I’m missing with my implementation here?

/* Mbed Hardware Test
Authors: Jackie Hanlon, Conner Reinholt

SD Card code based on: https://os.mbed.com/users/hudakz/code/SDCard/
 */
#include "mbed.h"
#include <stdio.h>

#include "SDBlockDevice.h"
#include <errno.h>
#include "FATFileSystem.h"

// Physical block device, can be any device that supports the BlockDevice API
SDBlockDevice blockDevice(PA_7, PA_6, PA_5, PA_2); // mosi, miso, sck, cs

// File system declaration
FATFileSystem fileSystem("fs");

// Entry point for the example
int main() {
  // Try to mount the filesystem
  fflush(stdout);
  int err = fileSystem.mount(&blockDevice);
  if (err) {
    printf("Failed to recognize SD card\n");
    return 0;
  }

  // Open file
  FILE *f = fopen("/fs/peanut.txt", "r+");
  if (!f) {
    printf("No file found, creating a new file... ");
    fflush(stdout);
    f = fopen("/fs/peanut.txt", "a");
  }

  fprintf(f, "just another test thing\n");

  fclose(f); // Close the file which also flushes any cached writes


  // Tidy up
  fflush(stdout);
  fileSystem.unmount(); //unmount device
  fflush(stdout);
  blockDevice.init();
  fflush(stdout);
  blockDevice.erase(0, blockDevice.size()); //erase block device
  fflush(stdout);
  blockDevice.deinit(); //deinitialize block device
  printf("\n");
}

Hello Jackie,

Try to move the file position to the end of file:

...
f.seek(0, SEEK_END);
fprintf(f, "just another test thing\n");
...

Hello,

you create the file and then erase SD card, that sounds to me the program does exactly what it has to do.

BR, Jan

This fixed it, thank you! Syntax for anyone coming to this later:

fseek(f, 0, SEEK_END);

Ok, I was wrong probably and I do not know what erase does then.

However, the reason of that behavior seems to be first line of your code below. You open the file for read although you don’t read anything. Then you open it again for adding of a content, but without closing of previous attempt.

When you do that like below it normally works without the fseek

  // Open file
  FILE *f = fopen("/fs/peanut.txt", "a");;

BTW you not need to check if file exist and then reopen it, it does it automatically. You have to check if it fails or not.

fopen - “a” append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist.

All opened files are automatically closed on normal program termination.

BR, Jan