Tell me more ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

Atmel recommends:

"if the reprogram operations occur in a random fashion in which any number of pages is
updated in a random order, then the system must ensure that each page of the Serial DataFlash memory array be updated/rewritten at least once within every 10,000 cumulative page reprogram operations" (http://www.piclist.com/techref/atmel/doc0842.pdf)

There is an algorithm proposed for rewriting pages, which use page adress pointer (or page reprogram counter). My question is what is the right place for this pointer/counter? One of DataFlash pages?

share|improve this question

3 Answers

If at all possible, it's nice to keep a number like that in the software (preferably RAM, possibly EEPROM) of the device (e.g., microcontroller) controlling the flash.

If you have to do it in that flash device, you might want to take advantage of the extra 8 bytes per 256-byte flash page in that device to store the pointers; that's one of the suggested uses.

"System designers can use all of a page’s 264 bytes for storing data. Alternatively, the 8 extra bytes per page can be used for error detection and correction mechanisms (EDC) or associated control information, such as pointers, flags, and phone message routing directions."

share|improve this answer
RAM? Would it be ever possible to keep in RAM that pointer through the lifecycle of the system? – Stephen Aug 25 '10 at 6:45
That depends on what you're doing. Many times, this is indeed possible. Imagine a small, self-contained datalogger. It might operate for years on a main battery, plus have a backup battery to maintain power through battery changes. Flash memory doesn't last forever-- typically 10k - 100k cycles per page. Whether that lifetime is minutes or decades depends heavily on your application. – Windell Oskay Aug 26 '10 at 0:51

Here's how I'm doing this to save a circular buffer in flash.

Reserve one page (528 bytes) for the Index. The first 16 bytes is a bitmask. The first 0 in the bitmask is the offset position of the latest Index value. So the first page has 16 bytes for bitmask followed by 128 4-byte values for the Index.

As you write to the circular buffer you need to save the new Index value. Do this by knocking down the next '1' bit in the bitmask to a '0' and writing the Index to this offset position. You will need to do a "Program without Erase" command to the flash.

Once all the bits in the bitmask are '0', then you have to erase the page and start fresh.

share|improve this answer

Another alternative:

Reserve a "recently rewritten" bit in each page of that flash chip's memory. (Perhaps store that bit in one of the 8 "extra" bytes per page).

As the appsheet suggests, every time the application writes to some random page, also re-write some other page that hasn't been re-written in a while. To find that other page, scan through all the "recently rewritten" bits searching for a "0" bit. The first "0" bit you find corresponds to the specific page to be rewritten. Once you've found it, rewrite the data in page while erasing the "recently rewritten" bit to "1".

Since you scan in sequential order, the "recently rewritten" bits towards the beginning are all "1", and the bits towards the end are all "0".

(Optionally keep a pointer in RAM pointing to the page with the last page with a "1" "recently rewritten" bit, or first page with a "0" bit, so you can start searching from that point, rather than starting from page 0 every time).

When you do the search, and the CPU can't find any pages that need to be rewritten (every "recently rewritten" bit is a "1"), then program every "recently rewritten" bit to "0", starting with that bit in flash page 0. (You can program just this one bit per page without erasing the entire page).

At boot time, when the power first gets turned on, you'll need to check if the flash is in the "normal" state -- all the pages towards the beginning all have a "1" "recently rewritten" bit, and all the pages towards the end all have a "0" bit. Anything else indicates the "interrupted" state, in the middle of programming all the "needs to be rewritten" bits to "0", in which case the CPU should finish programming all those "recently rewritten" bits to "0".

(I suppose you could, instead of storing that bit inside its corresponding page, pack all those bits together in a bit array and store them in a few pages of flash that you reserve for that use. For example, the 7th bit in that array corresponds to the 7th page of flash. In that case, you'll probably want to invert the meaning of the bit, and program the bit to "0" when the corresponding page is erased and rewritten, and once in a long while, whenever you discover that every page has a corresponding "0" bit, erase all those bits to "1". The result is about the same as what rdeml suggested).

share|improve this answer
One caveat with this approach is that the Dataflash only allows (i.e. specifies the behavior of) programming operations on completely blank pages. The approach I used in my application was to maintain a count of how many flash writes had been performed in the application's lifetime, and store in each flash page the value that counter had when the page was written. – supercat Mar 2 '11 at 17:25
Oops, it looks like you are right. Most of the other flash chips I've used or read about -- such as the Atmel Block Erase Flash -- allow partial writes: I can arbitrarily change bit(s) from 1 to 0, without an erase cycle, even if I've already changed some bits in that block from 1 to 0. Since the Dataflash datasheet doesn't specifically say what happens when I write more 0 bits to a page that already has some 0 bits, it's an undefined operation. – davidcary Mar 7 '11 at 17:26
It's too bad there's no nice way of adding just a little data to a page. It would have simplified some things. Still, if you want a robust way of adding data to a rolling log or something, I'd suggest having a system invariant that when the system is idle there will always be two blank pages after the end of the written data, and no others (when the device is new, pre-fill all the other pages). The page following the two blank pages should be presumed meaningless. To write a new data page, overwrite the first blank page, then erase the page after the second. On startup... – supercat Mar 24 '11 at 19:52
...make sure there are two blank pages. If there's only one, erase the page before it since it might only be partially written. This will cover the cases where the write of the blank page failed, as well as the case where the erase failed, provided that the memory doesn't get erased just enough that it sometimes reads blank and sometimes not. There isn't any good way to handle that scenario, except to use checksums and hope for the best. – supercat Mar 24 '11 at 19:55
Note, btw, that if one could add "0"'s to non-blank pages, one could write a protocol that was immune to "almost-erase" operations, but without such a feature it's not possible. – supercat Mar 24 '11 at 19:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.