Menu

FATFS_File_System Log in to Edit

FATFS - File System Open/Close/Format

This group of API functions opens and closes a FAT file system. In order for any of the
FATFS functions to succeed, the file system must be open (with exceptions noted where applicable).

File System Time and Date

The fatfs package uses its own internal sense of date and time for date/time stamps for files
created or written. It is the application program's responsibility to update the fatfs sense of
the current date and time. This manner of operation keeps the implementation of time decoupled
between the physical hardware and the FAT file system implementation.

Set/Get File System Date/Time

These routines may be called without an open file system. These simply get or set the fatfs
package's sense of what the date and time currently is.

An application may set up an interrupt driven call to Set_FS_Time, to keep fatfs package's
sense of time up to date.

type FS_Time_Type

All time setting or fetching occurs through this defined type:

type FS_Time_Type is record
Year :          Year_Type;
Month :         Month_Type;
Day :           Day_Type;
Hour :          Hour_Type;
Minute :        Minute_Type;
Second2 :       Seconds2_Type;
end record;

Set_FS_Time

Calling Set_FS_Time establishes fatfs's current sense of date and time. Any file operations requiring
a date and time stamp following this call, will be stamped with this date and time.

procedure Set_FS_Time(Time : FS_Time_Type);

Get_FS_Time

An application may inquire of fatfs's sense of date and time, using the following procedure:

procedure Get_FS_Time(Time : out FS_Time_Type);

Set I/O Context

Before you can open a file system and perform file or directory operations, the I/O context must be established. This is defined by calling Register_Read_Proc with your Read sector routine and Register_Write_Proc with your sector write routine.

If you are only performing read operations, you can omit the call to Register_Write_Proc.

type Read_Proc is access
procedure(Sector : Sector_Type; Block : out Block_512; OK : out Boolean);

type Write_Proc is access
procedure(Sector : Sector_Type; Block : Block_512; OK : out Boolean);

procedure Register_Read_Proc(Read : Read_Proc);         -- Read one sector
procedure Register_Write_Proc(Write : Write_Proc);      -- Write one sector

Read Boot Sector

This procedure may be called at any time to read the boot sector, provided that the I/O context has been established for reading.

procedure Read_Boot_Sector(Boot_Sector : out Boot_Sector_Type; OK : out Boolean);

Open File System

Before any file or directory operations can be performed, the file system must be opened with the following procedure:

procedure Open_FS(OK : out Boolean);

The value OK will be true if there were no errors.

Read-Only Operation

The opened file system is only available for reading if the Register_Write_Proc procedure was not called to define a write operation. Should a write operation be attempted in this case, the library will abort in a non-AVR environment. In the AVR environment, the process fails (hangs?) because the procedure access type is null.

Instance Notes

The fatfs library was designed to be small and effective for small AVR MCUs. Consequently, it is only designed to support one opened file system at a time.

File System

The following function returns what file system type is currently open. The file system must be open for the result to be valid:

function File_System return FS_Type;

OEM Name

Returns the OEM Name that is recorded in the boot sector. The file system must be open.

function OEM_Name return String;

Volume Name

The following function returns the file system's volume name. The file system must be open.

function Volume return String;

Close File System

The following procedure closes the currently open file system.

procedure Close_FS;

Free Space

This function returns the amount of free disk space available, in bytes. This call should be used sparingly, since it traverses the entire FAT table to determine space available.

function Free_Space return Unsigned_32;

Test Information Functions

Normally an application should not be concerned about the physical aspects of the file system. The following series of functions are intended for the test suite's use, to test the fatfs package. However, these API functions are publicly available for applications that might wish to use them.

FS_Root_Entries

For FAT16 file systems, this function returns the maximum number of root directory entries available in the root directory for the currently open file system.

FAT32 file systems return zero, since the root directory resides in a cluster, which can grow in size.

function FS_Root_Entries return Unsigned_16;

FS_Sectors_Per_Cluster

For all FAT file systems supported, this function returns the number of sectors per cluster for the currently open file system (the sector is fixed at 512 bytes in this implementation).

