cancel
Showing results for 
Search instead for 
Did you mean: 

Fatfs create folders

alex_embedded
Associate III

Hi All,

I am currently working on creating a file system on an stm32f207, using the nucleo board for the time being while I wait for my custom boards.

The board will have an SD card as well as a USB.

I have made a simple function for creating a folder onto a drive:

FRESULT f_CreateFolder(	const TCHAR* path){
 
	FRESULT fr;
 
	// Create folder/directory
	fr = f_mkdir(path);
	if(fr == FR_OK){
 
		// Success
		// TODO: f_mkdir Something to happen when successful
 
	}
	else{
 
		// Error
		// TODO: f_CreateFolder make directory error
 
	}
 
	return fr;
} // END f_CreateFolder

the "f_mdir" has no calls to which drive it is referring to, so if both SD and USB are mounted, how do I choose which drive to create a folder on??

Finally, I have been succesful with creating a single folder on the SD (yet to try on USB but I can't imagine it being any different) but I am not sure how to create folders within folders, if that makes sense lol.

This works to create folders in the root directory:

  // Mount SD Card
  f_MountDisk(&SDCard, &SDFatFS, SDPath);
 
  HAL_Delay(100);
 
  f_CreateFolder("INIT");
  HAL_Delay(100);
 
  f_CreateFolder("CONFIG");
  HAL_Delay(100);
 
  f_CreateFolder("LOGS");
  HAL_Delay(100);

How can I create folders inside the folders created above, for example have another folder in "LOGS" for specific dates.

Thanks in advance all!! =)

1 ACCEPTED SOLUTION

Accepted Solutions

>>Finally, I have been succesful with creating a single folder on the SD (yet to try on USB but I can't imagine it being any different) but I am not sure how to create folders within folders, if that makes sense lol.

f_mkdir("/FOO");

f_mkdir("/FOO/FOO");

f_mkdir("/FOO/FOO/FOO");

I have my f_open() wrapped so that if I get an FR_NO_PATH, I pass the fully qualified path/file to a BuildPath() function that recursively builds out the tree of pieces that don't already exist. Then I retry the f_open()

  res = f_open(&fil, Filename, FA_OPEN_ALWAYS | FA_WRITE);
 
  if (res == FR_NO_PATH)
  {
    BuildPath(Filename); // descend and build missing nodes
    res = f_open(&fil, Filename, FA_CREATE_ALWAYS | FA_WRITE); // try again
  }
 
  if (res == FR_OK)
  {
  ...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

6 REPLIES 6

>>Finally, I have been succesful with creating a single folder on the SD (yet to try on USB but I can't imagine it being any different) but I am not sure how to create folders within folders, if that makes sense lol.

f_mkdir("/FOO");

f_mkdir("/FOO/FOO");

f_mkdir("/FOO/FOO/FOO");

I have my f_open() wrapped so that if I get an FR_NO_PATH, I pass the fully qualified path/file to a BuildPath() function that recursively builds out the tree of pieces that don't already exist. Then I retry the f_open()

  res = f_open(&fil, Filename, FA_OPEN_ALWAYS | FA_WRITE);
 
  if (res == FR_NO_PATH)
  {
    BuildPath(Filename); // descend and build missing nodes
    res = f_open(&fil, Filename, FA_CREATE_ALWAYS | FA_WRITE); // try again
  }
 
  if (res == FR_OK)
  {
  ...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Awesome way to go about this!!

Here's a pint to say thank you -> :beer_mug:

Being that an aussie has given you a pint, it is customary for you to neck it all at once, good luck!

Shotgun...

I just need Amazon to be able to deliver beer, but I do accept gift cards when you run out of virtual beer..

Not totally bullet-proof, but serviceable..

//******************************************************************************
 
char *strmalloc(char *str)
{
  char *s = malloc(strlen(str) + 1);
  if (s)
    strcpy(s, str);
  return(s);
}
 
//******************************************************************************
 
// Top level input is "/FOO/FOO/FOO/BAR.LOG"
 
void BuildPath(char *path) // sourcer32@gmail.com
{
  FRESULT res;
  char *s = strmalloc(path);
  int i = strlen(s);
 
  while(i && s[i-1] != '/') // Find decomposition point
    i--;
 
  if (i) // Move to '/'
    i--;
 
  if (i)
  {
    s[i] = 0; // replace '/' with NUL
 
    res = f_mkdir(s);
 
//    printf("res = %d f_mkdir '%s'\n", res, s);
 
    if (res == FR_NO_PATH)
    {
      BuildPath(s); // Drop down a level, and build that
 
      res = f_mkdir(s); // Try again
 
//      printf("res = %d f_mkdir '%s' (2nd)\n", res, s);
    }
 
    if (res == FR_OK)
      printf("Created path '%s'\n", s);
  }
 
  free(s);
}
 
//******************************************************************************

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

As we had FR_NO_PATH for the full path at least one node is missing, it tries to make the longest one first, if that fails in goes up a level and tries again, as soon as f_mkdir() succeeds it unwinds immediately, and never tries to create the same path twice (obviously retries the one that had failed, but if the second time fails the universe is already collapsing in on itself). It is a pretty optimal approach.

*In a previous life I wrote tape backup and CD/DVD burning software, file systems and kernel/port/filter drivers.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
alex_embedded
Associate III

So, I came back to this today and was running some of my test code to backtrack what I had done.

Creating folders within folders now refuses to work, and I haven't touched the "createFolder" function I created!?

f_CreateFolder:

FRESULT f_CreateFolder(	const TCHAR* path){
 
	FRESULT fr;
 
	// Create folder/directory
	fr = f_mkdir(path);
	if(fr == FR_OK){
 
		// Success
		// TODO: f_mkdir Something to happen when successful
 
	}
	else{
 
		// Error
		// TODO: f_CreateFolder make directory error
 
	}
 
	return fr;
} // END f_CreateFolder

Creating a folder in the root directory is still successful:

  f_CreateFolder("/TEST");
  HAL_Delay(20);

And then, creating a folder under "TEST" returns "FR_INVALID_NAME"

  f_CreateFolder("/TEST/SECONDTEST");
  HAL_Delay(20);
  f_CreateFolder("/LOGS/THIRDTEST");
  HAL_Delay(20);

What the hell!? Previously I tried creating "12APR2019" folder inside a folder called "LOGS", creating the "LOGS" folder first and then creating the "12APR2019" next was both successful. What about the folder name is invalid?

**UPDATE**

Seems that the limit for the "path" variable in f_mkdir is limited to 14 characters.

fr = f_mkdir(path);

using my f_CreateFolder function (shown above):

f_CreateFolder("/TEST/1234567");

"/TEST/1234567" = 13 characters, returns FR_OK

"/TEST/12345678" = 14 characters, returns FR_OK

"/TEST/123456789" = 15 characters, returns FR_INVALID_NAME

Is this something that can be adjusted or is it a limit I must accept?