📄 emFloat User Guide & Reference Manual
📄 emNet User Guide & Reference Manual
📄 emRun User Guide & Reference Manual
📄 emSecure-ECDSA User Guide & Reference Manual
📄 emSecure-RSA User Guide & Reference Manual
📄 emSSH User Guide & Reference Manual
📄 emSSL User Guide & Reference Manual
📄 emUSB-Device User Guide & Reference Manual
📄 emUSB-Host User Guide & Reference Manual
📄 emVNC User Guide & Reference Manual
📄 emWeb User Guide & Reference Manual
📄 emWin User Guide & Reference Manual
📄 IoT Toolkit User Guide & Reference Manual
📄 SEGGER Assembler User Guide & Reference Manual
📄 SEGGER Linker User Guide & Reference Manual
📄 SEGGER SystemView User Guide
📄 SEGGER Online Documentation
📄 AppWizard User Guide & Reference Manual
📄 embOS Real-Time Operating System User Guide & Reference Manual
📄 embOS-Ultra Real-Time Operating System User Guide & Reference Manual
📄 emCompress-Embed User Guide & Reference Manual
📄 emCompress-ToGo User Guide & Reference Manual
📄 emCrypt User Guide & Reference Manual
📄 emDropbox User Guide & Reference Manual
📄 emFile User Guide & Reference Manual

emFile User Guide & Reference Manual

CPU-independent file system for embedded applications.

Introduction to emFile

This section presents an overview of emFile, its structure, and its capabilities.

What is emFile

emFile is a file system design for embedded applications which supports NAND, DataFlash, NOR and SPI Flash, SD and MMC Memory Cards, RAM and USB mass storage devices. emFile is a high performance library optimized for high speed, versatility and a minimal memory footprint of both RAM and ROM. It is written in ANSI C and can be used on any CPU.

Features

The main features of emFile are:

Basic concepts

This section describes the software structure of emFile as well as other general concepts such as fail safety and wear leveling.

emFile structure

emFile is organized in different layers as illustrated in the following diagram. A short description of each layer’s functionality follows below.

File system structure

API layer

The API layer is the interface between emFile and the user application. It is divided in two parts storage API and file system API. The file system API declares file functions in ANSI C standard I/O style, such as FS_FOpen(), FS_FWrite() etc. The API layer transfers any calls to these functions to the file system layer. Currently the FAT file system or an optional file system, called EFS, are available for emFile. Both file systems can be used simultaneously. The storage API declares the functions which are required to initialize and access a storage medium. The storage API allows sector read and write operations. The API layer transfers these calls to the storage layer. The storage API is optimized for applications which do not require file system functionality like file and directory handling. A typical application which uses the storage API could be a USB mass storage device, where data has to be stored on a medium, but all file system functionality is handled by the host PC.

File system layer

The file system layer translates file operations to logical block (sector) operations. After such a translation, the file system calls the logical block layer and specifies the corresponding device driver for a device.

Storage layer

The main purpose of the Storage Layer is to synchronize accesses to a device driver. Furthermore, it provides a simple interface for the File System API. The Storage Layer calls a device driver to perform a block operation. It also contains the cache mechanism.

Driver layer

Device drivers are low-level routines that are used to access sectors of the device and to check status. It is hardware independent but depends on the storage medium.

Hardware layer

These layer contains the low-level routines to access your hardware. These routines simply read and store fixed length sectors. The structure of the device driver is simple in order to allow easy integration of your own hardware.

Choice of file system type: FAT vs. EFS

Within emFile, there is a choice among two different file systems. The first, the FAT file system, is divided into three different sub types, FAT12, FAT16 and FAT32. The other file system EFS, is a proprietary file system developed by SEGGER. The choice of the suitable file system depends on the environment in which the end application is to operate.

The FAT file system was developed by Microsoft to manage file segments, locate available clusters and reassemble files for use. Released in 1976, the first version of the FAT file system was FAT12, which is no longer widely used. It was created for extremely small storage devices. (The early version of FAT12 did not support managing directories).

FAT16 is good for use on multiple operating systems because it is supported by all versions of Microsoft Windows, including DOS and Linux. The newest version, FAT32, improves upon the FAT16 file system by utilizing a partition/disk much more efficiently. It is supported by all Microsoft Windows versions newer than Windows 98 and as well on Linux based systems.

The EFS file system was added to emFile as an alternative to the FAT file system and was specifically designed for embedded devices. This file system uses the storage space dedicated to the file and directory names more efficiently while still offering faster access to embedded storage devices. Another benefit of EFS is that there are no issues concerning long file name (LFN) support. The FAT file system was not designed for long file name support, limiting names to twelve characters (8.3 format). LFN support may be added to any of the FAT file systems. Long file names are inherent to this proprietary file system.

Fail safety

Fail safety is the feature of emFile that ensures the consistency of data in case of unexpected loss of power during a write access to a storage medium. emFile will be fail-safe only when both the file system (FAT/EFS) and the device driver are fail-safe. The journaling add-on of emFile makes the FAT/EFS file systems fail-safe. The device drivers of emFile are all fail-safe by design. You can find detailed information about how the fail-safety works in chapter Journaling and as part of the description of individual device drivers.

Wear leveling

This is a feature of the NAND and NOR flash device drivers that increase the lifetime of a storage medium by ensuring that all the storage blocks are equally well used. The flash storage memories have a limited number of program/erase cycles, typically around 100,000. The manufacturers do not guarantee that the storage device will work properly once this limit is exceeded. The wear leveling logic implemented in the device drivers tries to keep the number of program-erase cycles of a storage block as low as possible. You can find additional information in the description of the respective device drivers.

Implementation notes

This section provides information about the implementation of emFile

File system configuration

The file system is designed to be configurable at runtime. This has various advantages. Most of the configuration is done automatically; the linker builds in only code that is required. This concept allows to put the file system in a library. The file system does not need to be recompiled when the configuration changes, e.g. a different driver is used. Compile time configuration is kept to a minimum, primarily to select the level of multitasking support and the level of debug information. For detailed information about configuration of emFile, refer to Configuration of emFile.

Runtime memory requirements

Because the configuration is selected at runtime the amount of memory required is not known at compile-time. For this reason a mechanism for runtime memory assignment is required. Runtime memory is typically allocated when required during the initialization and in most embedded systems never freed.

Initializing the file system

The first thing that needs to be done after the system start-up and before any file system function can be used, is to call the function FS_Init(). This routine initializes the internals of the file system. While initializing the file system, you have to add your target device to the file system. The function FS_X_AddDevices() adds and initializes the device.

  FS_Init()
    |
    +-> FS_X_AddDevices()
          |
          +-> FS_AssignMemory()
          |
          +-> FS_AddDevice()
          |
          +-> Optional: Other configuration functions

Development environment (compiler)

The CPU used is of no importance; only an ANSI-compliant C compiler complying with at least one of the following international standards is required:

Getting started

This chapter provides an introduction to using emFile. It explains how to use the Windows sample, which is an easy way to get a first project with emFile up and running.

Package content and installation

emFile is provided in source code and contains everything needed to compile it on any platform. The following table shows the contents of the emFile package:

Files Description
Application Sample applications.
BSP Support files for different evaluation boards
Config Configuration header files.
Doc emFile documentation.
FS emFile source code.
Inc Global header files.
Linux Utility applications for Linux.
Sample Sample drivers and applications.
SEGGER Utility source code.
Simulation Support files for PC simulation.
Windows Utility applications for Windows.
FS_Start.* PC simulation project MS Visual Studio / C++ and FAT.
FS_EFS_Start.* PC simulation project MS Visual Studio / C++ and EFS.
FS_STORAGE_Start.* PC simulation project MS Visual Studio / C++ and storage layer.

emFile is shipped in electronic form in a .zip file. In order to install it, extract the .zip file to any folder of your choice, preserving the directory structure of the .zip file.

Using the Windows sample application

If you have MS Visual C++ 6.00 or any later version available, you will be able to work with a Windows sample project using emFile. Even if you do not have the Microsoft compiler, you should read this chapter in order to understand how an application can use emFile.

Building the sample application

Open the workspace FS_Start.sln with MS Visual Studio (for example double-clicking it). There is no further configuration necessary. You should be able to build the application without any error or warning message.

Overview of the sample application

The sample project uses the RAM disk driver for demonstration. The main function of the sample application Start.c calls the function MainTask(). MainTask() initializes the file system and executes some basic file system operations. The sample application Start.c step-by-step:

