Flash Translation Layer for NOR Flash
Fail-safe device drivers that support external serial and parallel NOR flash and internal MCU flash.
Overview
The Flash Translation Layer for NOR Flash allows the file system layer to efficiently write and read blocks of data (logical sectors) to and from a NOR flash device. All the details regarding the access to NOR flash such us the identification of the NOR flash device, erasing of NOR physical blocks, writing the data page-wise, etc. are managed internally by the NOR driver. The NOR flash device is presented to the upper file system layer as an array of logical sectors that are identified by a 0-based logical sector index.
emFile comes with two different NOR drivers:
- Block map NOR driver
- Sector map NOR driver
The block map NOR driver has been designed for reduced RAM usage while the sector map driver for fast write operation. Both drivers support the same NOR flash devices therefor the choice of the NOR driver is a trade-off between memory usage and write performance.
Key features
- Fail-safe in case of unexpected reset
- Automatic device identification using SFDP and CFI
- Supports single, dual and quad SPI modes
- Performs static and active wear-leveling
- Devices that can not rewrite same data are supported
- Very high performance
Supported devices
In general, the Flash Translation Layer for NOR Flash supports all popular NOR flash devices. The following tables list NOR flash devices that have been tested or are known to be compatible with a tested device.
Missing a device on the list?
Most NOR flash devices are compatible with at least one supported device. This means that the driver can usually be used with these devices with little or no modification. For questions about devices not listed here, please feel free to contact us.
Serial NOR flash devices
| Device Type | Storage Capacity | |
|---|---|---|
| Cypress | ||
| S25FL128S | 128 Mbits (16 Mbytes) | |
| S25FL127S | 128 Mbits (16 Mbytes) | |
| Macronix | ||
| MX25L256 | 256 Mbits (32 Mbytes) | |
| MX66L51235F | 512 Mbit (64 Mbytes) | |
| Microchip | ||
| SST26VF064B | 64 Mbits (8 Mbytes) | |
| Micron | ||
| N25Q064 | 64 Mbits (8 Mbytes) | |
| M25P64 | 64 Mbits (8 Mbytes) | |
| N25Q128A | 128 Mbits (16 Mbytes) | |
| N25Q256 | 256 Mbits (32 Mbytes) | |
| ST Microelectronics | ||
| M25P40 | 4 Mbits (512 Kbytes) | |
| M25P80 | 8 Mbits (1 Mbyte) | |
| M25P128 | 128 Mbits (16 Mbytes) | |
| M25P32 | 32 Mbits (4 Mbytes) | |
| M25P16 | 16 Mbits (2 Mbytes) | |
| Winbond | ||
| W25Q64 | 64 Mbits (8 Mbytes) | |
Parallel NOR (CFI) flash devices
| Device Type | Storage Capacity | |
|---|---|---|
| Cypress | ||
| S29GL128N | 128 MBits (8 Mbytes x 16) | |
| Intel | ||
| 28FxxxP30 | 64 Mbits - 1 Gbits | |
| 28FxxxP33 | 64 Mbits - 512 Mbits | |
| ST Microelectronics | ||
| M28W160 | 16 Mbits (1 Mbytes x 16) | |
| M28W320 | 32 Mbits (2 Mbytes x 16) | |
| M28W640 | 64 Mbits (4 Mbytes x 16) | |
| M29F080 | 8 Mbits (1 Mbytes x 8) | |
| M29W160 | 16 Mbits (2 Mbytes x 8, 1 Mbytes x 16) | |
| M29W320 | 32 Mbits (4 Mbytes x 8, 2 Mbytes x 16) | |
| M29W640 | 64 Mbits (8 Mbytes x 8, 4 Mbytes x 16) | |
| M58LW064 | 64 Mbits (8 Mbytes x 8, 4 Mbytes x 16) | |
| Micron | ||
| MT28F128 | 128 Mbits (8 MBytes x 16) | |
| MT28F256 | 256 Mbits (16 MBytes x 16) | |
| MT28F320 | 32 Mbits (2 MBytes x 16) | |
| MT28F640 | 64 Mbits (4 MBytes x 16) | |
Theory of operation
Differentiating between logical sectors (or blocks) and physical sectors is essential to understanding this section.
A logical sector or block is the basic unit used by a file system and typically has a size of 512 bytes. A physical sector, in contrast, is an area of the flash memory that is erased as a single unit, typically ranging from 2 KB to 128 KB.
The flash driver acts as an abstraction layer between logical and physical sectors. Whenever a logical sector is updated, its previous version is marked as invalid and the new data is written to another location in the flash memory. As a result, the physical location and order of logical sectors may change with each write operation. There is therefore no fixed relationship between a logical sector index and its physical location.
The flash driver manages this mapping by storing the logical sector indexes in dedicated headers. For the upper file system layer, the physical location of a logical sector and the amount of flash memory used as a buffer are irrelevant. All logical sectors, starting with sector index 0, are always available for user access.
Wear leveling
The Flash Translation Layer for NOR Flash supports wear leveling in order to extend the lifetime of the NOR flash device. Wear leveling makes sure that the number of erase cycles remains approximately equal for each NOR physical sector. The Flash Translation Layer for NOR Flash keeps track of the physical sector with the lowest erase count and checks the difference between its erase count and the erase count of the physical sector selected to be erased. If the difference exceeds a configured value the physical sector with the lowest erase count is used instead. This method makes sure that NOR physical sectors that contain constant data will also get erased evenly.
Fail-safe operation
The Flash Translation Layer for NOR Flash provides fail-safe operation by performing only atomic actions and ensuring that the data managed by the file system remains valid. If a power loss or reset occurs during a write operation, incomplete data is discarded and the previously stored data remains valid and uncorrupted.
Fail-safe operation requires the NOR flash device to complete the last write operation received from the CPU before an unexpected reset. The flash supply voltage must therefore remain valid for several hundred microseconds after the CPU enters reset. The exact write timing depends on the device and can be found in its datasheet.
An erase operation may be interrupted by an unexpected reset. During low-level mounting, the Flash Translation Layer can detect a NOR flash sector that was not completely erased and erase it again at a later time.
Garbage collection
Flash Translation Layer for NOR Flash automatically performs garbage collection during write operations. If no empty logical sectors are available for storing new data, space is reclaimed by erasing physical NOR flash sectors containing logical sectors marked as invalid. Depending on the characteristics of the NOR flash, this erase operation can take a relatively long time and therefore increase write latency.
For applications that require minimum write latencies, garbage collection can instead be triggered by the application, for example, when the file system is idle.
Using NOR flash for code and data
Most NOR flash devices cannot be read while a program, erase, or identify operation is in progress. If code is executed from the same flash device that is currently being accessed for data storage, the application is therefore likely to crash.
This can be avoided in several ways:
- Use separate NOR flash devices: Store code and data on different devices.
- Use a multi-bank NOR flash device: This allows code to be read from one bank while another bank is being programmed.
- Execute flash routines from RAM: Ensure that the routines used to program, erase, or identify the flash reside in RAM and disable interrupts while they are executed.
NOR flash device identification
NOR flash devices can be identified using information stored on the device itself. This allows the same driver to support different devices by reading their identification and configuration data. The identification method depends on whether parallel or serial NOR flash is used.
Parallel NOR flash devices typically implement the Common Flash Interface (CFI). The NOR driver uses CFI data to determine parameters such as memory size, byte/word configuration, and physical sector layout. CFI is an open specification that can be implemented by flash memory manufacturers.
Serial NOR flash devices are identified using Serial Flash Discoverable Parameters (SFDP) or, if SFDP information is not available, the device ID. SFDP is an open specification that provides information such as memory size, physical sector sizes, and command codes for read operations in single, dual, or quad mode.
Sample configuration
The following sample shows how to configure the Block Map NOR Driver to access serial NOR flash devices. The driver is added to the file system by calling the FS_AddDevice() function with the driver type set to FS_NOR_BM_Driver. The FS_X_AddDevices() function is called during file system initialization, and all file system configuration must take place here.
The region of the NOR flash device to be used for storage is configured via the FLASH_BASE_ADDR, FLASH_START_ADDR, and FLASH_SIZE defines. In this sample, the entire NOR flash device is used for storage. However, it is also possible to reserve space for other purposes, such as a bootloader.
The logical sector size in this sample is 512 bytes (BYTES_PER_SECTOR), but other sector sizes are also supported.
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
#define ALLOC_SIZE 0x2000 // Size of memory dedicated to the file system.
// This value should be fine tuned according for your system.
#define FLASH_BASE_ADDR 0x00000000 // Base address of the NOR flash device to be used as storage.
#define FLASH_START_ADDR 0x00000000 // Start address of the first sector be used as storage.
// If the entire chip is used for file system,
// it is identical to the base address.
#define FLASH_SIZE 0x04000000 // Number of bytes to be used for storage
#define BYTES_PER_SECTOR 512 // Logical sector size
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
static U32 _aMemBlock[ALLOC_SIZE / 4];
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* 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().
*
* Note
* (1) Other API functions may NOT be called, since this function is called
* during initialization. The devices are not yet ready at this point.
*/
void FS_X_AddDevices(void) {
//
// Give file system memory to work with.
//
FS_AssignMemory(&_aMemBlock[0], sizeof(_aMemBlock));
//
// Configure the size of the logical sector and activate the file buffering.
//
FS_SetMaxSectorSize(BYTES_PER_SECTOR);
#if FS_USE_FILE_BUFFER
FS_ConfigFileBufferDefault(BYTES_PER_SECTOR, FS_FILE_BUFFER_WRITE);
#endif
//
// Add and configure the NOR driver.
//
FS_AddDevice(&FS_NOR_BM_Driver);
FS_NOR_BM_SetPhyType(0, &FS_NOR_PHY_SFDP);
FS_NOR_BM_Configure(0, FLASH_BASE_ADDR, FLASH_START_ADDR, FLASH_SIZE);
FS_NOR_BM_SetSectorSize(0, BYTES_PER_SECTOR);
//
// Configure the NOR physical layer.
//
FS_NOR_SFDP_Allow2bitMode(0, 1);
FS_NOR_SFDP_Allow4bitMode(0, 1);
FS_NOR_SFDP_SetHWType(0, &FS_NOR_HW_SPI_Template);
FS_NOR_SFDP_SetDeviceList(0, &FS_NOR_SPI_DeviceList_All);
}