0
\$\begingroup\$

I'd like to share with you some thoughts about a project to see if there are better solutions than mine...

I'm designing a board based upon CC3220SF, that requires an external flash (16 Mbit) where it stores system's and user's files.

My application MUST have a persistent circular buffer of 512/1024 kbytes. This is because the board acquires some sensors periodically and send them to the cloud. But if the connection is not available it MUST save the data for later uploading.

Some ideas:

  • use the internal RAM: reducing a bit the requirements about the buffer size, the space is enough but it seems it isn't reliable across resets (please note my system is battery powered: if the battery dies it's acceptable to loose the last records - if any)
  • use the external flash: there is plenty of space, but it seems there it's not possible to "overwrite" a file changing only the bytes involved: any write operation leads to a complete rewrite of the whole file. This limits the expected life of about 100,000 records. No way.
  • add an external S/F/D/NV-RAM: after some searches I found DRAMs are very cheap but require a parallel bus. The other types are quite expensive for that capacity.
  • ok, the last idea that comes to my mind is to add a second flash memory. Now I can write to it directly (without any file-system) but I have to select one that not requires a full page write.

Some other information:

  • the expected life of the battery should allow to acquire more than 130,000 records
  • of course after replacing the battery the board must be still functional...
  • due to the expected environment, it is very likely that the board might acquire hundreds of records every day WITHOUT an available connection. Then it will upload them at once during the night.

Any suggestions would be appreciated.

\$\endgroup\$
1
\$\begingroup\$

A typical external serial NOR flash would allow individual bytes to be written, but must be erased in 4K chunks. If all you need is a single rolling buffer, a simple approach would use a page-status byte on each page to keep track of where data should go. At any given time, there would be three "special" pages:

  1. The current page, to which new data would be written.
  2. The garbage page, which would be the one after that (or first page if the current is the very last one), which might contain anything, but whose contents should be presumed meaningless and thus ignored.
  3. The tagged page, which would be the one after that (wrapping as above), and will be the only page (other than the garbage page, which could contain anything) where the page-status byte is programmed.

If there's room in the current page to add data, append there. Otherwise, erase the garbage page, and program the page-mode byte on the page following the tagged page, turning that page into the tagged page, the previous tagged page into the garbage page, and the previous garbage page into the current page.

The tagged page may be identified because it will be the only page whose tag byte is programmed, but whose successor's tag byte isn't. Note that the tag byte on the garbage page might read as be programmed, but its successor's tag byte will also be programmed.

\$\endgroup\$
  • \$\begingroup\$ As far as I understand, the value of the status-byte names the related page (current and tagged, at least). The garbage is the page between them. I need the tagged one because the garbage might contain anything. \$\endgroup\$ – Mark May 24 '17 at 8:37
  • \$\begingroup\$ So, to find the current page I have to cycle among all pages, read every status-bytes to search for a 'current' value followed by a 'tagged' one, skipping one page (the 'garbage') \$\endgroup\$ – Mark May 24 '17 at 8:39
  • \$\begingroup\$ @Mark: On power-up, read the status byte of each page. There are some other slightly more complicated variations on this approach which would have a lower startup time, but the approach as described has a simple invariant (at most two pages will have the status byte programmed, and if there are two it will be clear that one is the garbage page). If power is lost during a block erase, repeated reads of the partially-erased page may yield different data, but with the approach as described nothing that is read from the garbage page will affect anything. Provided that programming operations... \$\endgroup\$ – supercat May 24 '17 at 14:31
  • 1
    \$\begingroup\$ ...always run to completion (which can be assured by using decent filter caps and ensuring that an operation won't start unless the voltage is high enough that the chip can remain operational for at least 10us) there is no danger that a page might read one way on one power cycle, and another way on another. If power is lost after an erase cycle would need to start, but before the next status-page-programming operation occurs, the erase cycle will be repeated without regard for whether the page in question "looks" blank. \$\endgroup\$ – supercat May 24 '17 at 14:34
  • \$\begingroup\$ Thanks for the time spent for this further clarification. I've got it. \$\endgroup\$ – Mark May 24 '17 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.