void main(void);
void main(void) {
  MainTask();                                           
}
void MainTask(void) {
  U32          v;
  FS_FILE    * pFile;
  char         ac[256];
  char         acFileName[32];
  const char * sVolumeName = "";

  FS_X_Log("Start\n");
  //
  // Initialize file system
  //
  FS_Init();                                            
  //
  // Check if low-level format is required
  //
  FS_FormatLLIfRequired(sVolumeName);                   
  //
  // Check if volume needs to be high level formatted.
  //
  if (FS_IsHLFormatted(sVolumeName) == 0) {             
    FS_X_Log("High-level format\n");
    FS_Format(sVolumeName, NULL);
  }
  sprintf(ac, "Running sample on \"%s\"\n", sVolumeName);
  FS_X_Log(ac);                                         
  v = FS_GetVolumeFreeSpaceKB(sVolumeName);             
  if (v < 0x8000) {
    sprintf(ac, "  Free space: %lu KBytes\n", v);
  } else {
    v >>= 10;
    sprintf(ac, "  Free space: %lu MBytes\n", v);
  }
  FS_X_Log(ac);
  sprintf(acFileName, "%s\\File.txt", sVolumeName);
  sprintf(ac, "  Write test data to file %s\n", acFileName);
  FS_X_Log(ac);
  pFile = FS_FOpen(acFileName, "w");                    
  if (pFile) {
    FS_Write(pFile, "Test", 4);                         
    FS_FClose(pFile);
  } else {
    sprintf(ac, "Could not open file: %s to write.\n", acFileName);
    FS_X_Log(ac);
  }
  v = FS_GetVolumeFreeSpaceKB(sVolumeName);             
  if (v < 0x8000) {
    sprintf(ac, "  Free space: %lu KBytes\n", v);
  } else {
    v >>= 10;
    sprintf(ac, "  Free space: %lu MBytes\n", v);
  }
  FS_X_Log(ac);
  FS_Unmount(sVolumeName);
  FS_X_Log("Finished\n");                               
  while (1) {
    ;
  }
}

  Application start main.c calls MainTask().   File system initialization MainTask() initializes and adds a device to emFile.   Low-level formatting Checks if volume is low-level formatted and formats if required.   High-level formatting Checks if volume is high-level formatted and formats if required.   Volume name Outputs the volume name.   Free space before operation Calls FS_GetVolumeFreeSpace() and outputs the return value - the available free space of the RAM disk - to console window.   File creation Creates and opens a file test with write access (File.txt) on the device.   File write Writes 4 bytes into the file and closes the file handle or outputs an error message.   Free space after operation Calls FS_GetVolumeFreeSpace() and outputs the return value - the available free space of the RAM disk - again to console window.   End of application Outputs a quit message and runs into an endless loop.

Stepping through the sample application

  Application start After starting the debugger by stepping into the application, your screen should look like the screenshot below. The main function calls MainTask().

Application start

  File system initialization The first thing called from MainTask() is the emFile function FS_Init(). This function initializes the file system and calls FS_X_AddDevices(). The function FS_X_AddDevices() is used to add and configure the used device drivers to the file system. In the example configuration only the RAM disk driver is added. FS_Init() must be called before using any other emFile function. You should step over this function.

File system initialization

  Low-level formatting If the initialization was successful, FS_FormatLLIfRequired() is called. It checks if the volume is low-level formatted and formats the volume if required. You should step over this function.

  High-level formatting Afterwards FS_IsHLFormatted() is called. It checks if the volume is high-level formatted and formats the volume if required. You should step over this function.

  Volume name The volume name is printed in the console window.

  Free space before operation The emFile function FS_GetVolumeFreeSpace() is called and the return value is written into the console window.

  File creation Afterwards, you should get to the emFile function call FS_FOpen(). This function creates a file named File.txt in the root directory of your RAM disk. Stepping over this function should return the address of an FS_FILE structure. In case of any error, it would return 0, indicating that the file could not be created.

File creation

  File write If FS_FOpen() returns a valid pointer to an FS_FILE structure, the sample application will write a small ASCII string to this file by calling the emFile function FS_Write(). Step over this function. If a problem occurs, compare the return value of FS_Write() with the length of the ASCII string, which should be written. FS_Write() returns the number of elements which have been written. If no problem occurs the function emFile function FS_FClose() should be reached. FS_FClose() closes the file handle for File.txt. Step over this function.

  Free space after operation Continue stepping over until you reach the place where the function FS_GetVolumeFreeSpace() is called. The emFile function FS_GetVolumeFreeSpace() returns available free drive space in bytes. After you step over this function, the variable v should have a value greater than zero.

  End of application The return value is written in the console window.

End of application

Further source code examples

Further source code examples which demonstrate directory operations and performance measuring are available. All emFile source code examples are located in the Sample/FS/Application folder of the emFile shipment.

We recommend keeping emFile separate from your application files. It is good practice to keep all the program files (including the header files) together in the FS subdirectory of your project’s root directory. This practice has the advantage of being very easy to update to newer versions of emFile by simply replacing the FS directory. Your application files can be stored anywhere.

Note

When updating to a newer emFile version as files may have been added, moved or deleted, the project directories may need to be updated accordingly.

Note

Always make sure that you have only one version of each file!

It is frequently a major problem when updating to a new version of emFile if you have old files included and therefore mix different versions. If you keep emFile in the directories as suggested (and only in these), this type of problem cannot occur. When updating to a newer version, you should be able to keep your configuration files and leave them unchanged. For safety reasons, we recommend backing up (or at least renaming) the FS directories before updating.

Running emFile on target hardware

This chapter explains how to integrate and run emFile on your target hardware. It explains this process step-by-step.

Integrating emFile