function FS_Sectors_Per_Cluster return Unsigned_16;

FS_Clusters

For all FAT file systems supported, this function returns the number of clusters available in the currently open file system.

function FS_Clusters return Unsigned_32;

Format File System

The Format procedure call can be used to perform a "fast format" of the file system. A "fast format" involves the following minimal steps:

  • A boot sector is created, without bootloader code
  • All reserved sectors (if any) are zeroed
  • All n FAT tables are written out, sector by sector (1 to 4 FAT tables max)
  • For FAT16, the root directory sectors are initialized
  • For FAT32, the root directory cluster is initialized
  • The last sector of each FAT has the last few non-existing clusters marked as unavailable

There is no bad sector checking. The entire medium (Total_Sectors) is assumed to be usable. Sector numbers start at zero.

If the AVR application is formatting a volume that requires a physical format operation, like a a retro 8 inch floppy project, the caller should perform that operation prior to invoking
this procedure. However, it will be assumed that all sectors are usable (no media defects are tolerated in the present implementation).

procedure Format(
Total_Sectors :         in      Sector_Type;            -- Device # of sectors
Sectors_Per_Cluster :   in      Unsigned_8;             -- Sectors per cluster
OK :                       out  Boolean;                -- Result of format
Root_Dir_Entries_16 :   in      Unsigned_16 := 512;     -- FAT16 Directory entries
OEM_Name :              in      String := "FATFS";      -- OEM Name to use
No_Of_FATs :            in      FAT_Copies_Type := 1;   -- # of FATs (4 max)
Reserved_Sectors :      in      Unsigned_16 := 1        -- Reserved sectors, including boot sector
);

Total_Sectors

This is the total number of 512 byte sectors available for use as a file system. The file system must include sector numbers starting at zero and extending through to Total_Sectors - 1.

Sectors_Per_Cluster

This value must be a power of 2, with a valid values starting at 1, 2, 4, 8 etc.

OK

This value is returned as True if the format operation succeeded. Note that many combinations of input parameters may lead to an immediate failure. For example a FAT16 file system may not have more than 16#FFFF# sectors.

Another potential problem is that the number of clusters is too small. If the total number of clusters (+2) is less than 16#0FFF#, DOS/Windows will expect a FAT12 file system, which is not supported here.

Root_Dir_Entries_16

This value specifies the maximum number of root directory entries to allocate. Specify zero for FAT32, as it's root directory is allocated in a cluster. A typical value used for FAT16 is 1024 directory entries.

OEM_Name

This is an optional OEM name, which defaults to "FATFS".

No_Of_FATs

This value defaults to 1, which specifies the number of FAT tables to allocate. Currently fatfs only uses the first FAT table.

Reserved_Sectors

If you wish to reserve sectors following the boot sector, indicate it here. The default is to allocate one hidden sector.

Format Limitations

The Format function doesn't rigorously check or enforce all aspects of the FAT file system compatibility rules. For compatibility, please make note of the following subsections.

512 MB or Less

For compatibility, the file system must be greater than 512 MB in size. Otherwise operating systems expect the file system to be a FAT12 format, which fatfs does not support.

The fatfs package can support small images as a FAT16 image but the resulting file system will not be compatible with external implementations. This might be useful in a small AVR fixed disk (or memory card) where the file system is not shared externally.

FAT16 Limitations

A FAT16 file system is limited to a maximum of 2 GB in size.

FAT32 Limitations

The FAT32 file system supports file systems up to 2 terabytes. Additionally a FAT32 volume must contain a minimum of 65,527 clusters in total. Otherwise external systems will expect a FAT16 file system. The same will apply to the fatfs package when it goes to open the formatted file system image.

Cluster Sizes

For FAT16 or FAT32 file systems, the cluster size should not be larger than 64KB (128 sectors per cluster). This will insure compatibility with Windows XP and later. The maximum cluster size should not be larger than 32KB (64 sectors per cluster), if compatibility with Windows operating systems prior to XP.

The fatfs package cannot use a sector size other than 512 bytes. This means that the maximum cluster size (for XP) is:

  • 64KB / 512 => 128 sectors per cluster.

