Flash operations (Read , write and Erase ) and FEE concept with clear Example :

First of all, we need to know our way around the different entities on a flash chip "package" the?die, the?plane, the?block?and the?page :

  • The?package?is the memory chip, i.e. the black rectangle with little electrical connectors sticking out of it. If you look at an SSD, a flash card or the internals of a flash array you will see many flash packages, each of which is produced by one of the big flash manufacturers:?Toshiba, Samsung, Micron, Intel, SanDisk, SK Hynix. These are the only companies with the multi-billion dollar fabrication plants necessary to make NAND flash.
  • Each package contains one or more?dies?(for example one, two, or four).?The?die is the smallest?unit that can independently execute commands or report status.
  • Each die(bank) contains one or more?planes?(usually one or two). Identical, concurrent operations?can take place on each plane, although with some restrictions.
  • Each plane contains a number of?blocks(sectors), which are the?smallest unit that can be erased. Remember that, it’s really important.
  • Each block (sector) contains a number of?pages, which are the smallest unit that can be programmed (i.e. written to).

The important bit here is that?program operations (i.e. writes) take place to a page, which might typically be 8-16KB in size, while erase operations take place to a block, which might be 4-8MB in size. Since a block needs to be erased before it can be programmed again (*sort of, I’m generalizing to make this easier), all of the pages in a block need to be candidates for erasure before this can happen.

Program / Erase Cycles

When your flash device arrives fresh from the vendor, all of the pages are “empty”. The first thing you will want to do, I’m sure, is write some data to them – which in the world of memory chips we call a program?operation. As discussed, these program operations take place at the page level. You can then read your fresh data back out again with?read?operations, which also take place at the page level.?

No alt text provided for this image

Where it gets interesting is if you want to?update the data you just wrote. There is no update operation for flash, no undo or rewind mechanism for changing what is currently in place, just the?erase?operation. in that you can continue to turn?the dials and make white sections of screen go black, but you cannot turn black sections of screen to white again without?erasing the entire screen.?An erase operation on a flash chip clears the data from?all pages in the block, so if some of the other pages contain active data (stuff you want to keep) you either have to copy it elsewhere first or hold off from doing the erase.

In fact, that second option (don’t erase just yet) makes the most sense, because the blocks on a flash chip can only tolerate a limited number of program and erase options (known as the?program erase cycle?or?PE cycle?because for obvious reasons they follow each other in turn). If you were to erase the block every time you wanted to change the contents of a page, your flash would wear out very quickly.

So a far better alternative is to simply mark the old page (containing the unchanged data) as INVALID and then write the new, changed data to an empty page. All that is required now is a mechanism for pointing any subsequent access operations to the new page and a way of tracking invalid pages so that, at some point, they can be recycled.

No alt text provided for this image

So a far better alternative is to simply mark the old page (containing the unchanged data) as INVALID and then write the new, changed data to an empty page. All that is required now is a mechanism for pointing any subsequent access operations to the new page and a way of tracking invalid pages so that, at some point, they can be recycled.

Flash EEPROM EMULATOR :

