This section documents the API support for line based text files.
Sequential text read operations use file control block TFCB_Type. Sequential text writes use the limited file control block TWCB_Type.
type TFCB_Type is private; type TWCB_Type is limited private;
The following outlines a quick reference for all text read/write API:
procedure Open_File(File : out TFCB_Type; Dir_Entry : Dir_Entry_Type; OK : out Boolean); procedure Open_File(File : out TFCB_Type; Dir : in out DCB_Type; Name : String; OK : out Boolean); procedure Rewind_File(File : in out TFCB_Type); procedure Read_Char(File : in out TFCB_Type; Char : out Character; OK : out Boolean); procedure Read_Line(File : in out TFCB_Type; Line : out String; Last : out Natural; OK : out Boolean); procedure Read(File : in out TFCB_Type; Buffer : out U8_Array; Count : out Unsigned_16; OK : out Boolean); procedure Read(File : in out TFCB_Type; Data : out Unsigned_8; OK : out Boolean); procedure Read(File : in out TFCB_Type; Data : out Unsigned_16; OK : out Boolean); procedure Read(File : in out TFCB_Type; Data : out Unsigned_32; OK : out Boolean); procedure Close_File(File : in out TFCB_Type); procedure Open_File(File : out TWCB_Type; Dir : in out DCB_Type; Name : String; OK : out Boolean); procedure Create_File(File : out TWCB_Type; Dir : in out DCB_Type; Name : String; OK : out Boolean); procedure Put(File : in out TWCB_Type; Char : Character; OK : out Boolean); procedure Put(File : in out TWCB_Type; Text : String; OK : out Boolean); procedure Put_Line(File : in out TWCB_Type; Text : String; OK : out Boolean); procedure Write(File : in out TWCB_Type; Buffer : U8_Array; OK : out Boolean); procedure Write(File : in out TWCB_Type; Data : Unsigned_8; OK : out Boolean); procedure Write(File : in out TWCB_Type; Data : Unsigned_16; OK : out Boolean); procedure Write(File : in out TWCB_Type; Data : Unsigned_32; OK : out Boolean); procedure New_Line(File : in out TWCB_Type; OK : out Boolean); procedure Sync_File(File : in out TWCB_Type; OK : out Boolean); procedure Close_File(File : in out TWCB_Type; OK : out Boolean);
This subsection documents the facilities for reading text files.
The following procedures permit the caller to open an existing text file. The argument Dir_Entry contains all the information needed to open the file. The second call using Dir and Name arguments, specify the directory and the name of the file in that directory. When successful, file control block File is populated and OK is returned as True. The named object must be a file.
procedure Open_File(File : out TFCB_Type; Dir_Entry : Dir_Entry_Type; OK : out Boolean); procedure Open_File(File : out TFCB_Type; Dir : in out DCB_Type; Name : String; OK : out Boolean);
An open text file may be rewound so that it can be read again, without closing and reopening it. The rewind always succeeds (unless File is not open).
procedure Rewind_File(File : in out TFCB_Type);
The Read_Char procedure allows an application to read one character from the open text file. OK is set to True when successful, or False if an error or end-file occurs.
'''Warning - this procedure is inefficient''', and is provided for special cases. Each call requires a physical sector read prior to returning the single character.
procedure Read_Char(File : in out TFCB_Type; Char : out Character; OK : out Boolean);
This procedure returns one text line in buffer argument Line. The last valid subscript returned is indicated in argument Last. Argument OK is returned as True if a text line was returned. Otherwise an error or end-file occurred.
procedure Read_Line(File : in out TFCB_Type; Line : out String; Last : out Natural; OK : out Boolean);
The following procedure permits the application to read up to Buffer'Length Unsigned_8 values from the text file. The actual number of values returned is passed back in Count. OK is set to True if any data was returned. OK will be False if an error or end-file is encountered.
procedure Read(File : in out TFCB_Type; Buffer : out U8_Array; Count : out Unsigned_16; OK : out Boolean);
The following procedure calls permits one Unsigned_8, Unsigned_16 or Unsigned_32 value to be read from the file. These values could be used to indicate a record length (for example). They should be otherwise avoided, since these always require a physical read for each call. OK is returned True if the data item was successfully read and returned. False indicates an error, incomplete read or end-file.
procedure Read(File : in out TFCB_Type; Data : out Unsigned_8; OK : out Boolean); procedure Read(File : in out TFCB_Type; Data : out Unsigned_16; OK : out Boolean); procedure Read(File : in out TFCB_Type; Data : out Unsigned_32; OK : out Boolean);
The Close_File procedure simply marks argument File as invalid, to prevent accidental re-use by the application.
procedure Close_File(File : in out TFCB_Type);
This section outlines a text write API.
The following operation opens an existing text file for overwriting. Any prior contents are released and the control block is positioned to write the first text line of the file. OK is returned as True if Name exists in Dir as a file and is writable.
procedure Open_File(File : out TWCB_Type; Dir : in out DCB_Type; Name : String; OK : out Boolean);
The Create_File procedure creates a new text file of name Name in directory Dir. When successful, the argument File is populated and made ready for text file writing. OK is returned as True when successful. OK will be false when this fails. If the file or object already exists, then the operation fails.
procedure Create_File(File : out TWCB_Type; Dir : in out DCB_Type; Name : String; OK : out Boolean);
This procedure puts a single character into the text file being written.
'''Warning - this is inefficient''', since each character is "put" with a physical I/O. This API is provided for special/rare circumstances.
procedure Put(File : in out TWCB_Type; Char : Character; OK : out Boolean);
This procedure puts the characters in argument Text out to the text file being written, with no line termination. OK is returned True when successful.
procedure Put(File : in out TWCB_Type; Text : String; OK : out Boolean);
This procedure is similar to writing a string, except that a "newline" is also added to the end. This will mark the end of the line. OK is returned as True when successful.
procedure Put_Line(File : in out TWCB_Type; Text : String; OK : out Boolean);
This procedure allows the application to write an arbitrary sequence of bytes out to the text file. The value OK is returned True if the full length of Buffer was successfully written.
procedure Write(File : in out TWCB_Type; Buffer : U8_Array; OK : out Boolean);
These procedures permit an Unsigned_8, Unsigned_16 or Unsigned_32 to be written as a single unit. This requires a physical I/O each time this is done, and should be avoided. OK is returned as True if the argument Data was fully written out.
procedure Write(File : in out TWCB_Type; Data : Unsigned_8; OK : out Boolean); procedure Write(File : in out TWCB_Type; Data : Unsigned_16; OK : out Boolean); procedure Write(File : in out TWCB_Type; Data : Unsigned_32; OK : out Boolean);
The following procedure puts the necessary characters out to the text file to mark the end of a line (CRLF). OK
is returned as True if this was successful.
procedure New_Line(File : in out TWCB_Type; OK : out Boolean);
This procedure performs most of the operations normally performed by a close. It is provided for data logging applications to make sure that the file's size (in bytes) is updated in the directory entry. Otherwise a failed or interrupted data logging application may lose all its data because the directory entry still shows zero bytes.
After being called, the application is free to continue adding text to the file.
OK is returned True if the directory entry was successfully updated on the media.
procedure Sync_File(File : in out TWCB_Type; OK : out Boolean);
This procedure performs the functions of Sync_File and then marks argument File as invalid. This prevents any accidental re-use of it within the application. OK is returned True when the Sync_File is successful.
procedure Close_File(File : in out TWCB_Type; OK : out Boolean);
This example demonstrates an AVR logging process that creates or overwrites a text log file in the root directory, named MYLOG.LOG.
Within the logging loop, function My_Logged_Text is a user supplied AVR routine, that returns a string of text to be logged to the SD/MMC memory card. The Put_Line procedure call uses the open log file to write it out to the log file. The loop exits if an I/O error occurs (perhaps it ran out of space or a sector failed to write successfully).
The Sync_File call that follows in the loop is useful for logging programs. Non-logging programs need not call it. It is used by logging programs to make sure that the directory entry pointing to the file's content, is updated with the file's true size in bytes. Otherwise, the directory entry would still reflect a file size of zero bytes. If the logging process fails, then the file would be interpreted as "empty" (when opened), even though the content exists in the cluster(s) written. Normally the file's size is not updated until the file is closed.
If the logging application is logging a lot of information in rapid succession, it is advisable to control the frequency of calls to Sync_File. For example, you might call Sync_File on every 8th time through the loop, or when some timeout occurs.
with Interfaces; use Interfaces; with FATFS; use FATFS; procedure Example_1 is D : DCB_Type; -- Directory control block F : TWCB_Type; -- Text Write control block OK : Boolean; -- Success flag begin Open_Dir(D,OK); -- Open root directory pragma Assert(OK); -- Create new log file, or overwrite existing log Create_File(F,D,"MYLOG.LOG",OK); if not OK then Open_File(F,D,"MYLOG.LOG",OK); end if; pragma assert(OK); Close_Dir(D); -- No longer need directory loop declare -- Generated event text to be logged Log_Msg : String := My_Logged_Text; begin Put_Line(F,Log_Msg,OK); -- Write text line end; exit when not OK; -- Exit if write error Sync_File(F,OK); -- Optional : update directory with log size exit when not OK; -- Exit if an error occurs end loop; Close_File(F,OK); -- Close file end Example_1;
Example 2 shows an AVR program reading the text log file created by Example 1. The call to Read_Line returns with OK set to False when it reaches end-file, or encountered an error.
with Interfaces; use Interfaces; with FATFS; use FATFS; procedure Example_2 is D : DCB_Type; -- Directory control block F : TFCB_Type; -- File control block OK : Boolean; -- Success/Failure flag begin Open_Dir(D,OK); -- Open root directory pragma Assert(OK); Open_File(F,D,"MYLOG.LOG",OK) ; -- Open log for reading pragma assert(OK); Close_Dir(D); -- DCB no longer required declare Line : String(1..120); Last : Natural; begin loop Read_Line(F,Line,Last,OK); -- Read one line of text exit when not OK; -- exit when EOF/Error -- Do something with Line(1..Last) end loop; end loop; Close_File(F); -- Close file end Example_2;