cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to append data to a file in SD Card.

Abhishek Deouskar
Associate III

Hello,

I am using a F413ZHTx Controller on a custom board. I am logging data onto the SD card using SDIO interface.

Since I am logging a lot of data, I created a code to:

1) Open the file on the SD card

2) Log 100 entries

3) Close the SD card file

4) Reopen the file.

5) Using f_lseek move to the last location and try appending data.

However, this is still resulting in data being overwritten every 100 entries instead on appending.

Here is my source code:

  FRESULT fr;
  uint testbyte;
 
  if(f_mount(&myFATFS, "0:" , 1) == FR_OK)
  {
//	  open_append(&myFILE0, "log.csv");
	  f_open(&myFILE0, "log.csv", FA_WRITE | FA_OPEN_APPEND);
  }
 
  count = preload_count;
  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
  HAL_CAN_Start(&hcan1);
  CAN_Filter_IDList(ID_00, ID_01, 0, 0, ENABLE);
//  CAN_Filter_IDList(ID_02, ID_03, 0, 0, ENABLE);
//  CAN_Filter_IDList(ID_04, ID_05, 0, 0, ENABLE);
//  CAN_Filter_IDList(ID_06, ID_07, 0, 0, ENABLE);
//  CAN_Filter_IDList(ID_08, ID_09, 0, 0, ENABLE);
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	if(Received_00)
	{
//		char data1[] = "Inside\n";
//		HAL_UART_Transmit(&huart7, (uint8_t*)data1, sizeof(data1), 500);
		Received_00 = 0;
		count--;
		if(count < preload_count && count > 0)
		{
//			open_append(&myFILE0, "log.csv\0");
			sprintf(CANdata,"0x%X, %d | %d | %d | %d | %d | %d | %d | %d\n", RxMessage.ExtId, RxMessage_Data[0], RxMessage_Data[1], RxMessage_Data[2], RxMessage_Data[3], RxMessage_Data[4], RxMessage_Data[5], RxMessage_Data[6], RxMessage_Data[7]);
			fr = f_write(&myFILE0, CANdata, strlen(CANdata), &testbyte);
			CAN_Filter_IDList(ID_00, ID_01, 0, 0, ENABLE);
			char data2[] = "count\n";
			HAL_UART_Transmit(&huart7, (uint8_t*)data2, sizeof(data2), 500);
		}
		else if(count == 0)
		{
			char data3[] = "100 Written\n";
			HAL_UART_Transmit(&huart7, (uint8_t*)data3, sizeof(data3), 500);
			f_close(&myFILE0);
			CAN_Filter_IDList(ID_00, ID_01, 0, 0, ENABLE);
 
			count = preload_count;
		}
		else if(count == preload_count)
		{
			char data1[] = "Next 100\n";
			HAL_UART_Transmit(&huart7, (uint8_t*)data1, sizeof(data1), 500);
 
			f_open(&myFILE0, "log.csv", FA_WRITE | FA_OPEN_APPEND);
			f_lseek(&myFILE0, f_size(&myFILE0));
//			open_append(&myFILE0, "log.csv");
			CAN_Filter_IDList(ID_00, ID_01, 0, 0, ENABLE);
		}
	}
 
/*****************************************************************************/
/*I also tried using the open_append function I found on ELM_CHAN website, but it didn't work for me.*/
/* USER CODE BEGIN 4 */
FRESULT open_append (
    FIL* fp,            /* [OUT] File object to create */
    const char* path    /* [IN]  File name to be opened */
)
{
    FRESULT fr;
 
    /* Opens an existing file. If not exist, creates a new file. */
    fr = f_open(fp, path, FA_WRITE | FA_OPEN_ALWAYS);
    if (fr == FR_OK) {
        /* Seek to end of the file to append data */
        fr = f_lseek(fp, f_size(fp));
        if (fr != FR_OK)
            f_close(fp);
    }
    return fr;
}
 
/* USER CODE END 4 */

1 ACCEPTED SOLUTION

Accepted Solutions
Abhishek Deouskar
Associate III

Hello,

I solved the issue. The issue was not of the SDIO interface but my logic for count.

Thanking You.

View solution in original post

5 REPLIES 5
AvaTar
Lead

Try f_lseek() to set the file pointer to the end before writing.

The OPEN_APPEND flag names a capability, not an automatism.

Hello AvaTar,

This section of the code does the same thing. After the first preload_count entries are written, then the preload_count is loaded back into the count variable and then I open the file again and perform f_lseek first before writing into the file.

Should I add a f_lseek to the first time I am creating or opening the file?

else if(count == preload_count)
{
	char data1[] = "Next 100\n";
	HAL_UART_Transmit(&huart7, (uint8_t*)data1, sizeof(data1), 500);
 
	f_open(&myFILE0, "log.csv", FA_WRITE | FA_OPEN_APPEND);
	f_lseek(&myFILE0, f_size(&myFILE0));
//	open_append(&myFILE0, "log.csv");
	CAN_Filter_IDList(ID_00, ID_01, 0, 0, ENABLE);
}

Abhishek Deouskar
Associate III

Hello,

I solved the issue. The issue was not of the SDIO interface but my logic for count.

Thanking You.

AvaTar
Lead

Didn't mess much with FATFS recently, but the usual clib way is calling fseek(..,..,SEEK_END) after opening the file. Your code looks fine, have you tried to debug it ?

I use to stick to simple use cases - like write- only, one file per session, file name created from date/time.

And since I mostly write medium-sized strings at a lower rates, I call f_sync() after each write.

FATFS is a limited replacement for the clib. I use to write persistant data from a MCU application, to evaluate them "offline" on a PC.

Nice. I did not read up properly on what f_sync does. Now I realize Why I am even closing the file at all when I can simply use the f_sync function.

Thanks @Community member​