Introduction
Files and directories are common abstractions, which we encounter daily when sending an e-mail attachment, downloading a new application or archiving old information. Those same abstractions may be leveraged in an embedded system for similar tasks or for unique ones. A device may serve web pages, play or record media (images, video or music) or log data. The file system software which performs such actions must meet the general expectations of an embedded environment—a limited code footprint, for instance—while still delivering good performance.
µC/FS
µC/FS is a compact, reliable, high-performance file system. It offers full-featured file and directory access with flexible device and volume management including support for partitions.
Source Code: µC/FS is provided in ANSI-C source to licensees. The source code is written to an exacting coding standard that emphasizes cleanness and readability. Moreover, extensive comments pepper the code to elucidate its logic and describe global variables and functions. Where appropriate, the code directly references standards and supporting documents.
Device Drivers: Device drivers are available for most common media including SD/MMC cards, NAND flash, NOR flash. Each of these is written with a clear, layered structure so that it can easily be ported to your hardware. The device driver structure is simple—basically just initialization, read and write functions—so that µC/FS can easily be ported to a new medium.
Devices and Volumes: Multiple media can be accessed simultaneously, including multiple instances of the same type of medium (since all drivers are re-entrant). DOS partitions are supported, so more than one volume can be located on a device. In addition, the logical device driver allows a single volume to span several (typically identical) devices, such as a bank of flash chips.
FAT: All standard FAT variants and features are supported including FAT12/FAT16/FAT32 and long file names, which encompasses Unicode file names. Files can be up to 4-GB and volumes up to 8-TB (the standard maximum). An optional journaling module provides total power fail-safety to the FAT system driver.
Application Programming Interface (API): µC/FS provides two APIs for file and directory access. A proprietary API with parallel argument placement and meaningful return error codes is provided, with functions like FSFile_Wr()
, FSFile_Rd()
and FSFile_PosSet()
. Alternatively, a standard POSIX-like API is provided, including functions like fs_fwrite()
, fs_fread()
and fs_fsetpos()
that have the same arguments and return values as the POSIX functions fwrite()
, fread()
and fsetpos()
.
Scalable: The memory footprint of µC/FS can be adjusted at compile-time based on the features you need and the desired level of run-time argument checking. For applications with limited RAM, features such as cache and read/write buffering can be disabled; for applications with sufficient RAM, these features can be enabled in order to gain better performance.
Portable: µC/FS was designed for resource-constrained embedded applications. Although µC/FS can work on 8- and 16-bit processors, it will work best with 32- or 64-bit CPUs.
RTOS: µC/FS does not assume the presence of a RTOS kernel. However, if you are using a RTOS, a simple port layer is required (consisting of a few semaphores), in order to prevent simultaneous access to core structures from different tasks. If you are not using a RTOS, this port layer may consist of empty functions.
Typical Usages
Applications have sundry reasons for non-volatile storage. A subset require (or benefit from) organizing data into named files within a directory hierarchy on a volume—basically, from having a file system. Perhaps the most obvious expose the structure of information to the user, like products that store images, video or music that are transferred to or from a PC. A web interface poses a similar opportunity, since the URLs of pages and images fetched by the remote browser would resolve neatly to locations on a volume.
Another typical use is data logging. A primary purpose of a device may be to collect data from its environment for later retrieval. If the information must persist across device reset events or will exceed the capacity of its RAM, some non-volatile memory is necessary. The benefit of a file system is the ability to organize that information logically, with a fitting directory structure, through a familiar API.
A file system can also store programs. In a simple embedded CPU, the program is stored at a fixed location in a non-volatile memory (usually flash). If an application must support firmware updates, a file system may be a more convenient place, since the software handles the details of storing the program. The boot-loader, of course, would need to be able to load the application, but since that requires only read-only access, no imposing program is required. The ROM boot-loaders in some CPUs can check the root directory of a SD card for a binary in addition to the more usual locations such as external NAND or NOR flash.
Why FAT?
File Allocation Table (FAT) is a simple file system, widely supported across major OSs. While it has been supplanted as the format of hard drives in Windows PCs, removable media still use FAT because of its wide support. That is suitable for embedded systems, which would often be challenged to muster the resources for the modern file systems developed principally for large fixed disks.
µC/FS supports FAT because of the interoperability requirements of removable media, allowing that a storage medium be removed from an embedded device and connected to a PC. All variants and extensions are supported to specification.
A notorious weakness of FAT (exacerbated by early Windows system drivers) is its non-fail safe architecture. Certain operations leave the file system in an inconsistent state, albeit briefly, which may corrupt the disk or force a disk check upon unexpected power failure. µC/FS minimizes the problem by ordering modifications wisely. The problem is completely solved in an optional journaling module which logs information about pending changes so those can be resumed on start-up after a power failure.