emFile - Universal NAND Flash Driver
Fast and efficient NAND driver that supports SLC and MLC NAND flash devices and multi-bit ECC.
About the Driver
The Universal NAND driver provides the file system a very fast and efficient access to most of the modern SLC and MLC raw NAND flash devices. It supports a large number of NAND flash devices from different manufacturers using either parallel or serial interface. The implementation of the driver has been carefully optimized to use as less RAM and ROM as possible while maintaining a very good performance. The data reliability is ensured by making use of ECC to correct single or multiple bit errors that occur in the user and in the driver management data. The ECC can be calculated either using dedicated hardware such as the internal hardware ECC of some NAND flash devices or entirely in the software using an utility such as emLib ECC. The Universal NAND driver is by design fail-safe and comes with support for wear leveling and bad block management.
In general, the driver supports almost all Single-Level Cell NAND flash devices (SLC) and Multi-Level Cell NAND flash devices (MLC) with a page size larger than or equal to 2048+64 bytes. The table below shows the NAND flash devices that have been tested or are compatible with a tested device.
Performance and Resource Usage
The emFile NAND driver has been carefully designed to make effective use of RAM. The amount of RAM required by the driver depends on the runtime configuration and the connected device. In a typical embedded system which uses a 2 GBit NAND flash, the driver requires less than 8 KBytes of RAM.
The NAND Flash has a high read and write performance. For example, on an Cortex-M CPU running at 168 MHz, the driver reaches a transfer data speed of 4.6 MBytes/sec for writing and 8.0 MBytes/sec for reading.
Theory of Operation
NAND flash devices are divided into physical blocks and physical pages. One physical block is the smallest erasable unit; one physical page is the smallest writable unit. Large block NAND Flash devices contain blocks made up of 64 pages, each page containing 2112 bytes (2048 data bytes + 64 spare bytes). The first page of a block is reserved by the Universal NAND driver for management data.
The Universal NAND driver uses the spare bytes for the following purposes:
- To check if the block is valid. The driver uses only valid blocks for storage. If the block is not valid it will not be used. When the driver detects a bit error, the entire block is marked as invalid and its content is copied to a non-defective block.
- To store/load management information This includes the mapping of pages to logical sectors, the number of times a block has been erased and whether a page contains valid data or not.
- To store/load an ECC (Error Correction Code) for data reliability. When reading a sector, the driver also reads the ECC stored in the spare area of the sector, calculates the ECC based on the read data and compares the ECCs. If the ECCs are not identical, the driver tries to recover the data, based on the read ECC. When writing to a page the ECC is calculated based on the data the driver has to write to the page. The calculated ECC is then stored in the spare area.
Partial Write Operations
The Universal NAND driver has been designed to provide high data reliability. This is realized by performing a single write operation to any page of the NAND flash device between two block erase cycles which reduces the chance of a bit corruption. Using a number of partial writes of one makes the Universal NAND driver compatible with any popular SLC / MLC NAND flash device.
Support for Custom Hardware
It is possible to use the NAND driver with custom hardware. If port pins or simple memory controller are used to access the flash memory, only the hardware layer needs to be ported, normally no changes to the physical layer are required. If the NAND driver should be used with special memory controller (e.g. special FPGA implementations), the physical layer needs to be adapted. In this case, the hardware layer is not required, because the memory controller manages the hardware access.