This post demonstrates a way to use the flash memory of the 8-bit flash MCU families to emulate single variable rewritable EEPROM memory through software. The example API provided enables reading and writing of single variables to non-volatile flash memory. The erase-rewrite algorithm distributes page erases and thereby doing wear leveling.
2 General Theory
2.1 EEPROM and Flash Based Memory
EEPROM stands for Electrically Erasable Programmable Read-Only Memory and is a type of nonvolatile memory that is byte erasable and therefore often used to store small amounts of data that must be saved when power is removed. Most of 8 bit MCU does not include an embedded EEPROM module for byte erasable non-volatile storage, but for C8051Fxxx MCU families do provide flash memory for non-volatile data storage. The main difference between flash memory and EEPROM is the erasable unit size. Flash memory is block-erasable which means that bytes cannot be erased individually, instead a block consisting of several bytes need to be erased at the same time. Through software however, it is possible to emulate individually erasable rewritable byte memory using block-erasable flash memory.
To provide EEPROM functionality for the 8 bit flash MCU in an application, there are at least two options available. The first one is to include an external EEPROM module when designing the hardware layout of the application. The other is to use the on-chip flash memory and emulate EEPROM functionality through a software API. There are however some key differences between these two methods.
• First, the write access time for flash memory is shorter than for external EEPROM. This means that writing to emulated EEPROM is faster than writing to an external EEPROM.
• Second, while a standalone EEPROM will be able to complete a write operation even if the system is reset, the emulated EEPROM will need the CPU to be active throughout the entire flash operation. This is an important difference. The consequences of an aborted flash operation should be taken into account when designing an application. The flash based EEPROM emulation could use checksums and logging to ensure the integrity of written data.
• Lastly the emulated EEPROM will regularly need to erase pages in flash, to free space and be able to write to the same page more than once. On a standalone EEPROM there is no need for a dedicated erase operation, since all bytes can be rewritten independently. Here it is also important to notice that the flash erase operation will need the CPU to be running safely for the entire operation.
In addition to the risk of power failure or system reset aborting flash write or erase operations, one must also handle internal sources like disable interrupts and enable VDD monitor while performing the flash write/erase operations. This can be done in software.
1.1 Flash Limitations
Flash memory is limited to a finite number of program-erase cycles. This means that the embedded flash memory of the MCU can be erased only a certain number of times, before the wear will begin to affect the integrity of the storage. This deterioration applies to all kinds of flash memory. All 8 bit flash MCUs are guaranteed to withstand a number of erase cycles. This number can be found in the data sheet for each part.
All flash memory is divided into pages that each must be erased as single units. The amount of on-chip flash memory and the page size found in the different 8 bit MCU varies depending on the specific part. See the Reference Manual for more information about the page size. Because the erase operation erases only whole pages, it is important to write as much data as possible to a single page of flash, before erasing the page.
There are different ways to implement an EEPROM Emulator using flash memory. The idea behind the example attached in this application note, is to allocate a certain number of pages of flash memory for the entire lifetime of the application. The wear is then leveled among these by alternating which pages are used. The number of pages allocated must reflect the amount of data that will be written throughout the application lifetime.
2.1 Pages and Their States
In every page allocated to the EEPROM Emulator provided, the first dword is reserved for page head data. This head dword contains the status of the page and the erase count. The erase count is the number of times the page has been erased. The erase count is incremented each time the page is erased. Each page will always be in one of three different states. Active, Receiving or Erased.
• After a page is erased, all bits in the entire page are 1's except head data of the page.
• When a page is receiving, it means that a transfer of variables from a full active page is in progress. After the transfer is complete, the receiving page is made the new active one, and the old active page is erased.
• The active page is the page that contains the currently valid data. All read and write operations are made on the active page. There should never be more than one active or receiving page at any time in this implementation.
Fig 3.1 shows the state flow for a realization using 2 pages. The flow would be similar if more pages are allocated; only more pages would be in the erased state simultaneously.
Figure 3.1 EEPROM Emulation Page Status Flow.
During initialization, the page status for the selected number of pages is checked, to ensure that a legal set of page-states are obtained. If there is more than one active page, the page which is full will be erased. And receiving status page will be erased. This minimizes the probability for data collisions with program instructions, which are located at the base of the flash. In applications where much of the available flash memory is in use, it can be critical to know where all data is stored in the flash to avoid collisions.
The remaining words of each page, after the page head data, are free to be used for data storage. Each data storage word is divided into two parts; one virtual address field and one data field. Each of them is 8 bits wide. Whenever a page is full, a page transfer is initiated. This operation consists of several steps to always ensure that all variables are non-volatile in case of an external event. First, an erased page is located to store the valid data present in the full page. This page is marked as receiving. Next, the most recent data associated with each variable is transferred to the top of the new page. When this is done, the old active page is erased, the erase count is written to the old active page header, and receiving page is labeled as the new active page. This process is illustrated in Figure 3.2.
Figure 3.2. EEPRO Emulation Variable Flow.
3.2. Read and Write
Reading consists of iteration through the active page, starting from the bottom. When the correct virtual address is found for the first time, the corresponding data is returned as the currently valid data.
The write operation consists of a similar iteration, only which it is starting at the top of the active page. When an empty word is found, the correct virtual address and data are written, and the function returns. If no empty word is found, and the end of the page is reached, the page is considered full.
In this implementation all valid data has to fit in one page (the active page). The page size therefore puts a direct limitation on the number of variables. Each variable uses 2 bytes (1 byte for data and 1 byte for the virtual address) and 4 bytes per page is reserved for the Page Status Header. We default set the EEPROM size no more than 1/4 flash page size. And also 8 bit alignment. For example, 512 bytes page size, the maximum EEPROM size is:
Nmax = ((512 - 4) / 4) & 0xF8 = 127 & 0xF8 = 120.
3.3. Initialization and Recovery
An important part of EEPROM emulation software, is to ensure correct page state, and data recovery on system startup. For this reason, the initialization function should be run near the start of the software, before any data is written or read to/from EEPROM. The initializing function will decide how many pages that are allocated to the emulator, it will then check the head of each of these pages to ensure that the set of pages are valid. There are several conditions we need to handle.
· Erased page
It is not formatted, simply format this page. The format operation contains erase the page, and update erase count in page header data.
· Page with receiving status
Simply format this page; this situation can be caused by an uncompleted page transfer.
· Two more pages with active status.
Compare with two pages; simply format the page which is full.
Once status check completed, it will scan current active page, and update page information.
3.4 Configurable Options
The firmware supports all 8 bit flash MCU families. Define the device being used in flash_parameters.h, (i.e. C8051F850)
The EEPROM emulation firmware has following parameters can be configured. These parameters are located in head file eeprom_config.h.
Pages used for EEPROM emulation: 2
EEPROM storage area begins: LOCK_PAGE - FL_PAGE_SIZE * FL_PAGES
Number of bytes of EEPROM: 16
Number of bytes for page head data: 4
Number of bytes used per EEPROM data: 2
4. Source code
Source code can be found in https://github.com/MarkDing/eeprom-emulation