Skip navigation

emFile - NOR Flash Driver

  • 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

Fail-safe device drivers that support external serial and parallel NOR flash and internal MCU flash.

About the Drivers

The NOR driver 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.

Supported Devices

In general, the NOR driver supports all the popular NOR flash devices. The following tables list the types of NOR flash devices that have been tested or that are known to compatible with a tested device.

Serial NOR Flash Devices

Device Type Storage Capacity
Cypress
S25FL128S128 Mbits (16 Mbytes)
S25FL127S128 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
S29GL128N128 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)

Support for Devices Not Available in the List

Most other NOR flash devices are compatible with one of the supported devices. Thus the driver can be used with these devices or may only need a little modification, which can be easily done. Get in touch with us, if you have questions about support for devices not in this list.

Theory of Operation

Differentiating between "logical sectors" or "blocks" and "physical sectors" is very essential to understand this section. A logical sector/block is the base unit of any file system, its usual size is 512 bytes. A physical sector is an array of bytes on the flash chip that are erased together (typically between 2 Kbytes - 128 Kbytes). The flash chip driver is an abstraction layer between these two types of sectors. Every time a logical sector is being updated, it is marked as invalid and the new content of this sector is written into another area of the flash. The physical address and the order of logical sectors can change with every write access. Hence, there cannot exist a direct relation between the logical sector index and its physical location. The flash driver manages the logical sector indexes by writing it into special headers. It does not matter to the upper layer were the logical sector is stored or how much flash memory is used as a buffer. All logical sectors (starting with sector index 0) do always exist and are always available for user access.

Wear Leveling

The NOR driver 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 NOR driver 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 emFile NOR driver is fail-safe. That means that the driver makes only atomic actions and takes the responsibility that the data managed by the file system is always valid. In case of power loss or power reset during a write operation it is always assured that only valid data is stored in the flash. If the power loss interrupts the write operation, the old data will be kept and not corrupted.

The fail-safe operation is only guaranteed if the NOR flash device is able to fully complete the last write operation it received from the CPU before the unexpected reset. This means that the supply voltage of the NOR flash device has to remain valid for a few hundreds of microseconds after the CPU enters reset. The exact timings of the write operation can be taken from the datasheet of the NOR flash device. The erase operation of a NOR flash sector can be interrupted by an unexpected reset. The NOR driver can determine at low-level mount which NOR flash sector was not completely erased. The affected NOR flash sector will be erased again at a later time.

Garbage Collection

The driver performs the garbage collection automatically during the write operations. If no empty logical sectors are available to store the data, new ones are created by erasing the data of the logical sectors marked as invalid. This involves a NOR physical sector erase operation which, depending on the characteristics of the NOR flash, can potentially take a long time to complete, and therefor reduces the write latency. For applications which require minimum write latencies, the garbage collection can be performed in the application when, for example, the file system is idle.

Using NOR Flash for Code and Data

Most NOR flashes cannot be read out during a program, erase or identify operation. This means that code cannot be read from the NOR flash during a program or erase operation. If code which resides in the same NOR flash used for data storage is executed during program or erase, a program crash is almost certain. There are multiple options to solve this:

  • Use multiple NOR flash devices. Use one device for code and one for data.
  • Use a NOR flash device with multiple banks, which allows reading bank A while bank B is being programmed.
  • Make sure the hardware routines which program, erase or identify the NOR flash are located in RAM and interrupts are disabled.

Identification of NOR flash devices

The identification of a NOR flash device is performed using the information stored to NOR flash device. This makes possible to use the same driver for different NOR flash devices by reading identifying information out of the NOR flash device itself. The identification method depends on the type of NOR flash device used (parallel or serial).

The Common Flash Interface (CFI) is typically implemented in parallel NOR flash devices and the NOR driver can make use of this information to determine the memory size, byte/word configuration, block configuration, etc. CFI is an open specification which may be implemented freely by flash memory vendors in their devices.

The serial NOR flash devices are identified via Serial Flash Discoverable Parameters (SFDP) information or when this information is not available via the device id. SFDP is also an open specification that enable a serial NOR flash device to provide information about the memory size, physical sector sizes, command codes for reading in single, dual or quad mode and so on.

Sample Configuration

The following sample shows how to configure block map NOR driver that can access serial NOR flash devices. The NOR driver is added to 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 at the file system initialization and all the file system configuration has to take place here. The region of the NOR flash device to be used as storage is configured via FLASH_BASE_ADDR, FLASH_START_ADDR and FLASH_SIZE defines. In this sample the entire NOR flash device is used as storage but it is possible to reserve space for other purposes such as bootloader. The logical sector in this sample consists of 512 bytes (BYTES_PER_SECTOR) but other sector sizes are also supported by the NOR driver.

/*********************************************************************
*
*       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);
}