Emulating EEPROM in MSP430 Flash

From Texas Instruments Wiki
Jump to: navigation, search

Intro to EEPROM Emulation on the MSP430

As the industry continues its drive towards higher integration and the reduction of material costs for a given application, external electronically erasable and programmable read-only memories (EEPROMs) are often discussed as targets for cost saving strategies in hardware design. Using embedded Flash memory technology, the MSP430 microcontroller is capable of emulating EEPROM functionality in a variety of applications. This document describes a set of methodologies that can be used to accomplish EEPROM emulation as well as some of the limitations in memory and real-time performance that must be taken into consideration when evaluating the feasibility for a given design.

EEPROM vs Flash Technology

This section highlights the main features and differences between electrically erasable programmable read-only memory (EEPROM) and flash memory technologies. The assumption is made that the designer has or is currently working with an EEPROM and is knowledgeable of the specified capabilities of his or her particular memory device in the context of his application in order to draft a successful comparison of performance and feasibility of EEPROM emulation in his or her overall system.

External EEPROM

EEPROM is a type of non-volatile memory used in applications to hold data that must be maintained between power cycles. The memory is randomly read and write addressable. The amount of data being stored is most often small, limited to a boot program or a few variables that the application must keep track of. In some cases, more complex data structures can be stored in an EEPROM.

EEPROMs exist in two flavors: serial and parallel. Since the MSP430 has no parallel memory interface for its flash memory or otherwise, the scope of the application report is limited to serial EEPROM devices. Serial EEPROMs typically employ a standard interface, such as SPI or I2C, plus a chip select and a data hold line (optional) that, when active, instructs the EEPROM to ignore the clock line while the MCU handles a higher-priority event. Sometimes, proprietary EEPROM interfaces will require modifications of the SPI interface or software-driven solutions that employ a GPIO and a timer.

Though the communication protocols used to write to or read from an EEPROM vary, there is a set of basic modes of operation that are typical, including:

Address Write
The master device provides a write request and an address into the EEPROM, offset from 0x00, into which to write a byte or consecutive string of bytes to memory. Memory can be paged, and may require separate serial addresses to do so.
Address Read
The master device provides a read request and an address into the EEPROM, offset from 0x00, from to read a byte or consecutive string of bytes to memory.
Current Read
The EEPROM will keep a pointer to either the memory location that was last accessed or the memory location directly after. When a current read is issued from the master, the EEPROM automatically reads out the contents at this pointer into the serial communication buffer.

Embedded Flash

Flash memory is good for storing application constants, program code, and large amounts of application data that must be retained for relatively long periods of time. Data is stored in large multi-byte segments that may make it difficult to negotiate single byte or word write or erase operations, depending on the technology that is employed. For this reason, data stored in Flash memory is usually written to or read from in large blocks. Erase procedures must always be executed on entire segments, so all data stored within the bounds of that segment will be lost. Some flash memory controllers allow for the erasure of full memory banks, or a certain collection of memory segments. All flash memory controllers have the capability to clear the entire memory.

MSP430 Embedded Flash

The main MSP430 Flash features are as follows:

  • There are different segment sizes integrated onto the device including:
  • Information memory segments (e.g. – INFO_A) are each 128 B (F1xx, F4xx, F5xx, F6xx) and 64 B (F2xx, F47x) in size
  • INFO_A can be protected from write or erase operations
  • Main & BSL* memory segments are each 512 B in size
  • Byte, Word (2 bytes), and Long* (4 bytes) programmable
  • Each segment can be erased a minimum of 10,000 cycles
  • Segment erase, bank erase*, and mass erase
  • Multiple banks allow program execution from one bank during a flash erase operation in another bank.*

Note ( * ): Available only for 5xx & 6xx families of MSP430 devices. Please refer to the device-specific user guide / datasheet.

A Comparison

In comparison to an EEPROM, embedded flash technology has one significant advantage over EEPROM devices: access speed. Reading from on-chip flash is limited by the maximum operating frequency of the CPU and/or the bus speed of a device. For the MSP430, these are the same so the maximum operating frequency can be used to evaluate read speeds. In contrast, read access from an EEPROM is in the microsecond range. For a write operation, the difference is even more significant. For example the MSP430F5xx family specifies a worst case 85 μs to write a single byte or word to flash. The typical time for a single-byte write to an EEPROM is in the range of multiple milliseconds.

