This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I am struggling understanding how the struct FIL gets its pointer to the filesystem (FATFS).
In the code sample, SDCardLib instantiates the filesystem with:
FATFS fatfs; //FatFs handle for current FatFs operation session
and just prior to that, the FIL struct was instantiated as
static FIL fil;
fil holds the *fs pointer to the FATFS filesystem.
I understand that f_open() is suppose to populate an empty fil object (It takes an empty fil object and a pointer to the path/filename),
If so, then how does f_open() get the filesystem fatfs handle (created in SdCardLib) so that it can assign it to the *fs pointer in fil? If f_open() doesn't fill in the fs pointer, then how did FIL know where the pointer was if the SDCardLib object (holding the fatfs handle) was instantiated afterwards?
The ChaN website has a lot of useful information but I haven't found where it describes how FIL interacts with FATFS.
Some guidance here is most welcomed. thank you.
I found an example code on the ChaN website that shows where I need some guidance. How did the fil object get the filesystem handle (*fs) ? Was the handle assigned at the time when the fil object was created? If so, how did the compiler know which fatfs session to assign to the *fs pointer ( assuming I instantiated more than one FATFS object? Was it assigned by the f_mount(), if so how did f_mount() get the reference to &fil?
thanks
/* Read a text file and display it */ FATFS FatFs; /* Work area (filesystem object) for logical drive */ int main (void) { FIL fil; /* File object */ char line[100]; /* Line buffer */ FRESULT fr; /* FatFs return code */ /* Register work area to the default drive */ f_mount(&FatFs, "", 0); /* Open a text file */ fr = f_open(&fil, "message.txt", FA_READ); if (fr) return (int)fr; /* Read every line and display it */ while (f_gets(line, sizeof line, &fil)) { printf(line); } /* Close the file */ f_close(&fil); return 0; }
I think I found my answer. The association of filesystem is done through f_mount(). f_mount() takes three parameters, the first parameter is a reference to the &fatfs object which is a struct which holds the filesystem work area. The second parameter is a path name of the form "0: filename" or "1: filename" where the first two characters (a numeric followed by a colon) represents a logical drive number. The absence of a numeric and colon mean the logical drive is the default drive ("0:"). The third parameter taken by f_mount() is an initialization option.
Thus after f_mount() the logical drive is now associated with fatfs object. In the code above the f_mount() second parameter doesn't have a logical drive numeric followed by a colon, thus it is defaults to 0: Similarly, the second parameter of f_open() also uses the default drive 0 (it doesn't have a numeric followed by a colon). The bottom line is that f_open() knows the logical drive mounted by f_mount() and is now able to associate the *fs pointer in fil with &fatfs.
Below is an example where the logical drives are explicitly specified ("0:" and "1:").
/* Copy a file "file.bin" on the drive 1 to drive 0 */ int main (void) { FATFS fs0, fs1; /* Work area (filesystem object) for logical drives */ FIL fsrc, fdst; /* File objects */ BYTE buffer[4096]; /* File copy buffer */ FRESULT fr; /* FatFs function common result code */ UINT br, bw; /* File read/write count */ /* Register work area for each logical drive */ f_mount(&fs0, "0:", 0); f_mount(&fs1, "1:", 0); /* Open source file on the drive 1 */ fr = f_open(&fsrc, "1:file.bin", FA_READ); if (fr) return (int)fr; /* Create destination file on the drive 0 */ fr = f_open(&fdst, "0:file.bin", FA_WRITE | FA_CREATE_ALWAYS); if (fr) return (int)fr; /* Copy source to destination */ for (;;) { fr = f_read(&fsrc, buffer, sizeof buffer, &br); /* Read a chunk of source file */ if (fr || br == 0) break; /* error or eof */ fr = f_write(&fdst, buffer, br, &bw); /* Write it to the destination file */ if (fr || bw < br) break; /* error or disk full */ } /* Close open files */ f_close(&fsrc); f_close(&fdst); /* Unregister work area prior to discard it */ f_mount(0, "0:", 0); f_mount(0, "1:", 0); return (int)fr; }
Hello James,
Thanks for your post and share the solution with the community.
Thanks,
Yiding
**Attention** This is a public forum