The default configuration of emFile contains a single storage device: a RAM disk. This should always be the first step to check if emFile functions properly on your target hardware. We assume that you are familiar with the tools you have selected for your development (compiler, project manager, linker, etc.). You should therefore be able to add files, add directories to the include search path, and so on. It is also assumed that you are familiar with the OS that you will be using on your target system (if you are using one). The SEGGER Embedded Studio IDE (https://www.segger.com/embedded-studio.html) is used in this document for all examples and screenshots, but every other ANSI C toolchain can also be used. It is also possible to use makefiles; in this case, when we say “add to the project”, this translates into “add to the makefile”.

Procedure to follow

Integration of emFile is a relatively simple process, which consists of the following steps:

Step 1: Creating a simple project without emFile

We recommend that you create a small “hello world” program for your system. That project should already use your OS and there should be a way to display text on a screen or serial port. If you are using the SEGGER embOS (https://www.segger.com/products/rtos/embos/), you can use the start project shipped with the embOS for this purpose.

Start project

Step 2: Adding emFile to the start project

Add all source files from the following directories (and their subdirectories) to your project:

It is recommended to keep the provided folder structure.

Add source files

Configuring the include path

The include path is the path in which the compiler looks for include files. In cases where the included files (typically header files, .h) do not reside in the same directory as the C file to compile, an include path needs to be set. In order to build the project with all added files, you will need to add the following directories to your include path:

Include paths

Select the start application

For quick and easy testing of your emFile integration, start with the code found in the Application folder of the shipment. Exclude all files in the Application folder of your project except the supplied main.c and FS_Start.c files. The application performs the following steps:

Build the project and test it

Build the project. It should compile without errors and warnings. If you encounter any problem during the build process, check your include path and your project configuration settings. The start application should print out the storage space of the device twice, once before a file has been written to the device and once afterwards.

Step 3: Adding the device driver

To configure emFile with a device driver, two modifications have to be performed:

Each step is explained in the following sections. For example, the implementation of the MMC/SD driver is shown, but all steps can easily be adapted to every other device driver implementation.

Adding the device driver source to project

Add the driver sources to the project and add the directory to the include path.

Add device driver

Most drivers require additional hardware routines to work with the specific hardware. If your driver requires low-level I/O routines to access the hardware, you will have to provide them. Drivers which require hardware routines are:

Nearly all drivers have to be configured before they can be used. The runtime configuration functions which specify for example the memory addresses and the size of memory are located in the configuration file of the respective driver. All required configurations are explained in the configuration section of the respective driver. If you use one of the drivers which do not require hardware routines skip the next section and refer to Step 4: Activating the driver.

Adding hardware routines to project

A template with empty function bodies and in most cases one ore more sample implementations are supplied for every driver that requires hardware routines. The easiest way to start is to use one of the ready-to-use samples. The ready-to-use samples can be found in the subfolders Sample/FS/Driver/<DRIVER_DIR> of the emFile shipment where DRIVER_DIR is the type of the device driver. You should check the Readme.txt file located in the driver directory to see which samples are included. If there is one which is a good or close match for your hardware, it should be used. Otherwise, use the template to implement the hardware routines. The template is a skeleton driver which contains empty implementations of the required functions and is the ideal base to start the implementation of hardware specific I/O routines. What to do Copy the compatible hardware function sample or the template into a subdirectory of your work directory and add it to your project. The template file is located in the Sample/FS/Driver/<DRIVER_DIR> folder; the example implementations are located in the respective directories. If you start the implementation of hardware routines with the hardware routine template, refer to Device drivers for detailed information about the implementation of the driver specific hardware functions, else refer to section Step 4: Activating the driver.

Note

You cannot run and test the project with the new driver on your hardware as long as you have not added the proper configuration file for the driver to your project. Refer to section Step 4: Activating the driver for more information about the activation of the driver with the configuration file.

Step 4: Activating the driver

After adding the driver source, and if required the hardware function implementation, copy the FS_Config<DRIVER_NAME>.c file (for example, FS_ConfigMMC_CardMode.c for the MMC/SD card driver using card mode) into the Config folder of your emFile work directory and add it to your project.

Add template driver

The configuration files contain, all the runtime configuration functions of the file system. The configuration files include a start configuration which allows a quick and easy start with every driver. The most important function for the beginning is FS_X_AddDevices(). It activates and configures the driver, if required. A driver which does not require hardware routines has to be configured before it can be used.

Modifying the runtime configuration

The following example a single CFI compliant NOR flash chip with a 16-bit interface and a size of 256 Mbytes to the file system. The base address, the start address and the size of the NOR flash are defined using the macros FLASH0_BASE_ADDR, FLASH0_START_ADDR and FLASH0_SIZE. Normally, only the “Defines, configurable” section of the configuration files requires changes for typical embedded systems. The “Public code” section which includes the time and date functions and FS_X_AddDevices() does not require modifications on most systems.

/*********************************************************************
*
*       Defines, configurable
*
*       This section is the only section which requires changes for
*       typical embedded systems using the NOR flash driver with a
*       single device.
*
**********************************************************************
*/
#define ALLOC_SIZE         0x10000        // Size of memory dedicated to the file
                                          // system. This value should be fine-tuned
                                          // according for your system.
#define FLASH0_BASE_ADDR   0x40000000     // Base address of the NOR flash device
                                          // to be used as storage
#define FLASH0_START_ADDR  0x40000000     // Start address of the first sector
                                          // to be used as storage. If the entire
                                          // device is used for file system,
                                          // it is identical to
                                          // the base address.
#define FLASH0_SIZE        0x200000       // Number of bytes to be used for storage

/*********************************************************************
*
*       Static data.
*
*       This section does not require modifications in most systems.
*
**********************************************************************
*/
static U32 _aMemBlock[ALLOC_SIZE / 4];    // Memory pool used for semi-dynamic
                                          // allocation in FS_AssignMemory().
/*********************************************************************
*
*       Public code
*
*       This section does not require modifications in most systems.
*
**********************************************************************
*/

/*********************************************************************
*
*       FS_X_AddDevices
*
*  Function description
*    This function is called by the FS during FS_Init().
*    It is supposed to add all devices, using primarily FS_AddDevice().
*/
void FS_X_AddDevices(void) {
  FS_AssignMemory(&_aMemBlock[0], sizeof(_aMemBlock));
  //
  // Add driver the NOR driver.
  //
  FS_AddDevice(&FS_NOR_Driver);
  //
  // Configure the NOR flash interface.
  //
  FS_NOR_SetPhyType(0, &FS_NOR_PHY_CFI_1x16);
  FS_NOR_Configure(0, FLASH0_BASE_ADDR, FLASH0_START_ADDR, FLASH0_SIZE);
  //
  // Configure a read buffer for the file data.
  //
  FS_ConfigFileBufferDefault(512, 0);
}

After the driver has been added, the configuration functions (in this example FS_NOR_SetPhyType() and FS_NOR_Configure()) should be called. Detailed information about the driver configuration can be found in the configuration section of the respective driver. Refer to section Runtime configuration for detailed information about the other runtime configurations of the file system. Before compiling and running the sample application with the added driver, you have to exclude FS_ConfigRAMDisk.c from the project.

Note

For the drivers which required hardware access routines, if you have only added the template with empty function bodies until now, the project should compile without errors or warning messages. But you can only run the project on your hardware if you have finished the implementation of the hardware functions.

Step 5: Adjusting the RAM usage

The file system needs RAM for management purposes in various places. The amount of RAM required depends primarily on the configuration, especially the drivers used. The drivers which have their own level of management (such as NOR / NAND drivers) require in general more RAM than the “simple” drivers such as for hard drives, compact flash or MMC/SD cards. Every driver needs to allocate RAM. The file system allocates RAM in the initialization phase and holds it while the file system is running. The macro ALLOC_SIZE which is located in the respective driver configuration file specifies the size of RAM used by the file system. This value should be fine-tuned according to the requirements of your target system.

Per default, ALLOC_SIZE is set to a value which should be appropriate for most target systems. Nevertheless, you should adjust it in order to avoid wasting too much RAM. Once your file system project is up and running, you can check the real RAM requirement of the driver via the public variable FS_Global.MemManager.NumBytesAllocated. Check the value of FS_Global.MemManager.NumBytesAllocated after the initialization of the file system and after a volume has been mounted. At this point FS_Global.MemManager.NumBytesAllocated can be used as reference for the dynamic memory usage of emFile. You should reserve a few more bytes for emFile as the value of FS_Global.MemManager.NumBytesAllocated is at this point, since every file which is opened needs dynamic memory for maintenance information. For more information about resource usage of the file handlers, please refer to Dynamic RAM usage.

Note

If you define ALLOC_SIZE with a value which is smaller than the appropriate size, the file system will run into FS_X_Panic(). If you define ALLOC_SIZE with a value which is above the limits of your target system, the linker will give an error during the build process of the project.

API functions

This chapter provides a detailed description of emFile API layer.

General information

Any functions or data structures that are not described in this chapter but are exposed through inclusion of the FS.h header file must be considered private and subject to change.

Volume, file and directory names

A volume, file or directory name is a 0-terminated string the application can use as a parameter to an API function (such as FS_FOpen()) to identify a volume, file or directory the API function has to operate on.

A file or directory name contains the following mandatory and optional elements where the optional elements are surrounded by []:

[VolumeName:[UnitNo:]][DirPath]FileName|DirName

A volume name contains the following mandatory and optional elements where the optional elements are surrounded by []:

VolumeName:[UnitNo:]

VolumeName and UnitNo have the same meaning as described above.

Examples

The following examples specify the same file name assuming that the first driver added to file system is the NAND driver.

The following examples specify the same volume name assuming that the first driver added to file system is the NOR driver.

API function overview

The table below lists the available API functions within their respective categories.

Function Description
File system control functions
FS_Init() Starts the file system.
FS_DeInit() Frees allocated resources.
FS_Mount() Initializes a volume in default access mode.
FS_MountEx() Initializes a volume in a specified access mode.
FS_SetAutoMount() Sets the automatic mount behavior.
FS_Sync() Saves cached information to storage.
FS_Unmount() Synchronizes the data and marks the volume as not initialized.
FS_UnmountForced() Marks the volume as not initialized.
File system configuration functions
FS_AddDevice() Adds a driver to file system.
FS_AddPhysDevice() Adds a device to file system without assigning a volume to it.
FS_AssignMemory() Assigns a memory pool to the file system.
FS_ConfigFileBufferDefault() Configures the size and flags for the file buffer.
FS_LOGVOL_Create() Creates a driver instance.
FS_LOGVOL_AddDevice() Adds a storage device to a logical volume.
FS_SetFileBufferFlags() Changes the operating mode of the file buffer.
FS_SetFileBufferFlagsEx() Changes the operating mode of the file buffer.
FS_SetFileWriteMode() Configures the file write mode.
FS_SetFileWriteModeEx() Configures the write mode of a specified volume.
FS_SetMemHandler() Configures functions for memory management.
FS_SetMaxSectorSize() Configures the maximum size of a logical sector.
File access functions
FS_FClose() Closes an opened file.
FS_FGets() Reads a line of text from file.
FS_FOpen() Opens an existing file or creates a new one.
FS_FOpenEx() Opens an existing file or creates a new one.
FS_FPrintf() Writes a formatted string to a file.
FS_FPuts() Writes a 0-terminated string to a file.
FS_FRead() Reads data from file.
FS_FSeek() Sets the current position in file.
FS_FWrite() Writes data to file.
FS_FTell() Returns current position in file.
FS_GetFileSize() Returns the size of a file.
FS_Read() Reads data from a file.
FS_SetEndOfFile() Sets the file size to current file position.
FS_SetFileSize() Sets the file size to the specified number of bytes.
FS_SyncFile() Synchronizes file to storage device.
FS_Truncate() Changes the size of a file.
FS_Verify() Verifies the file contents.
FS_Write() Writes data to file.
Operations on files
FS_CopyFile() Copies a file.
FS_CopyFileEx() Copies a file.
FS_GetFileAttributes() Queries the attributes of a file or directory.
FS_GetFileInfo() Returns information about a file or directory.
FS_GetFileTime() Returns the creation time of a file or directory.
FS_GetFileTimeEx() Gets the timestamp of a file or directory.
FS_ModifyFileAttributes() Sets / clears the attributes of a file or directory.
FS_Move() Moves a file or directory to another location.
FS_Remove() Removes a file.
FS_Rename() Changes the name of a file or directory.
FS_SetFileAttributes() Modifies all the attributes of a file or directory.
FS_SetFileBuffer() Assigns a file buffer to an opened file.
FS_SetFileTime() Sets the creation time of a file or directory.
FS_SetFileTimeEx() Sets the timestamp of a file or directory.
FS_WipeFile() Overwrites the contents of a file with random data.
Directory functions
FS_CreateDir() Creates a directory including any missing directories from path.
FS_DeleteDir() Removes a directory and its contents.
FS_FindClose() Ends a directory scanning operation.
FS_FindFirstFile() Initiates a directory scanning operation and returns information about the first file or directory.
FS_FindNextFile() Returns information about the next file or directory in a directory scanning operation.
FS_FindNextFileEx() Returns information about the next file or directory in a directory scanning operation.
FS_MkDir() Creates a directory.
FS_RmDir() Removes a directory.
Formatting functions
FS_Format() Performs a high-level format.
FS_FormatLLIfRequired() Performs a low-level format.
FS_FormatLow() Performs a low-level format.
FS_IsHLFormatted() Checks if a volume is high-level formatted or not.
FS_IsLLFormatted() Returns whether a volume is low-level formatted or not.
Partitioning functions
FS_CreateGPT() Partitions the specified volume using a GPT (GUID Partition Table) partition scheme.
FS_CreateMBR() Partitions the specified volume using a MBR (Master Boot Record) partition scheme.
FS_GetGPTInfo() Returns information about the GPT partitioning.
FS_GetPartitionInfoMBR() Returns information about a MBR partition.
FS_GetPartitionInfoGPT() Returns information about a GPT partition.
FS_GetPartitioningScheme() Returns information about how a storage device is partitioned.
File system structure checking
FS_CheckAT() Verifies the consistency of the allocation table.
FS_CheckDir() Verifies the consistency of a single directory.
FS_CheckDisk() Checks the consistency of the file system structure.
FS_CheckDisk_ErrCode2Text() Returns a human-readable text description of a disk checking error code.
FS_InitCheck() Initializes a non-blocking disk checking operation.
File system extended functions
FS_ConfigEOFErrorSuppression() Enables / disables the reporting of end-of-file condition as error.
FS_ConfigPOSIXSupport() Enables / disables support for the POSIX-like behavior.
FS_ConfigWriteVerification() Enables / disables the verification of the written data.
FS_FileTimeToTimeStamp() Converts a broken-down date and time specification to a timestamp.
FS_FreeSectors() Informs the device driver about unused sectors.
FS_GetAutoMount() Returns information about how a volume is automatically mounted.
FS_GetFileId() Calculates a value that uniquely identifies a file.
FS_GetFileWriteMode() Returns the write mode.
FS_GetFileWriteModeEx() Returns the write mode configured for a specified volume.
FS_GetFSType() Returns the type of file system assigned to volume.
FS_GetMaxSectorSize() Queries the maximum configured logical sector size.
FS_GetMemInfo() Returns information about the memory management.
FS_GetMountType() Returns information about how a volume is mounted.
FS_GetNumFilesOpen() Queries the number of opened file handles.
FS_GetNumFilesOpenEx() Queries the number of opened file handles on a volume.
FS_GetNumVolumes() Queries the number of configured volumes.
FS_GetVolumeAlias() Returns the alternative name of a volume.
FS_GetVolumeFreeSpace() Returns the free space available on a volume.
FS_GetVolumeFreeSpaceFirst() Initiates the search for free space.
FS_GetVolumeFreeSpaceKB() Returns the free space available on a volume.
FS_GetVolumeFreeSpaceNext() Continues the search for free space.
FS_GetVolumeInfo() Returns information about a volume.
FS_GetVolumeInfoEx() Returns information about a volume.
FS_GetVolumeLabel() Returns the label of the volume.
FS_GetVolumeName() Returns the name of a volume.
FS_GetVolumeSize() Returns the size of a volume.
FS_GetVolumeSizeKB() Returns the size of a volume.
FS_GetVolumeStatus() Returns the presence status of a volume.
FS_IsVolumeMounted() Checks if a volume is mounted.
FS_Lock() Claims exclusive access to file system.
FS_LockVolume() Claims exclusive access to a volume.
FS_SetBusyLEDCallback() Registers a callback for busy status changes of a volume.
FS_SetCharSetType() Configures the character set that is used for the file and directory names.
FS_SetFSType() Sets the type of file system a volume.
FS_SetMemCheckCallback() Registers a callback for checking of 0-copy operations.
FS_SetTimeDateCallback() Configures a function that the file system can use to get the current time and date.
FS_SetVolumeAlias() Assigns an alternative name for a volume.
FS_SetVolumeLabel() Modifies the label of a volume.
FS_TimeStampToFileTime() Converts a timestamp to a broken-down date and time specification.
FS_Unlock() Releases the exclusive access to file system.
FS_UnlockVolume() Releases the exclusive access to a volume.
Storage layer functions
FS_STORAGE_Clean() Performs garbage collection on a volume.
FS_STORAGE_CleanOne() Performs garbage collection on a volume.
FS_STORAGE_DeInit() Frees the resources allocated by the storage layer.
FS_STORAGE_FillSectors() Writes the same sector data to one or more logical sectors.
FS_STORAGE_FillSectorsEx() Writes the same sector data to one or more logical sectors.
FS_STORAGE_FindVolume() Searches for a volume instance by name.
FS_STORAGE_FormatLowEx() Formats the storage device.
FS_STORAGE_FreeSectors() Informs the driver about unused sectors.
FS_STORAGE_GetCleanCnt() Calculates the number of garbage collection sub-operations.
FS_STORAGE_GetCounters() Returns the values of statistical counters.
FS_STORAGE_GetDeviceInfo() Returns information about the storage device.
FS_STORAGE_GetDeviceInfoEx() Returns information about the storage device.
FS_STORAGE_GetSectorUsage() Returns information about the usage of a logical sector.
FS_STORAGE_GetVolumeStatusEx() Returns the presence status of a volume.
FS_STORAGE_Init() Initializes the storage layer.
FS_STORAGE_IsLLFormattedEx() Checks if a storage device is low-level formatted.
FS_STORAGE_ReadSector() Reads the data of one logical sector.
FS_STORAGE_ReadSectorEx() Reads the contents of one logical sector from the storage device.
FS_STORAGE_ReadSectors() Reads the data of one or more logical sectors.
FS_STORAGE_ReadSectorsEx() Reads the contents of multiple logical sectors from a storage device.
FS_STORAGE_RefreshSectors() Reads the contents of a logical sector and writes it back.
FS_STORAGE_ResetCounters() Sets all statistical counters to 0.
FS_STORAGE_SetOnDeviceActivityCallback() Registers a function to be called on any logical sector read or write operation.
FS_STORAGE_Sync() Writes cached information to volume.
FS_STORAGE_SyncSectors() Synchronize the contents of one or more logical sectors.
FS_STORAGE_Unmount() Synchronizes a volume and marks it as not initialized.
FS_STORAGE_UnmountEx() Synchronizes the volume and marks it as not initialized.
FS_STORAGE_UnmountForced() Marks a volume it as not initialized.
FS_STORAGE_UnmountForcedEx() Marks the volume as not initialized without synchronizing it.
FS_STORAGE_WriteSector() Modifies the data of a logical sector.
FS_STORAGE_WriteSectorEx() Writes a logical sector to the storage device.
FS_STORAGE_WriteSectors() Modifies the data of one or more logical sectors.
FS_STORAGE_WriteSectorsEx() Writes multiple logical sectors to the storage device.
FAT related functions
FS_FAT_ConfigDirtyFlagUpdate() Enables / disables the update of the flag that indicates if the volume has been unmounted correctly.
FS_FAT_ConfigFATCopyMaintenance() Enables / disables the update of the second allocation table.
FS_FAT_ConfigFSInfoSectorUse() Enables / disables the usage of information from the FSInfo sector.
FS_FAT_ConfigROFileMovePermission() Enables / disables the permission to move (and rename) files and directories with the read-only file attribute set.
FS_FAT_DisableLFN() Disables the support for long file names.
FS_FAT_FormatSD() Formats the volume according to specification of SD Association.
FS_FAT_GetConfig() Returns information about how the FAT component is configured to operate.
FS_FAT_GetLFNConverter() Returns the type of configured file name converter.
FS_FAT_GrowRootDir() Increases the size of the root directory.
FS_FAT_SetLFNConverter() Configures how long file names are to be encoded and decoded.
FS_FAT_SupportLFN() Enables the support for long file names.
EFS related functions
FS_EFS_ConfigCaseSensitivity() Configures how the file names are compared.
FS_EFS_ConfigStatusSectorSupport() Enables or disables the usage of information from the status sector.
FS_EFS_GetConfig() Returns information about how the EFS component is configured to operate.
FS_EFS_SetFileNameConverter() Configures how file names are to be encoded.
Error-handling functions
FS_ClearErr() Clears error status of a file handle.
FS_ErrorNo2Text() Returns a human-readable text description of an API error code.
FS_FEof() Returns if end of file has been reached.
FS_FError() Return error status of a file handle.
Configuration checking functions
FS_CONF_GetDebugLevel() Returns the level of debug information configured for the file system.
FS_CONF_GetDirectoryDelimiter() Returns the character that is configured as delimiter between the directory names in a file path.
FS_CONF_GetMaxPath() Returns the configured maximum number of characters in a path to a file or directory.
FS_CONF_GetNumVolumes() Returns the maximum number of volumes configured for the file system.
FS_CONF_GetOSLocking() Returns the type of task locking configured for the file system.
FS_CONF_IsCacheSupported() Checks if the file system is configured to support the sector cache.
FS_CONF_IsDeInitSupported() Checks if the file system is configured to support deinitialization.
FS_CONF_IsEFSSupported() Checks if the file system is configured to support the EFS file system.
FS_CONF_IsEncryptionSupported() Checks if the file system is configured to support encryption.
FS_CONF_IsFATSupported() Checks if the file system is configured to support the FAT file system.
FS_CONF_IsFreeSectorSupported() Checks if the file system is configured to support the “free sector” command.
FS_CONF_IsJournalSupported() Checks if the file system is configured to support journaling.
FS_CONF_IsTrialVersion() Checks if the file system has been configured as a trial (limited) version.
FS_GetVersion() Returns the version number of the file system.
Obsolete functions
FS_AddOnExitHandler() Registers a deinitialization callback.
FS_CloseDir() Closes a directory.
FS_ConfigOnWriteDirUpdate() Configures if the directory entry has be updated after writing to file.
FS_DirEnt2Attr() Loads attributes of a directory entry.
FS_DirEnt2Name() Loads the name of a directory entry.
FS_DirEnt2Size() Loads the size of a directory entry.
FS_DirEnt2Time() Loads the time stamp of a directory entry.
FS_GetNumFiles() API function.
FS_OpenDir() API function.
FS_ReadDir() Reads next directory entry in directory.
FS_RewindDir() Sets pointer for reading the next directory entry to the first entry in the directory.

File system control functions

FS_Init()

Description

Starts the file system.

Prototype

void FS_Init(void);

Additional information

FS_Init() initializes the file system and creates resources required for the access of the storage device in a multi-tasking environment. This function has to be called before any other file system API function.

Example

#include "FS.h"

void SampleInit(void) {
  FS_Init();
  //
  // Access file system
  //
}

FS_DeInit()

Description

Frees allocated resources.

Prototype

void FS_DeInit(void);

Additional information

This function is optional. FS_DeInit() frees all resources that are allocated by the file system after initialization. Also, all static variables of all file system layers are reset in order to guarantee that the file system remains in a known state after deinitialization.The application can call this function only after it called FS_Init().

This function has to be used when the file system is reset at runtime. For example this is the case if the system uses a software reboot which reinitializes the target application.

This function is available if the emFile sources are compiled with the FS_SUPPORT_DEINIT configuration define set to 1.

Example

#include "FS.h"

void SampleDeInit(void) {
  FS_Init();
  //
  // Access the file system...
  //
  FS_DeInit();
  //
  // The file system cannot be accessed anymore.
  //
}

FS_Mount()

Description

Initializes a volume in default access mode.

Prototype

int FS_Mount(const char * sVolumeName);

Parameters

Parameter Description
sVolumeName The name of a volume. If the empty string is specified, the first device in the volume table is used.

Return value

= 0 Volume is not mounted.
= FS_MOUNT_RO Volume is mounted read only.
= FS_MOUNT_RW Volume is mounted read/write.
< 0 Error code indicating the failure reason. Refer to FS_ErrorNo2Text().

Additional information

The storage device has to be mounted before being accessed for the first time after file system initialization. The file system is configured by default to automatically mount the storage device at the first access in read / write mode. This function can be used to explicitly mount the storage device if the automatic mount behavior has been disabled via FS_SetAutoMount(). Refer to FS_SetAutoMount() for an overview of the different automatic mount types.

Example

#include "FS.h"

void SampleMount(void) {
  FS_Init();
  //
  // Mount default volume in read / write mode.
  //
  FS_Mount("");
  //
  // Access the data stored on the file system.
  //
}

FS_MountEx()

Description

Initializes a volume in a specified access mode.

Prototype

int FS_MountEx(const char * sVolumeName,
                     U8     MountType);

Parameters

Parameter Description
sVolumeName The name of the volume. If the empty string is specified, the first device in the volume table is used.
MountType Indicates how the volume has to be mounted. FS_MOUNT_RO Read only access. FS_MOUNT_RW Read / write access.

Return value

= 0 Volume is not mounted.
= FS_MOUNT_RO Volume is mounted read only.
= FS_MOUNT_RW Volume is mounted read/write.
< 0 Error code indicating the failure reason. Refer to FS_ErrorNo2Text().

Additional information

Performs the same operation as FS_Mount() while it allows the application to specify how the storage device has to be mounted.

Example

#include "FS.h"

void SampleMountEx(void) {
  FS_Init();
  //
  // Mount default volume in read-only mode.
  //
  FS_MountEx("", FS_MOUNT_RO);
  //
  // Access the data stored on the file system.
  //
}

FS_SetAutoMount()

Description

Sets the automatic mount behavior.

Prototype

void FS_SetAutoMount(const char * sVolumeName,
                           U8     MountType);

Parameters

Parameter Description
sVolumeName Pointer to a string containing the name of the volume. If the empty string is specified, the first device in the volume table is used.
MountType Indicates how the volume has to be mounted. FS_MOUNT_RO Allows to automatically mount the volume in read only mode. FS_MOUNT_RW Allows to automatically mount the volume in read / write mode. 0 Disables the automatic mount operation for the volume.

Additional information

By default, the file system is configured to automatically mount all volumes in read / write mode and this function can be used to change the default automatic mount type or to disable the automatic mounting.

Example

#include "FS.h"

void SampleSetAutoMount(void) {
  FS_SetAutoMount("", FS_MOUNT_R);    // Mount default volume in read-only mode.
}

FS_Sync()

Description

Saves cached information to storage.

Prototype

int FS_Sync(const char * sVolumeName);

Parameters

Parameter Description
sVolumeName Pointer to a string containing the name of the volume to be synchronized. If the empty string is specified, the first configured volume is used.

Return value

= 0 OK, volume synchronized
≠ 0 Error code indicating the failure reason. Refer to FS_ErrorNo2Text() for more information.

Additional information

The function write the contents of write buffers and updates the management information of all opened file handles to storage device. All the file handles are left open. If configured, FS_Sync() also writes to storage the changes present in the write cache and in the journal. FS_Sync() can be called from the same task as the one writing data or from a different task.

Example

#include "FS.h"

void SampleSync(void) {
  FS_Sync("");      // Synchronize the default volume.
}

FS_Unmount()

Description

Synchronizes the data and marks the volume as not initialized.

Prototype

void FS_Unmount(const char * sVolumeName);

Parameters

Parameter Description
sVolumeName Pointer to a string containing the name of the volume to be unmounted. If the empty string is specified, the first device in the volume table is used. Can not be NULL.

Additional information

This function closes all open files and synchronizes the volume, that is writes all cached data to storage device. FS_Unmount() hast to be called before a storage device is removed to make sure that all the information cached by the file system is updated to storage device. This function is also useful when shutting down a system.

The volume is initialized again at the next call to any other file system API function that requires access to storage device. The application can also explicitly initialize the volume via FS_Mount() or FS_MountEx().

Example

#include "FS.h"

void SampleUnmount(void) {
  FS_Unmount("");     // Unmount the default volume.
}

FS_UnmountForced()

Description

Marks the volume as not initialized.

Prototype

void FS_UnmountForced(const char * sVolumeName);

Parameters

Parameter Description
sVolumeName Pointer to a string containing the name of the volume to be unmounted. If the empty string is specified, the first device in the volume table is used.

Additional information

This function performs the same operations as FS_Unmount(). FS_UnmountForced() has to be called if a storage device has been removed before it could be regularly unmounted. When using FS_UnmountForced() there is no guarantee that the information cached by the file system is updated to storage.

The volume is initialized again at the next call to any other file system API function that requires access to storage device. The application can also explicitly initialize the volume via FS_Mount() or FS_MountEx().

Opened file handles are only marked as invalid but they are not closed. The application has to close them explicitly by calling FS_FClose().

Example

#include "FS.h"
#include "FS_OS.h"

void SampleUnmountForced(void) {
  int IsPresentNew;
  int IsPresent;

  IsPresent = FS_GetVolumeStatus("");
  while (1) {
    IsPresentNew = FS_GetVolumeStatus("");
    //
    // Check if the presence status of the storage device has been changed.
    //
    if (IsPresentNew != IsPresent) {
      if (IsPresentNew == FS_MEDIA_IS_PRESENT) {
        FS_Mount("");
      } else  {
        FS_UnmountForced("");
      }
      IsPresent = IsPresentNew;
    }
    FS_X_OS_Delay(500);
  }
}

Volume mounting modes

Description

Modes for mounting a volume.

Definition

#define FS_MOUNT_RO    FS_MOUNT_R
#define FS_MOUNT_RW    (FS_MOUNT_R | FS_MOUNT_W)

Symbols

Definition Description
FS_MOUNT_RO Read-only. Data can only be read from storage device.
FS_MOUNT_RW Read / Write. Data can be read form and written to storage device.

File system configuration functions

The file system control functions listed in this section can only be used in the runtime configuration phase. This means in practice that they can only be called from within FS_X_AddDevices().

FS_AddDevice()

Description

Adds a driver to file system.

Prototype

FS_VOLUME *FS_AddDevice(const FS_DEVICE_TYPE * pDevType);

Parameters

Parameter Description
pDevType  in  Pointer to a function table identifying the driver that has to be added.

Return value

≠ 0 OK, driver added.
= 0 An error occurred.

Additional information

This function can be used to add a device or a logical driver to file system. The application has to add at least one driver to file system.

The function performs the following operations:

Example

#include "FS.h"

void FS_X_AddDevices(void) {
  //
  // Basic configuration of the file system...
  //

  //
  // Add and configure a device driver for NAND flash.
  //
  FS_AddDevice(&FS_NAND_UNI_Driver);

  //
  // Additional configuration of the file system...
  //
}

FS_AddPhysDevice()

Description

Adds a device to file system without assigning a volume to it.

Prototype

int FS_AddPhysDevice(const FS_DEVICE_TYPE * pDevType);

Parameters

Parameter Description
pDevType  in  Pointer to a function table identifying the driver that has to be added.

Return value

= 0 OK, storage device added.
≠ 0 An error occurred.

Additional information

This function can be used to add a device or a logical driver to file system. It works similarly to FS_AddDevice() with the difference that it does not assign a logical volume to storage device. This means that the storage device is not directly accessible by the application via the API functions of the file system. An additional logical driver is required to be added via FS_AddDevice() to make the storage device visible to application.

FS_AddPhysDevice() initializes the driver, allowing the driver to identify the storage device as far as required and allocate memory required for driver level management of the device. This makes sector operations possible.

FS_AssignMemory()

Description

Assigns a memory pool to the file system.

Prototype

void FS_AssignMemory(U32 * pData,
                     U32   NumBytes);

Parameters

Parameter Description
pData  in  A pointer to the start of the memory region assigned to file system.
NumBytes Size of the memory pool assigned.

Additional information

emFile comes with a simple semi-dynamic internal memory manager that is used to satisfy the runtime memory requirements of the file system. FS_AssignMemory() can be used to provide a memory pool to the internal memory manager of the file system. If not enough memory is assigned, the file system calls FS_X_Panic() in debug builds which by default halts the execution of the application. The actual number of bytes allocated is stored in the global variable FS_Global.MemManager.NumBytesAllocated. This variable can be used to fine-tune the size of the memory pool.

emFile supports also the use of an external memory manager (e.g. via malloc() and free() functions of the standard C library). The selection between the internal and the external memory management has to be done at compile time via the FS_SUPPORT_EXT_MEM_MANAGER define. The configuration of the memory management functions is done via FS_SetMemHandler().

This function has to be called in the initialization phase of the file system; typically in FS_X_AddDevices(). The support for internal memory management has to be enabled at compile time by setting the FS_SUPPORT_EXT_MEM_MANAGER define to 0. FS_AssignMemory() does nothing if the FS_SUPPORT_EXT_MEM_MANAGER define is set to 1.

Example

#include "FS.h"

#define ALLOC_SIZE    0x1000

static U32 _aMemBlock[ALLOC_SIZE / 4];

void FS_X_AddDevices(void) {
  FS_AssignMemory(_aMemBlock, sizeof(_aMemBlock));
  //
  // Perform additional file system configuration.
  //
}

FS_ConfigFileBufferDefault()

Description

Configures the size and flags for the file buffer.

Prototype

int FS_ConfigFileBufferDefault(int BufferSize,
                               int Flags);

Parameters

Parameter Description
BufferSize Size of the file buffer in bytes.
Flags File buffer operating mode. 0 Read file buffer. FS_FILE_BUFFER_WRITE Read / write file buffer. FS_FILE_BUFFER_ALIGNED Logical sector boundary alignment.

Return value

= 0 OK, the file buffer has been configured.
≠ 0 Error code indicating the failure reason.

Additional information

The function has to be called only once, in FS_X_AddDevices(). If called after FS_Init() the function does nothing and generates a warning.

The file system allocates a file buffer of BufferSize bytes for each file the application opens. The operating mode of the file buffer can be changed at runtime via FS_SetFileBufferFlags(). If file buffers of different sizes are required FS_SetFileBuffer() should be used instead.

For best performance it is recommended to set the size of the file buffer to be equal to the size of the logical sector. Smaller file buffer sizes can also be used to reduce the RAM usage.

FS_SetFileBuffer() is available if the emFile sources are compiled with the FS_SUPPORT_FILE_BUFFER configuration define set to 1.

Example

#include "FS.h"

#define ALLOC_SIZE    0x1000

static U32 _aMemBlock[ALLOC_SIZE / 4];

void FS_X_AddDevices(void) {
  FS_AssignMemory(_aMemBlock, sizeof(_aMemBlock));
  //
  // Set the file buffer of 512 bytes for read and write operations.
  // The file buffer is allocated at runtime for each opened file
  // from _aMemBlock.
  //
#if (FS_USE_FILE_BUFFER || FS_SUPPORT_FILE_BUFFER)
  FS_ConfigFileBufferDefault(512, FS_FILE_BUFFER_WRITE);
#endif
}

FS_LOGVOL_Create()

Description

Creates a driver instance.

Prototype

int FS_LOGVOL_Create(const char * sVolumeName);

Parameters

Parameter Description
sVolumeName Name of the volume to create.

Return value

= 0 OK, volume has been created.
≠ 0 An error occurred.

Additional information

This function creates an instance of a logical volume. A logical volume is the representation of one or more physical devices as a single device. It allows treating multiple physical devices as one larger device. The file system takes care of selecting the correct location on the correct physical device when reading from or writing to the logical volume. Logical volumes are typically used if multiple flash devices (NOR or NAND) are present, but they should be presented to the application in the same way as a single device with the combined capacity of both.

sVolumeName is the name that has to be assigned to the logical volume. This is the volume name that is passed to some of the FS API functions and that has to be used in a file path.

FS_LOGVOL_Create() does nothing if the module is configured to work in driver mode by setting the FS_LOGVOL_SUPPORT_DRIVER_MODE define option to 1. In this case a logical driver is created by adding it via FS_AddDevice() to file system.

Normally, all devices are added individually using FS_AddDevice(). This function adds the devices physically as well as logically to the file system. In contrast to adding all devices individually, all devices can be combined in a logical volume with a total size of all combined devices. To create a logical volume the following steps have to be performed: 1. The storage device has to be physically added to the file system using FS_AddPhysDevice(). 2. A logical volume has to be created using FS_LOGVOL_Create(). 3. The devices which are physically added to the file system have to be added to the logical volume using FS_LOGVOL_AddDevice().

FS_LOGVOL_AddDevice()

Description

Adds a storage device to a logical volume.

Prototype

int FS_LOGVOL_AddDevice(const char           * sVolumeName,
                        const FS_DEVICE_TYPE * pDeviceType,
                              U8               DeviceUnit,
                              U32              StartSector,
                              U32              NumSectors);

Parameters

Parameter Description
sVolumeName Name of the logical volume.
pDeviceType Type of the storage device that has to be added.
DeviceUnit Index of the storage device that has to be added (0-based).
StartSector Index of the first sector that has to be used as storage (0-based).
NumSectors Number of sectors that have to be used as storage.

Return value

= 0 OK, storage device added.
≠ 0 An error occurred.

Additional information

Only devices with an identical sector size can be combined to a logical volume. All additionally added devices need to have the same sector size as the first physical device of the logical volume.

This function does nothing if FS_LOGVOL_SUPPORT_DRIVER_MODE is set to 1.

FS_SetFileBufferFlags()

Description

Changes the operating mode of the file buffer.

Prototype

int FS_SetFileBufferFlags(FS_FILE * pFile,
                          int       Flags);

Parameters

Parameter Description
pFile Handle to opened file.
Flags File buffer operating mode. 0 Read file buffer. FS_FILE_BUFFER_WRITE Read / write file buffer. FS_FILE_BUFFER_ALIGNED Logical sector boundary alignment.

Return value

= 0 OK, file buffer flags changed.
≠ 0 Error code indicating the failure reason.

Additional information

This function can only be called immediately after FS_FOpen(), to change the operating mode of the file buffer (read or read / write).

FS_SetFileBufferFlags() is available if the emFile sources are compiled with the FS_SUPPORT_FILE_BUFFER configuration define set to 1.

Example

#include "FS.h"

void SampleSetFileBufferFlags(void) {
  FS_FILE * pFile;
  U8        abData[16];

  pFile = FS_FOpen("Test.txt", "w");
  if (pFile != NULL) {
    memset(abData, 'a', sizeof(abData));
    FS_SetFileBufferFlags(pFile, FS_FILE_BUFFER_WRITE);
    FS_Write(pFile, abData, sizeof(abData));
    FS_FClose(pFile);
  }
}

FS_SetFileBufferFlagsEx()

Description

Changes the operating mode of the file buffer.

Prototype

int FS_SetFileBufferFlagsEx(const char * sVolumeName,
                                  int    Flags);

Parameters

Parameter Description
sVolumeName Name of the volume for which to set the flags.
Flags File buffer operating mode. 0 Read file buffer. FS_FILE_BUFFER_WRITE Read / write file buffer. FS_FILE_BUFFER_ALIGNED Logical sector boundary alignment.

Return value

= 0 OK, operating mode changed.
≠ 0 Error code indicating the failure reason.

Additional information

This function can be used to change the operating mode of the file buffer for the files that are located on a specific volume.

FS_SetFileBufferFlagsEx() is available if the emFile sources are compiled with the FS_SUPPORT_FILE_BUFFER configuration define set to 1.

FS_SetFileWriteMode()

Description

Configures the file write mode.

Prototype

void FS_SetFileWriteMode(FS_WRITEMODE WriteMode);

Parameters

Parameter Description
WriteMode Specifies how to write to file: FS_WRITEMODE_SAFE Updates the allocation table and the directory entry at each write to file operation. FS_WRITEMODE_MEDIUM Updates the allocation table at each write to file operation. FS_WRITEMODE_FAST The allocation table and directory entry are updated when the file is closed.

Additional information

This function can be called to configure which mode the file system has to use when writing to a file. The file system uses by default FS_WRITEMODE_SAFE which allows the maximum fail-safe behavior, since the allocation table and the directory entry is updated on every write operation to file.

If FS_WRITEMODE_FAST is set, the update of the allocation table is performed using a special algorithm. When writing to the file for the first time, the file system checks how many clusters in series are empty starting with the first one occupied by the file. This cluster chain is remembered, so that if the file grows and needs an additional cluster, the allocation doesn’t have to be read again in order to find the next free cluster. The allocation table is only modified if necessary, which is the case when:

Especially when writing large amounts of data, FS_WRITEMODE_FAST allows maximum performance, since usually the file system has to search for a free cluster in the allocation table and link it with the last one occupied by the file. In worst case, multiple sectors of the allocation table have to be read in order to find a free cluster.

Example

#include "FS.h"

void FS_X_AddDevices(void) {
  //
  // Configure the file system to write as fast as possible
  // to all files on all volumes.
  //
  FS_SetFileWriteMode(FS_WRITEMODE_FAST);
  //
  // Perform other file system configuration...
  //
}

FS_SetFileWriteModeEx()

Description

Configures the write mode of a specified volume.

Prototype

int FS_SetFileWriteModeEx(      FS_WRITEMODE   WriteMode,
                          const char         * sVolumeName);

Parameters

Parameter Description
WriteMode Specifies how to write to file: FS_WRITEMODE_SAFE Updates the allocation table and the directory entry at each write to file operation. FS_WRITEMODE_MEDIUM Updates the allocation table at each write to file operation. FS_WRITEMODE_FAST The allocation table and directory entry are updated when the file is closed.
sVolumeName Identifies the volume for which the write mode has to be changed.

Return value

= 0 OK, write mode set.
≠ 0 Error code inidicating the failure reason.

Additional information

When not explicitly set using this function the write mode of a volume is the write mode set via FS_SetFileWriteMode() or the default write mode (FS_WRITEMODE_SAFE). FS_SetFileWriteModeEx() is typically on file system configurations using multiple volumes that require different write modes. For example on a file system configured to use two volumes where one volume has to be configured for maximum write performance (FS_WRITEMODE_FAST) while on the other volume the write operation has to be fail-safe (FS_WRITEMODE_SAFE).

Refer to FS_SetFileWriteMode() for detailed information about the different write modes.

Example

#include "FS.h"

void FS_X_AddDevices(void) {
  //
  // Configure the file system to write as fast as possible
  // to all files on the "nand:0:" volume.
  //
  FS_SetFileWriteModeEx(FS_WRITEMODE_FAST, "nand:0");
  //
  // Perform other file system configuration...
  //
}

FS_SetMemHandler()

Description

Configures functions for memory management.

Prototype

void FS_SetMemHandler(FS_MEM_ALLOC_CALLBACK * pfAlloc,
                      FS_MEM_FREE_CALLBACK  * pfFree);

Parameters

Parameter Description
pfAlloc Pointer to a function that allocates memory (e.g. malloc()). It cannot be NULL.
pfFree Pointer to a function that frees memory (e.g. free()). It cannot be NULL.

Additional information

The application can use this function to configure functions for the memory management. The file system calls pfAlloc to allocate memory and pfFree to release the allocated memory.

This function has to be called in the initialization phase of the file system; typically in FS_X_AddDevices(). The support for external memory management has to be enabled at compile time by setting the FS_SUPPORT_EXT_MEM_MANAGER define to 1. FS_SetMemHandler() does nothing if FS_SUPPORT_EXT_MEM_MANAGER is set to 0 (default).

Example

#include <stdlib.h>
#include "FS.h"

void FS_X_AddDevices(void) {
#if FS_SUPPORT_EXT_MEM_MANAGER
  //
  // Configure functions for dynamic memory allocation.
  //
  FS_SetMemHandler((FS_MEM_ALLOC_CALLBACK *)malloc, free);
#endif // FS_SUPPORT_EXT_MEM_MANAGER
  //
  // Configure the file system...
  //
}

FS_SetMaxSectorSize()

Description

Configures the maximum size of a logical sector.

Prototype

int FS_SetMaxSectorSize(unsigned MaxSectorSize);

Parameters

Parameter Description
MaxSectorSize Number of bytes in the logical sector.

Return value

= 0 OK, the sector size had been set.
≠ 0 Error code indicating the failure reason.

Additional information

The file system uses internal RAM buffers to store the data of logical sectors it accesses. The storage devices added to file system can have different logical sector sizes. Since the size of the logical sectors is not known at the time the internal RAM buffers are allocated the application has to call FS_SetMaxSectorSize() to specify the size of the largest logical sector used by the configured drivers.

The default value for the maximum size of a logical sector is 512 bytes. The size of the logical sector supported by a driver can be found in the section that describes the specific driver.

FS_SetMaxSectorSize() can be called only at file system initialization in FS_X_AddDevices().

Example

#include "FS.h"

void FS_X_AddDevices(void) {
  //
  // This function call is typically required when
  // a NAND flash with 2048 byte pages is used as
  // storage device.
  //
  FS_SetMaxSectorSize(2048);
}

FS_MEM_ALLOC_CALLBACK

Description

Type of function called by the file system to allocate memory dynamically.

Type definition

typedef void * FS_MEM_ALLOC_CALLBACK(U32 NumBytes);

Parameters

Parameter Description
NumBytes Number of bytes to be allocated.

Return value

NULL OK, pointer to the allocated memory block.
= NULL Error, could not allocate memory.

Additional information

The callback function has the same signature as the malloc() standard C function. The application can register the callback function via FS_SetMemHandler().

FS_MEM_FREE_CALLBACK

Description

Type of function called by the file system to release dynamically allocated memory.

Type definition

typedef void FS_MEM_FREE_CALLBACK(void * pData);

Parameters

Parameter Description
pData Memory block to be released.

Additional information

The callback function has the same signature as the free() standard C function. The application can register the callback function via FS_SetMemHandler(). pMem points to a memory block that was allocated using a call to pfAlloc callback function registered via FS_SetMemHandler().

FS_WRITEMODE

Description

Modes of writing to file.

Type definition

typedef enum {
  FS_WRITEMODE_SAFE,
  FS_WRITEMODE_MEDIUM,
  FS_WRITEMODE_FAST,
  FS_WRITEMODE_UNKNOWN
} FS_WRITEMODE;

Enumeration constants

Constant Description
FS_WRITEMODE_SAFE Allows maximum fail-safe behavior. The allocation table and the directory entry are updated after each write access to file. This write mode provides the slowest performance.
FS_WRITEMODE_MEDIUM Medium fail-safe. The allocation table is updated after each write access to file. The directory entry is updated only if file is synchronized that is when FS_Sync(), FS_FClose(), or FS_SyncFile() is called.
FS_WRITEMODE_FAST This write mode provided the maximum performance. The directory entry is updated only if the file is synchronized that is when FS_Sync(), FS_FClose(), or FS_SyncFile() is called. The allocation table is modified only if necessary.
FS_WRITEMODE_UNKNOWN End of enumeration (for internal use only)

File access functions

The functions in this section can be used to access the data stored in a file.

FS_FClose()

Description

Closes an opened file.

Prototype

int FS_FClose(FS_FILE * pFile);

Parameters

Parameter Description
pFile Handle to the file to be closed.

Return value

= 0 OK, file handle has been successfully closed.
≠ 0 Error code indicating the failure reason. Refer to FS_ErrorNo2Text().

Example

#include "FS.h"

void SampleFClose(void) {
  FS_FILE * pFile;

  pFile = FS_FOpen("Test.txt", "r");
  if (pFile) {
    //
    // Access file.
    //
    FS_FClose(pFile);
  }
}

FS_FGets()

Description

Reads a line of text from file.

Prototype

char *FS_FGets(char    * sData,
               int       SizeOfData,
               FS_FILE * pFile);

Parameters

Parameter Description
sData  out  Buffer that receives the data read from file. It cannot be NULL.
SizeOfData Number of bytes in sData. It cannot be 0.
pFile Handle to opened file. It cannot be NULL.

Return value

NULL OK, data read successfully. The returned value is sData buffer.
= NULL An error occurred.

Additional information

This function starts reading from the current position in the file and advances the current file position by the number of bytes read.

FS_FGets() returns when either a line terminator is read from file and stored to sData, SizeOfData - 1 bytes are stored to sData or the end of file is reached. The data stored to sData is 0-terminated.

A line terminator can be either a single Line Feed character (0x0A), a single Carriage Return character (0x0D) or a Carriage Return and Line Feed character sequence (0x0D 0x0A).

The file to read from has to be opened with read permissions. For more information about open modes refer to FS_FOpen().

The application can check for the actual error using FS_FError().

Example

#include "FS.h"

void SampleFGets(void) {
  FS_FILE * pFile;
  char      ac[128];
  char    * s;

  pFile = FS_FOpen("Test.txt", "r");
  if (pFile != NULL) {
    for (;;) {
      s = FS_FGets(ac, sizeof(ac), pFile);
      if (s == NULL) {
        break;
      }
    }
    FS_FClose(pFile);
  }
}

FS_FOpen()

Description

Opens an existing file or creates a new one.

Prototype

FS_FILE *FS_FOpen(const char * sFileName,
                  const char * sMode);

Parameters

Parameter Description
sFileName Name of the file to be opened or created. It is a 0-terminated string that cannot be NULL.
sMode Indicates how the file should be opened. It is a 0-terminated string that cannot be NULL.

Return value

≠ 0 OK, pointer to a file handle that identifies the opened file.
= 0 Error, unable to open the file.

Additional information

The sMode parameter can take one of the following values:

sMode Description
“r” or “rb” Open files for reading.
“w” or “wb” Truncates to zero length or creates file for writing.
“a” or “ab” Appends; opens / creates file for writing at end of file.
“r+”, “r+b” or “rb+” Opens file for update (reading and writing).
“w+”, “w+b” or “wb+” Truncates to zero length or creates file for update.
“a+”, “a+b” or “ab+” Appends; opens / creates file for update, writing at end of file.

For more details about FS_FOpen(), refer to the ANSI C documentation of the fopen() function.

The file system does not distinguish between binary and text mode; the files are always accessed in binary mode.

In order to use long file names with FAT, the FS_FAT_SupportLFN() has to be called before after the file system is initialized.

FS_FOpen() accepts file names encoded in UTF-8 format. This feature is disabled by default. To enable it the file system has to be compiled with the FS_FAT_SUPPORT_UTF8 configuration define to 1. Additionally, the support for long file names has to be enabled for volumes formatted as FAT.

Example

#include "FS.h"

void SampleOpenFile(void) {
  FS_FILE * pFile;

  //
  // Opens for reading a file on the default volume.
  //
  pFile = FS_FOpen("Test.txt", "r");
  //
  // Opens for writing a file on the default volume.
  //
  pFile = FS_FOpen("Test.txt", "w");
  //
  // Opens for reading a file in folder "SubDir" on the default volume.
  // The directory delimiter is the '\' character.
  //
  pFile = FS_FOpen("\\SubDir\\Test.txt", "r");
  //
  // Opens for reading a file on the first RAM disk volume.
  //
  pFile = FS_FOpen("ram:Test.txt", "r");
  //
  // Opens for reading a file on the second RAM disk volume.
  //
  pFile = FS_FOpen("ram:1:Test.txt", "r");
  //
  // Opens for writing a file with a long name for writing.
  //
  FS_FAT_SupportLFN();
  pFile = FS_FOpen("Long file name.text", "w");
  //
  // Opens for writing a file with a name encoded in UTF-8 format.
  // The file system has to be compiled with FS_FAT_SUPPORT_UTF8 define
  // set to 1. The name contains the following characters:
  //   small a, umlaut mark
  //   small o, umlaut mark
  //   small sharp s
  //   small u, umlaut mark
  //   '.'
  //   't'
  //   'x'
  //   't'
  //
  FS_FAT_SupportLFN();
  pFile = FS_FOpen("\xC3\xA4\xC3\xB6\xC3\x9F\xC3\xBC.txt", "w");
}

FS_FOpenEx()

Description

Opens an existing file or creates a new one.

Prototype

int FS_FOpenEx(const char     * sFileName,
               const char     * sMode,
                     FS_FILE ** ppFile);

Parameters

Parameter Description
sFileName Name of the file to be opened or created. It is a 0-terminated string that cannot be NULL.
sMode Indicates how the file should be opened. It is a 0-terminated string that cannot be NULL.
ppFile Pointer to a file handle pointer that receives the opened file handle.

Return value

= 0 OK, file opened.
≠ 0 Error code indicating the failure reason.

Additional information

For additional information about the sMode parameter refer to FS_FOpen().

Example

#include <stdio.h>
#include "FS.h"

FS_FILE * pFile;

/*********************************************************************
*
*       SampleFOpenEx
*
*  Function description
*    Opens for reading a file on the default volume.
*/
void SampleFOpenEx(void) {
  int  r;
  char ac[100];

  r = FS_FOpenEx("Test.txt", "r", &pFile);
  if (r) {
    SEGGER_snprintf(ac, sizeof(ac), "Could not open file (Reason: %s)\n", 
      FS_ErrorNo2Text(r));
    FS_X_Log(ac);
  }
}

FS_FPrintf()

Description

Writes a formatted string to a file.

Prototype

int FS_FPrintf(      FS_FILE * pFile,
               const char    * sFormat,
                               ...);

Parameters

Parameter Description
pFile Opened file handle. It cannot be NULL.
sFormat Format of the data to be written (0-terminated string). It cannot be NULL.

Return value

≥ 0 OK, number of bytes written to file.
< 0 Error code indicating the failure reason.

Additional information

This function works in the same way as the fprintf() standard C library function. It formats the data according to sFormat and then writes the formatted string to pFile. The format specification is identical to that of fprintf(). FS_FPrintf() relies on SEGGER_vsnprintfEx() to perform the actual formatting.

The file position is advanced by the number of bytes written.

FS_FPrintf() uses a buffer allocated on the stack for the formatting of the data. The size of this buffer can be configured via FS_BUFFER_SIZE_FILE_PRINT and it has to be at least 1 byte large.

Example

#include "FS.h"

void SampleFPrintf(void) {
  FS_FILE * pFile;
  int       i;

  pFile = FS_FOpen("Test.txt", "w");
  if (pFile != NULL) {
    for (i = 0; i < 10; ++i) {
      FS_FPrintf(pFile, "Counter value: %d\n", i);
    }
    FS_FClose(pFile);
  }
}

FS_FPuts()

Description

Writes a 0-terminated string to a file.

Prototype

int FS_FPuts(const char    * sData,
                   FS_FILE * pFile);

Parameters

Parameter Description
sData Data to be written (0-terminated string). It cannot be NULL.
pFile Opened file handle. It cannot be NULL.

Return value

= 0 OK, data written successfully.
≠ 0 Error code indicating the failure reason.

Additional information

This function works in the same way as the fputs() standard C library function. It writes the 0-terminated string sData to the file pFile. The 0-terminator is not written to file. The file position is advanced by the number of bytes written.

Example

#include "FS.h"

const char acText[] = "Hello world\n";

void SampleFPuts(void) {
  FS_FILE * pFile;

  pFile = FS_FOpen("Test.txt", "w");
  if (pFile != NULL) {
    FS_FPuts(acText, pFile);
    FS_FClose(pFile);
  }
}

FS_FRead()

Description

Reads data from file.

Prototype

U32 FS_FRead(void    * pData,
             U32       ItemSize,
             U32       NumItems,
             FS_FILE * pFile);

Parameters

Parameter Description
pData Buffer that receives the data read from file.
ItemSize Size of one item to be read from file (in bytes).
NumItems Number of items to be read from the file.
pFile Handle to opened file. It cannot be NULL.

Return value

Number of items read.

Additional information

The file has to be opened with read permissions. For more information about open modes refer to FS_FOpen().

The application has to check for possible errors using FS_FError() if the number of items actually read is different than the number of items requested to be read by the application.

The data is read from the current position in the file that is indicated by the file pointer. FS_FRead() moves the file pointer forward by the number of bytes successfully read.

Example

#include "FS.h"

char acBuffer[100];

void SampleFRead(void) {
  FS_FILE * pFile;
  U32       NumItems;
  int       ErrCode;

  pFile = FS_FOpen("Test.txt", "r");
  if (pFile) {
    NumItems = FS_FRead(acBuffer, 1, sizeof(acBuffer), pFile);
    if (NumItems != sizeof(acBuffer)) {
      ErrCode = FS_FError(pFile);
      if (ErrCode) {
        //
        // An error occurred during the read operation.
        //
      }
    }
    FS_FClose(pFile);
  }
}

FS_FSeek()

Description

Sets the current position in file.

Prototype

int FS_FSeek(FS_FILE     * pFile,
             FS_FILE_OFF   Offset,
             int           Origin);

Parameters

Parameter Description
pFile Handle to opened file.
Offset Byte offset for setting the file pointer position.
Origin Indicates how the file pointer has to be moved.

Return value

= 0 OK, file pointer has been positioned according to the specified parameters.
≠ 0 Error code indicating the failure reason.

Additional information

FS_FSeek() moves the file pointer to a new location by a number of bytes relative to the position specified by the Origin parameter. The Origin parameter can take the values specified by the FS_SEEK_… defines

The file pointer can be repositioned anywhere in the file. It is also possible to reposition the file pointer beyond the end of the file. This feature is used together with FS_SetEndOfFile() to reserve space for a file (preallocate the file).

Alternative name

FS_SetFilePos

Example

#include "FS.h"

const char acText[]="Some text will be overwritten";

void SampleFTell(void) {
  FS_FILE * pFile;

  pFile = FS_FOpen("Test.txt", "w");
  if (pFile) {
    //
    // Write the data to file.
    //
    FS_FWrite(acText, 1, strlen(acText), pFile);
    //
    // Move the file pointer back 4 bytes from the current
    // position in file. The data stored in the file looks
    // like this: "Some text will be overwritten"
    //
    FS_FSeek(pFile, -4, FS_SEEK_CUR);
    //
    // The write operation overwrites the last
    // 4 characters that is "tten" of the data
    // written in the previous call to FS_FWrite().
    //
    FS_FWrite(acText, 1, strlen(acText), pFile);
    //
    // The data in the file looks now like this:
    // "Some text will be overwriSome text will be overwritten"
    //
    FS_FClose(pFile);
  }
}

FS_FWrite()

Description

Writes data to file.

Prototype

U32 FS_FWrite(const void    * pData,
                    U32       ItemSize,
                    U32       NumItems,
                    FS_FILE * pFile);

Parameters

Parameter Description
pData Data to be written to file.
ItemSize Size of an item to be written to file (in bytes).
NumItems Number of items to be written to file.
pFile Handle to opened file. It cannot be NULL.

Return value

Number of elements written.

Additional information

The file has to be opened with write permissions. For more information about open modes refer to FS_FOpen().

The application has to check for possible errors using FS_FError() if the number of items actually written is different than the number of items requested to be written by the application.

The data is written at the current position in the file that is indicated by the file pointer. FS_FWrite() moves the file pointer forward by the number of bytes successfully written.

Example

#include "FS.h"

const char acText[] = "Hello world\n";

void SampleFWrite(void) {
  FS_FILE * pFile;

  pFile = FS_FOpen