The tradeoffs for EEPROM emulation include the segment-erase behavior inherent to flash technology and the added dependency of a data write on the CPU, meaning high-priority interrupts such as reset conditions that could interrupt and negatively affect a write in progress. These conditions should be evaluated per the application and accounted for by the firmware engineer. A segment-erase takes longer in an MSP430 (e.g – the MSP430F5xx family specifies a best-case 23 us) versus a byte-reprogrammable device like an EEPROM. Due to the fact that many MSP430 device families do not include multiple memory banks, the CPU must spin during the time that either a write or an erase operation is being executed. These milliseconds of latency can disrupt the real-time behavior that was previously independent of the EEPROM and must be accounted for in a worst-case analysis of any real-time system with the consideration that it can become a showstopper if those required times to execute the write and erase procedures are not periodically and reliably available.

Segment erase operations also erase full 128 or 512 byte segments, whereas an EEPROM can singularly re-program any byte in the memory array. This adds a complexity to an application emulating EEPROM since memory management becomes an important consideration for the firmware and, in some cases, even the hardware designer. The methodologies for addressing these considerations are described in the following sections.

Before deciding if EEPROM emulation suits your application needs; check the following factors:

  • What is the size (# of EEPROM emulated bytes)?
  • What is the expected endurance? (flash minimum = 10000 write/erase cycles)
  • How many bytes require a 'true' random write capability. Page backup and re-write efforts can be greatly minimized by arranging data sequentially.
  • What are the availabe RAM and Code Flash resources to handle the algorithm for data management
  • All writes are confined to a minimum page size of 512 bytes(128 bytes when using Info memory). Will my application be able to support a full page write on power loss? or can it withstand losing one page of data?
  • What are the real time limitations on the system? for e.g. disabled interrupts during flash erase.

Emulating EEPROM in Flash

In general, the greater the size and complexity of the data structures that are stored in the EEPROM, the more memory and overhead that an MCU using embedded flash will require to manage and properly emulate the EEPROM behavior. The basic premise for EEPROM emulation is as follows.

Assume that one byte of EEPROM storage must be emulated in embedded flash resulting in a guaranteed endurance specification of 100,000 write cycles.

MSP430 flash segments:

  • Guarantee a minimum of 10,000 erase cycles (100,000 erase cycles typical)
  • Are 512 bytes in size

To emulate 100,000 write cycles, a one-byte value should be allocated ten bytes of embedded flash in order to implement a circular buffer. Through use of the circular buffer the value may be updated ten times before requiring an erasure of flash.

 10,000 guaranteed erases * 10 byte writes per erase = 100,000 guaranteed writes 

Assume now that two bytes of EEPROM must be emulated in embedded flash, and each byte must guarantee an endurance of 100,000 write cycles. Since the segments are 512 bytes in size both bytes may be stored in the same segment of memory. In this case, the firmware designer must account for the fact that an erasure of the segment due to a circular buffer overflow will count against the endurance limit of both bytes in the segment. It follows that the bytes should be erased half as often in order for both to meet the original 100,000 write cycle specification. This is accomplished by extending the size of each circular buffer to a full twenty bytes.

This logic may be extended to the maximum of 7 circular buffers, each 70 bytes in length.

 7 x 70-byte circular buffers = 490 bytes 

This results in 7 x emulated bytes of EEPROM that guarantee 100,000 write cycles per segment of embedded flash.

This methodology is successful in emulating the non-volatile behavior of EEPROM. It fails, however, to account for the non-volatile storage of the array of pointers to the latest values written to flash. Since this pointer table must be kept in RAM, the application will lose the location of the valid values between power cycles unless a bulk capacitor of sufficient size is used to guarantee enough time to move the information to flash memory.

The solution to this inherent gap in functionality versus EEPROM is to have a shadow byte for each location in the circular buffer. This shadow byte holds the index to the circular buffers containing the data. For every flash byte that is written to, the corresponding shadow byte is programmed to 0x00.

EEPROM flash emulation MSP430.jpg

The result of this implementation is that the after a power cycle, the firmware can traverse the shadow bytes for the value 0x00, until ‘0xFF’ is reached (default state of erased flash). The offset into the circular buffer that contains the last valid value of emulated EEPROM can then be inferred from the last location that contains a 0x00. Because the algorithm depends on a valid compare against the value 0xFF, the mirrored buffer must be of length 10n + 1, where n is the number of emulated EEPROM bytes in the segment of flash. This means that the maximum number of emulated EEPROM bytes per segment of flash is five.

 5 x (10n + 10n + 1) 						=  	...
 5 x (10*5 + 10*5 + 1)						=	...
 5 x (50-byte circular buffer + 51-byte mirrored buffer) 	= 	...
 5 x 101-byte buffers 						= 	505 bytes 	

This results in 5 emulated bytes of EEPROM that guarantee 100,000 write cycles per segment of embedded flash. The resulting requirement of flash memory to emulate x bytes of EEPROM of 100,000 write cycles is, therefore:

 round_up( x / 5 ) 

In order to emulate 128 bytes, 26 segments of embedded flash, or 26 x 512 = 13,312 bytes of Flash memory are required. Each segment is specified as its own section in the linker command file as to be protected from being overwritten by the linker. An array EEPROMy[5][101] would be defined within each segment where y is a number 0 – 25 representing the segment in memory used to emulate the 128 bytes of EEPROM.

Suggested User API

The interface to the EEPROM emulation firmware could be implemented as a 3-function API, for which the pseudo-code follows:

Init_RAM_Table( )

Description: The correct offsets to the latest valid values written to flash are interpreted and stored as a table of pointers, char * RAMtable[128]. This necessitates 256 bytes of RAM for the EEPROM emulation (128 word-length pointers to the emulated bytes of EEPROM). Added to the other 128 bytes of volatile EEPROM emulation, this results in a minimum of 384 bytes of RAM required for the EEPROM emulation – not accounting for the variables used to implement the code.

These offsets must be properly identified and stored at startup by an initialization function, called Init_RAM_Table( ).


 init_RAM_table( ) {
   char * table_ptr = &RAMtable[0]; 	// point to the first pointer in the table 
   for (y = 0; y < 26; y++){ 		// y is the number of the segment of memory
     init_segment_pointers(* EEPROMy, *table_ptr); 
     table_ptr				// table_ptr + 5 every iteration and is initialized to 

// &RAMtable[0]

 init_segment_pointers( * segment_ptr, * table_ptr) {
   for (n = 0 ; n < 5 ; n++) {
     Search the mirrored bytes for 0xFF @ EEPROMy[n][k] to identify the offset k;
     // Set the RAMtable ptr to the last valid location in the circular buffer    
     *table_ptr = &segment_ptr[n][k+50]; 
     table_ptr++; 			// Increment the RAMtable ptr being written to

write_data_byte( )


The EEPROM address (EEPROM_addr - a number between 0 and 256) and the value intended for that address are input to the micro using I2C. RAMtable[EEPROM_addr] holds the pointer to which the value should be written. In the case that this index is the last within the circular buffer, the segment will need to be erased prior to writing the value. The other four emulated EEPROM bytes in the segment must also be copied into a global temporary buffer (char temp_buffer[4]) and re-written into flash.

Since RAMtable does not hold information about the segment boundaries or which of the other pointers exist within the same segment, the pointer to the current segment must be calculated by decoding an offset from the EEPROM_base_address (the address of the first byte in the EEPROM0 array) and EEPROM_addr.


 write_data_byte( char EEPROM_addr, char value )
   if(EEPROM_addr >= 128){
     write_to_upper_128( );			// Write to volatile memory buffer
     int quotient = EEPROM_addr % 5; 
     int remainder = EEPROM_addr – (5 * quotient);
     // Calculate the data_ptr to the beginning of the x array where x is the EEPROM byte   
     being emulated.
     char * data_ptr = EEPROM_base_address + 512 * quotient + 101 * remainder; 
     // Check if the value is currently written to the last location in the circular buffer
     if( (RAMtable[EEPROM_addr] – data_ptr) > 100 )
       store_valid_bytes( );      	// Store the other four valid bytes in the segment
       erase_flash_segment( );	
       restore_bytes( ); 		// Restore the other four valid bytes in the segment
       flash_write_byte(  );	// Write the value into the intended EEPROM address
     else				// byte is not at the last location of the circular buffer
       flash_write_byte( ); 	

read_data_byte( )


Dereferences the index at the input EEPROM_addr.


 char read_data_byte( char EEPROM_addr)
     if(EEPROM_addr >= 128){
       return upper_128[EEPROM]
       return *RAMtable[EEPROM_addr];