2015-12-13 07:54 AM
Hello all,
I am new here and struggling to write a clean for creating a file with auto-increment name after the power on. My purpose is to save buffer data in .BIN format, power off system, start a new session when necessary and save new sensor data in new .BIN file. I have started in this way: FRESULT res; FILINFO fno; FIL fil; DIR dir; FATFS fs32; char* path = ''''; UINT BytesWritten; // SD card write Byte Count uint16_t ReceiveData_16[8192]; // 16-bit Data Buffer #if _USE_LFN static char lfn[_MAX_LFN + 1]; #endif #if _USE_LFN fno.lfname = lfn; fno.lfsize = sizeof(lfn); #endif void SD_Write(void) { char str[]; char *s = str; char *fn; if (f_opendir(&dir, path)== FR_OK) { while(1) { res = f_readdir(&dir, &fno); // Read Directory for all files if ((res != FR_OK) || (fno.fname[0] == 0)) // Break loop after all file read break; #if _USE_LFN fn = *fno.lfname ? fno.lfname : fno.fname; // Store File Names #else fn = fno.fname; #endif strcpy(s, fn); } } len= strlen(s); // Need to increment file name, say, ''073.BIN'' to ''074.BIN'' file if (s[len-5]=='9') { s[len-5]='0'; if (s[len-6]=='9') { s[len-6]='0'; } else { s[len-6]=s[len-6]+1; } } else { s[len-5]=s[len-5]+1; } //Buffer write with new file name if (f_open(&fil, str, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { f_lseek(&fil, fil.fsize); f_write(&fil, ReceiveData_16, sizeof(ReceiveData_16), &BytesWritten); f_close(&fil); } } The issue is it'll not work with a blank directory. Can anyone suggest me a clean code in this regard. I apologize for my poor coding logic. Thank you for your time.2015-12-13 08:46 AM
The file system does not guarantee in order files. You'll need to enumerate all the files, and find the one with the largest 123.BIN format. ie parse each file name, check the format, pull out the index number, do a max() with the current largest starting with -1. Once you have gone through the directory sprintf(filename, ''%03d.BIN'', maxindex + 1);
Incrementing the ASCII digits seems unduly awkward2015-12-13 09:21 AM
Thank you.. Initially I thought in the following way(messed with &fil pointer):
FIL fil1,fil2; char line[3]; FRESULT fr1; FRESULT fr2; char file_name_str[7]; char file_name_str1[7]; int file_name; char file_ext[4]= ''.BIN''; UINT *data; ........... void New_SD_write(char file_name_with_ext[7]){ if (f_open(&fil, file_name_with_ext, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { f_lseek(&fil, fil.fsize); f_write(&fil, BufferNow, sizeof(BufferNow), &BytesWritten9); f_close(&fil); } } void SD_Init(void) { // Open a file 000.bin fr1 = f_open(&fil1, ''000.BIN'', FA_READ); if (fr1 == FR_NO_FILE){ fr2 = f_open(&fil2, ''000.BIN'', FA_WRITE); if (fr2 == FR_OK){ sprintf(line, ''%3d'', 001); // convert to string fr2= f_write(&fil2,line,sizeof(line),data); f_close(&fil2); //creat new file named 001.bin New_SD_write(''001.BIN''); } }else{ fr1 = f_read(&fil1,line,sizeof(line),data); file_name = (int)line; file_name=file_name+1; sprintf(file_name_str, ''%3d'', file_name); // convert to string f_close(&fil1); strcat(file_name_str,file_ext); // open the 000.bin file in write mode fr1 = f_open(&fil1, ''000.BIN'', FA_WRITE); fr1= f_write(&fil1,line,sizeof(line),data); New_SD_write(file_name_str); } f_close(&fil1); } int main() { ........ NVIC_SDIO_Configuration(); memset(&fs32, 0, sizeof(FATFS)); res = f_mount(0, &fs32); memset(&fil1, 0, sizeof(FIL)); SD_Init(); ........... } Would I implement your direction here? Do you have any sample code? Thank you again.2015-12-13 12:00 PM
Do you have any sample code?
I'm a developer, I just write code to do what I need to the specification Something like this should be serviceable, though I'm not sure 1000 is big enoughvoid New_SD_write(char *filename)
{
UINT BytesWritten;
FIL fil;
if (f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
{
f_lseek(&fil, fil.fsize); // Should always be zero if creating
f_write(&fil, BufferNow, sizeof(BufferNow), &BytesWritten);
f_close(&fil);
}
}
int GetNextIndex(char *path)
{
DIR dir;
FILINFO fno;
int i, index = -1;
if (f_opendir(&dir, path) == FR_OK)
{
while(1)
{
if ((f_readdir(&dir, &fno) != FR_OK) || (fno.fname[0] == 0))
break;
if ((strstr(fno.fname, ''.BIN'') != NULL) && (sscanf(fno.fname, ''%d'', &i) == 1))
if (i > index) index = i;
}
}
return(index + 1);
}
{
char filename[16]; // enough space for characters and terminating NUL
sprintf(filename, ''%03d.BIN'', GetNextIndex('''') );
New_SD_write(filename);
}
I think you need to review the chapter on strings and pointers, you need enough space to accommodate the string, however large it may expand, and the NUL added to the end. Subroutines don't need to specify fixed length strings, it's very inflexible.
2015-12-13 05:21 PM
Thank you Clive1. Its working fine.. I appreciate your time spending here.
2015-12-19 11:26 AM
2015-12-19 04:14 PM
The purpose of using pointers would be to avoid replication, not create it.
I don't understand why filename needs 10000 characters, or why it's referenced with &filename, it could be simply passed as filename
Consider int i[2], where flag is 0 or 1, refer as i[flag], buffer[flag]
2015-12-19 08:39 PM
Thank you Clive for the correction. Could you suggest any simpler way to switch buffer for storage and SDIO write. Thank you in advance.