There are probably many different algorithms to accomplish EEPROM emulation without forcing a lot of unnecessary writes. The main concept is like a ledger (except values don't depend on previous values). The data set or a variable has many "records" in the ledger. When a new value is written, the old value must be invalidated.

For example, you can invalidate the old value by writing some magic value which means "that record is invalid". Then, a new record can be created. Looking up a value means reading through the ledger to find the current record. All invalidated records can be ignored. Flash pages can be erased when full (the values must all be invalid or be migrated to a new flash page before erasing).

concrete algorithm example:

Let's say I have a data set of 6 bytes. I will devote 2 flash pages to emulated EEPROM for my 6 byte data set. Make the following assumptions:

  • Assume my flash pages are significantly larger than 6 bytes.
  • Assume that flash after being erased is value 0xFF.
  • Assume that I can re-write flash repeatedly without erasing, but only change ones to zeros (1->0).
  • Assume that my flash page is full when I can't fit any more full records.
  • I am not paying attention to endianness (you'll get the picture).

Flash page header

I'll start my flash page with some sort of header to indicate that I am actively storing data there (or not). Let me use 4 bytes at the start of the flash page which indicate one of the following conditions:

  1. 0x5555FFFF: This page is currently in use (the current value is one of the records).
  2. 0x55555555: This page is completely full (no current values can be found in this page). (At this point, the page should be erased before it is needed again).
  3. 0xFFFFFFFF: This page is completely erased.
  4. Anything else: Error. (Should not happen.)

Record header

For each record, I will start with a header also. Let me use 2 bytes, indicating one of the following:

  1. 0x55FF: This is the current record.
  2. 0x5555: This record is invalidated.
  3. 0xFFFF: This record slot has not been filled since the last erase.
  4. Anything else: Error. No record header slot should have anything else.

Flash pages start erased

Flash Page #0
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...

Flash Page #1
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

System initialization

After detecting that the EEPROM data has not been initialized, I will begin by initializing my data set to all 0s:

Flash Page #0
5555FFFF // Page Header (current value here: 0x5555FFFF header.)
55FF0000 // Record slot #0 (current value: 0x55FF header.)
00000000
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...

Flash Page #1
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

Notice that bytes 2-3 were not written and remain 0xFFFF. When this flash page fills up and I start a new flash page, I will write 0x5555 over bytes 2-3.

The record header essentially works the same. Byte 1 of the record #0 header remains 0xFF indicating that it is the current record (because byte 0 is 0x55).

Write the value 0xDEADBEEFCAFE

In this order:

  1. Write the new record's data.
  2. Write 0x55 to byte 0 of the new record (record slot #1) to indicate that it is the current record.
  3. Finally, write 0x55 to byte 1 of the old record (record slot #0) to invalidate it.

Order is important for recovery from spurious resets (this is similar to a journal in a file system).

Flash Page #0
5555FFFF // Page Header (current value here: 0x5555FFFF header.)
55550000 // Record slot #0 (now invalid: 0x5555 header.)
00000000
55FFDEAD // Record slot #1 (current value: 0x55FF header.)
BEEFCAFE
...

Flash Page #1
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

Write the value 0x12345678ABCD

Flash Page #0
5555FFFF // Page Header (current value here: 0x5555FFFF header.)
55550000 // Record slot #0 (now invalid: 0x5555 header.)
00000000
5555DEAD // Record slot #1 (now invalid: 0x5555 header.)
BEEFCAFE
55FF1234 // Record slot #2 (current value: 0x55FF header.)
5678ABCD
...

Flash Page #1
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

The current page is full

This is what the pages look like when the current page (Page #0) is completely full (the current value is 0xAAAA5555BBBB):

Flash Page #0
5555FFFF // Page Header (current value here: 0x5555FFFF header.)
55550000 // Record slot #0 (now invalid: 0x5555 header.)
00000000
5555DEAD // Record slot #1 (now invalid: 0x5555 header.)
BEEFCAFE
55551234 // Record slot #2 (now invalid: 0x5555 header.)
5678ABCD
...
55FFAAAA // Final record slot (current value: 0x55FF header.)
5555BBBB

Flash Page #1
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

Notice that flash page #0 is not yet invalidated (the current record is the last record in flash page #0).

Write the value 0x80009000ABCD

The next value must go into flash page #1. After writing the new record in flash page #1 and creating the page header to indicate that flash page #1 now contains the current value, we invalidate flash page #0 (write 0x55 to bytes 2-3) and the last record in flash page #0 (write 0x55 to the last record's header byte 1).

Flash Page #0
55555555 // Page Header (page is all now invalid: 0x55555555 header.)
55550000 // Record slot #0 (now invalid: 0x5555 header.)
00000000
5555DEAD // Record slot #1 (now invalid: 0x5555 header.)
BEEFCAFE
55551234 // Record slot #2 (now invalid: 0x5555 header.)
5678ABCD
...
5555AAAA // Final record slot (now invalid: 0x5555 header.)
5555BBBB

Flash Page #1
5555FFFF // Page Header (current value here: 0x5555FFFF header.)
55FF8000 // Record slot #0 (current value: 0x55FF header.)
9000ABCD
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

Now, flash page #0 is completely invalid, and the new page is Flash page #1.

Flash page #0 is garbage collected (erased)

Finally, flash page #0 can be erased when the system finds it convenient.

Flash Page #0
FFFFFFFF // Page Header (unused: 0xFFFFFFFF header.)
FFFFFFFF // Record slot #0 (unused: 0xFFFF header.)
FFFFFFFF
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...

Flash Page #1
5555FFFF // Page Header (current value here: 0x5555FFFF header.)
55FF8000 // Record slot #0 (current value: 0x55FF header.)
9000ABCD
FFFFFFFF // Record slot #1 (unused: 0xFFFF header.)
FFFFFFFF
...        

Record lookup, real-world complexities

In the real world, the data set would be larger and more complex than a single 6-byte chunk. There are many complexities I glossed over. This is a really simple example, but it would work. It illustrates how EEPROM can be emulated in flash without excessive erasing by creating a ledger of value records.

To look up the current data set values, find which flash page is current (one and only one flash page should have the header 0x5555FFFF). Then, read through the records in that page sequentially until finding the current record (one and only one record should have record header 0x55FF). Errors could invalidate the header configuration, potentially leading to multiple pages and/or records which appear to be current. A real application would need to handle such errors.

Abdelrahman Hebish ????

Embedded software engineer @ Cairomotive || Functional safety || ISO 26262 || IEC 61508 || Classic AUTOSAR

1 年

It really helped me and many many thanks Happy to see this as a first proposal from google search engine

Ahmed Sherif

Software Developer | AI Engineer | Data Scientist

3 年

Very informative Thanks

Mariam Habashy

Senior Test Manual and Automation Engineer| ISTQB?

3 年

Thanks for your efforts ??

要查看或添加评论,请登录

Mohamed Gaber的更多文章

  • Memory Management Unit (MMU)

    Memory Management Unit (MMU)

    Memory management units (MMUs) are incorporated in, or available for, a wide range of embedded CPUs. Under some…

社区洞察

其他会员也浏览了