AnsweredAssumed Answered

Need help with FatFS and Long File Names

Question asked by Rob on Jul 27, 2016
Latest reply on Jul 27, 2016 by Clive One
Hi all,
I’ve been banging my head against an issue with FATFs and long file names. I’m writing a series of files to an SD card, and I’m composing the filenames from the date and time each file is created. The date and time are read from the STM32 RTC, and a filename is created in the format YYYYMMDD_HHMMSS.wav

The code will run fine in the beginning. Its intended to read a stream of audio from the I2S port and store it in a series of files. However, after several files are successfully created the code inevitably fails. I’ve tracked the problem down to my long file name implementation.

Referring to ffconf.h, I’ve set up long file names as follows:
#define _CODE_PAGE         437  /* 437  - U.S. (OEM) */
#define _USE_LFN     1               /* 0 to 3 */
#define _MAX_LFN     35           /* Maximum LFN length to handle (12 to 255) */
#define _LFN_UNICODE    0      /* 0:ANSI/OEM or 1:Unicode */
#define _STRF_ENCODE    0      /* 0:ANSI/OEM */

Following is the function I use to create the long file name based on the date and time:
char* RTC_ReturnDateTimeString(void)
  static char buff[20]; 
  struct tm now; 
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;
  HAL_RTC_GetTime(&hrtc, &sTime, FORMAT_BIN); //Read RTC Time
  HAL_RTC_GetDate(&hrtc, &sDate, FORMAT_BIN); //Read RTC Date
  //Store date and time in tm variable
  now.tm_year = (sDate.Year + 2000) - 1900;
  now.tm_mon = sDate.Month - 1;
  now.tm_mday = sDate.Date;
  now.tm_hour = sTime.Hours;
  now.tm_min = sTime.Minutes;
  now.tm_sec = sTime.Seconds;
  now.tm_isdst = sTime.DayLightSaving;
  strftime(buff, 20, "%Y%m%d_%H%M%S.wav", &now); //Store formatted string in buff
  return buff; 

And here is the code I use to open the new file:
uint8_t AudioFiles_CreateNextFile(SWIFT_ERRORS* SwiftError, FIL* MyFile, uint32_t filesize)
  char *MyFileName;
  SwiftError->CallingFunction = FUNC_AudioFiles_CreateNextFile; //SwiftError is a struct that stores error info
  MyFileName = RTC_ReturnDateTimeString();
  UARTDebugOut_PrintString("\r\n\r\n***OPENING FILE: ", 21); //This code prints debug info to UART
  UARTDebugOut_PrintString(MyFileName, 20);
  SwiftError->FatFsResult = f_open(MyFile, MyFileName, FA_CREATE_ALWAYS | FA_WRITE); //This is where code fails
  if (SwiftError->FatFsResult != FR_OK)
    SwiftError->ErrorNumber = 1;
    UARTDebugOut_PrintString("\r\n***Failed to open file", 24); //print this message if f_open fails
    return 1; //Error occured
  return 0; //NO ERROR

The code fails when opening a new file, and most often it fails with a hard fault. I suspect it has to do with the memory in the Heap, because that’s where the memory is being allocated for the long file name. Can someone give me some idea on how I might fix this issue?

Thank you,