The fatfs package may format and support file system configurations that are incompatible with Windows operating systems. For example the fatfs package will support clusters greater than 128 sectors per cluster. The above limitations are important for compatibility. The limits may also be somewhat different for Linux implementations of the FAT file system. This was not researched or tested, however.

For these reasons, the user should carefully choose his format parameters.

Example 1 - Simulated File System

In the test subdirectory, are the following source modules applicable to testing fatfs on a non-AVR platform (recommended):
test/adaio.ads
test/adaio.adb
The spec of adaio.ads consists of these definitions:

with FATFS;
use FATFS;

package AdaDIO is

procedure Open(Pathname : String; For_Write, Create : Boolean := False);
procedure Read(Sector : Sector_Type; Block : out Block_512; OK : out Boolean);
procedure Write(Sector : Sector_Type; Block : Block_512; OK : out Boolean);
procedure Close;

end AdaDIO;

The Open routine permits you to create or open an existing FAT file system image file. Open also controls whether or not you wish to open the file system for writing (argument For_Write). The Close routine naturally closes it. The Read and Write routines are supplied to the IO_Context, to define the input/output procedures to be used by fatfs.

Your testbed program, can look something like this:

with AdaDIO;
with FATFS;                            use FATFS;

package body My_Tests is

procedure My_Test is
begin

AdaDIO.Open("fatfs.img",For_Write => True, Create => True);

FATFS.Format(
Total_Sectors        => 50_000,
Sectors_Per_Cluster  => 128,
Root_Dir_Entries_16  => 1024,
OEM_Name             => "XFAT16",
No_Of_FATs           => 1,
OK                   => OK
);
pragma Assert(OK);

FATFS.Open_FS(OK);
pragma Assert(OK);

...tests on the open FAT16 fs...

FATFS.Close_FS;
AdaDIO.Close;

end My_Test;

The above example first creates a file system image file named "fatfs.img" on your non-AVR platform.

The Format call creates a FAT16 file system with a total of 50,000 sectors, using 128 sectors / cluster, 1024 root directory entries, OEM Name of "XFAT16", and one FAT table.

The Open_FS opens the file system and if OK is returned as True, any fatfs call may now be used.

Once the tests are completed, close the file system with Close_FS. Finally, calling AdaDIO.Close closes the underlying Ada.Direct_IO file that is simulating the SD/MMC card.

AVR code would NOT be using the AdaDIO package at all. The caller would supply his own Read/Write sector routines to be used by fatfs.

Read/Write Procs

One thing that has not been shown yet, is how the Read/Write sector routines have been registered. This happens in the test package AdaDIO:

procedure Open(Pathname : String; For_Write, Create : Boolean := False) is
Need_Create : Boolean := False;
begin

if not For_Write then
DIO.Open(File,DIO.In_File,Pathname);         -- Open existing file system image
else
begin
DIO.Open(File,DIO.Inout_File,Pathname);   -- Open image for read/write
exception
when Ada.IO_Exceptions.Name_Error =>
Need_Create := True;                   -- Image does not exist yet
end;

if Need_Create then
if not Create then
raise Ada.IO_Exceptions.Name_Error;          -- Raise an error (no image file to open)
else
DIO.Create(File,DIO.Inout_File,Pathname);    -- Create a new image file
end if;
end if;
end if;

Register_Read_Proc(Read'Access);         -- Tell file system about how to read a sector
Register_Write_Proc(Write'Access);       -- Tell file system about how to write

end Open;

Once the Ada.Direct_IO file is opened, the following two routines then register the Read and Write routines:

Register_Read_Proc(Read'Access);         -- Tell file system about how to read a sector
Register_Write_Proc(Write'Access);       -- Tell file system about how to write

An AVR application (obviously not using AdaDIO) would need to supply their own Read and Write routines this way. These registrations tell the fatfs package how to read and write a sector, on the AVR platform. For SD/MMC cards, there would be a Read and Write procedure supplied for the purpose, for example.


Related

Wiki: Fatfs

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.