Standard Type And Function Names
For ease of interoperability this driver uses modified version of the standard ANSI-C function names and FILE data types. To avoid conflicting with your compilers stdio.h definitions you can comment out this section and use the modified ffs_ (flash filing system) names in your code. If you want to use the ANSI-C standard names then un-comment this section:-
#define fopen ffs_fopen
#define fseek ffs_fseek
#define ftell ffs_ftell
#define fgetpos ffs_fgetpos
#define fsetpos ffs_fsetpos
#define rewind ffs_rewind
#define fputc ffs_fputc
#define fgetc ffs_fgetc
#define fputs ffs_fputs
#define fgets ffs_fgets
#define fwrite ffs_fwrite
#define fread ffs_fread
#define fflush ffs_fflush
#define fclose ffs_fclose
#define remove ffs_remove
#define rename ffs_rename
#define clearerr ffs_clearerr
#define feof ffs_feof
#define ferror ffs_ferror
#define putc ffs_putc
#define getc ffs_getc
#define EOF FFS_EOF
#define SEEK_SET FFS_SEEK_SET
#define SEEK_CUR FFS_SEEK_CUR
#define SEEK_END FFS_SEEK_END
Open File
FFS_FILE* ffs_fopen (const char *filename, const char *access_mode)
This function opens a file for read and or write access.
For ease of use this driver does not differentiate between text and binary mode. You may open a file in either mode (or neither) and all file operations will be exactly the same (basically is if the file was opened in binary mode. LF characters will not be converted to a pair CRLF characters and vice versa. This makes using functions like fseek much simpler and avoids operating system difference issues. (If you are not aware there is no difference between a binary file and a text file – the difference is in how the operating system chooses to handle text files)
filename
Only 8 character DOS compatible root directory filenames are allowed. Format is F.E where F may be between 1 and 8 characters and E may be between 1 and 3 characters, null terminated, non-case sensitive. The ‘*’ and ‘?’ wildcard characters may be used.
access_mode
“r” Open a file for reading. The file must exist.
“r+” Open a file for reading and writing. The file must exist.
“w” Create an empty file for writing. If a file with the same name already exists its content is erased.
“w+” Create an empty file for writing and reading. If a file with the same name already exists its content is erased before it is opened.
“a” Append to a file. Write operations append data at the end of the file. The file is created if it doesn’t exist.
“a+” Open a file for reading and appending. All writing operations are done at the end of the file protecting the previous content from being overwritten. You can reposition (fseek) the pointer to anywhere in the file for reading, but writing operations will move back to the end of file. The file is created if it doesn’t exist.
Return value.
If the file has been successfully opened the function will return a pointer to the file. Otherwise a null pointer is returned (0×00).
Move File Byte Pointer
int ffs_fseek (FFS_FILE *file_pointer, long offset, int origin)
This function allows you to change the byte location in the file which the next read or write access will address. The function is quite complex as it looks to see if the new location is in the same cluster as the current location to avoid having to read all of the FAT table entries for the file from the file start where possible, which results in a large speed improvement.
file_pointer
Pointer to the open file to use.
origin
The initial position from where the offset is applied
FFS_SEEK_SET (0) Beginning of file
FFS_SEEK_CUR (1) Current position of the file pointer
FFS_SEEK_END (2) End of file
offset
Signed offset from the position set by origin
returns
0 if successful, 1 otherwise
int ffs_fsetpos (FFS_FILE *file_pointer, long *position)
This function is an alternative to ffs_seek. The value used is intended to be file system specific and obtained using the ffs_getpos function. However as the type is recommended to be a long and this doesn’t provide enough space to store everything needed for the low level file position this function calls the ffs_fseek function.
Get The Current Position In The File
long ffs_ftell (FFS_FILE *file_pointer)
This function returns the current position within the file (the next byte that will be read or written).
int ffs_fgetpos (FFS_FILE *file_pointer, long *position)
This function is an alternative to ffs_tell. The value returned is intended to be file system specific and only to be used with fsetpos. However as the position type is recommended to be a long and this doesn’t provide enough space to store everything needed for the low level file position this function calls the ffs_tell function.
Returns
0 if successful, 1 otherwise
Set File Byte Pointer To Start Of File
void ffs_rewind (FFS_FILE *file_pointer)
The file byte pointer is set to the first byte of the file and the file access error flag is cleared if it has been set.
file_pointer
Pointer to the open file to use.
Write Byte To File
int ffs_fputc (int data, FFS_FILE *file_pointer)
or
ffs_putc(int data, FFS_FILE *file_pointer)
file_pointer
Pointer to the open file to use.
data
The data byte to write which is converted to a byte before writing (the int type is specified by ANSI-C)
Returns
If there are no errors the written character is returned. If an error occurs FFS_EOF is returned.
Read Byte From File
int ffs_fgetc (FFS_FILE *file_pointer)
or
int ffs_getc (FFS_FILE *file_pointer)
file_pointer
Pointer to the open file to use.
Returns
The byte read is returned as an int value (int type is specified by ANSI-C). If the End Of File has been reached or there has been an error reading FFS_EOF is returned.
Write String To File
int ffs_fputs (const char *string, FFS_FILE *file_pointer)
or
int ffs_fputs_char (char *string, FFS_FILE *file_pointer)
This function writes a string to the file until a null termination is reached. The null termination is not written to the file. If a new line character (\n) is required it should be included at the end of the string
The alternative ffs_fputs_char function is not part of the ANSI-C standard but may be needed writing a string from ram with compilers that won’t deal with converting the ram string to a constant string.
Returns
Non-negative value if successful. If an error occurs FFS_EOF is returned.
Read String From File
char* ffs_fgets (char *string, int length, FFS_FILE *file_pointer)
This function reads characters from file and stores them into the specified buffer until a newline (\n) or EOF character is read or (length – 1) characters have been read. A newline character (\n) is not discarded. A null termination is added to the string
Returns
Pointer to the buffer if successful. A null pointer (0×00) if there is an error of the end-of-file is reached (use ffs_ferror or ffs_feof to check what happened).
Write Data Block To File
int ffs_fwrite (const void *buffer, int size, int count, FFS_FILE *file_pointer)
Writes count number of items, each one with a size of size bytes, from the specified buffer.
No translation occurs for files opened in text mode. The total number of bytes to be written is (size x count).
Returns
The number of full items (not bytes) successfully written. This may be less than the requested number if an error occurred.
Read Data Block From File
int ffs_fread (void *buffer, int size, int count, FFS_FILE *file_pointer)
Reads count number of items each one with a size of size bytes from the file to the specified buffer.
Total amount of bytes read is (size x count).
Returns
The number of items (not bytes) read is returned. If this number differs from the requested amount (count) an error has occurred or the End Of File has been reached (use ffs_ferror or ffs_feof to check what happened).
(For a very fast method of reading complete sectors at a time see the ‘Using The Driver In A Project’ section in this manual).
Store Any Unwritten Data To The Card
int ffs_fflush (FFS_FILE *file_pointer)
Write any data that is currently held in microcontroller / processor ram that is waiting to be written to the card. Update the file filesize value if it has changed.
This function does not need to be called by your application, but may be called if your application opens a file for a long period of time to avoid data loss if your device suddenly looses power.
Returns
0 if successful, 1 otherwise
Close File
int ffs_fclose (FFS_FILE *file_pointer)
Closes an open file, saving any unsaved data to the card and updating the file filesize value if it has changed.
Returns
0 if successful, 1 otherwise
Delete File
int ffs_remove (const char *filename)
This function is optimised to avoid unnecessary read and writes of the FAT table to greatly improve its speed.
Returns
0 if the file is successfully deleted, 1 if there was an error (the file doesn’t exist or can’t be deleted as its currently open.
Change File Size
int ffs_change_file_size (const char *filename, DWORD new_file_size)
This function allows you to increase or decrease a files size and is included to allow faster writing in certain situations. When writing a new file every time a sector is completed the driver must read the FAT table to find the next available sector, write to both FAT tables to mark the next sector as now used and then continue with writing the file. When needing to write a large amount of live data quickly this repeated process has a significant effect on write speeds and data buffering requirements. By using this function an application has the possibility to create an oversized file prior to the write starting and then overwriting the file with the data to be stored. As the file is already big enough all the driver has to do as each sector is completed is read the FAT table to find the location of the next sector, removing the need to scan and write to both FAT tables. Once the writing of the file is complete, if the total size of the data is smaller than the file size this function can be used again to reduce the file size.
Returns
0 if the file size was successfully changed, 1 if there was an error (the file doesn’t exist or can’t be changed as its currently open.
Rename File
int ffs_rename (const char *old_filename, const char *new_filename)
Returns
0 if the file is successfully renamed, 1 if there was and error (the file doesn’t exist or can’t be renamed as its currently open)
Clear Error & End Of File Flags
void ffs_clearerr (FFS_FILE *file_pointer)
Has End Of File Been Reached
int ffs_feof (FFS_FILE *file_pointer)
Has An Error Occurred During File Access
int ffs_ferror (FFS_FILE *file_pointer)
Is A Card Inserted And Available
BYTE ffs_is_card_available (void)
Do Background Tasks
void ffs_process (void)
This function needs to be called regularly from your applications main loop to detect a new card being inserted so that it can be initialised ready for access.