microsd flash structure - Page 1
Forum section: electronics / projects

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 19, 2014, 10:48:26 pm
content: Hi allI want to write to a microsd card millions of times. To do this I need to move around the card a bit but I do not know the flash size of the memory pages. I assume that when it comes to read/writing, every write contains an erase and re-write of a whole page of memory. So I need to know this structure so that I can ensure my data is not moving around in the same page areas. Hope this make sense.Anyone got a link to such information? Is there a standard page structure to flash memory microsd cards ?ThanksTrev

author: bobcat
author_rank: Regular Contributor
timestamp: October 19, 2014, 10:54:01 pm
content: SD card block size is 512 bytes. HD cards can only address full blocks. LD card can address individual bytes in a block. Erase is only in full block sizes.Seehttp://media.digikey.com/pdf/Data%20Sheets/ATP%20Electronics%20PDFs/IG_SD_SDHC_Card_Spec_Rev2.6.pdf

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 19, 2014, 11:07:07 pm
content: Thank you, that is great. I am a bit tired so the obvious thing of looking through a datasheet escaped me right now. Thanks for helping me out.Trev

author: T3sl4co1l
author_rank: Super Contributor
timestamp: October 20, 2014, 01:16:09 am
content: Is it not performed automatically by the hidden MCU inside?Tim

author: marshallh
author_rank: Unknown
timestamp: October 20, 2014, 02:06:56 am
content: SD is NAND with a smart controller.Read up on SLC, MLC NAND structure.here's an example:If you want to write 512 bytes, you'd issue a SD WriteBlock command. What happens:1. Controller reads out entire page, usualy 16/64/128kb2. Controller erases page3. Controller modifies your 512 bytes of its read data, and writes it all back.So your 512bytes write caused an entire block to wear, and took a long time.Normally in an SSD you'd use a TRIM command to tell the controller to "throw out" unused space. This way it can internally write level the blocks.With SD you need to use the "WRITE MULTIPLE" command. Basically, you tell the controller "I'm planning on writing 5000 blocks, so go ahead and erase them all in preparation of writing".Then you can send your new data. In fact I think you could possibly use this as a TRIM replacement, since you can free up almost the entire SD such that new writes (which have much finer granularity) don't need an erasures before.In your case there is no point to bother moving the address around, since this is internally abstracted away by the controller.E.g. when you say "write LBA 2367" it may choose to use a new NAND address and update its addressing.

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 20, 2014, 08:04:34 am
content: I am actually using Fatfs. I create a new file and use f_lseek at the beginning to expand the file size to what I need. This means as I keep writing data the FAT table is not being constantly re-written as the file is expanded. But what it also means is that I do not know the end of the file any more between power cycles. I cant look through the file for the end location as it will take too long. So I thought I would generate a header at the start of the file and store the current end of the data.But this brought me to a problem of constantly changing the header data as I write to the file. So I thought I would have several locations available for the header information. I would start with an index value that tells me which location to use. Once that location fails to write any more, I know I have a problem and I increment the index to the next location. But for this to work I need to ensure each header location is on a separate page otherwise it will not workIf pages are 128kb then its wasteful but I can still live with having the header files on separate pages. I just need to know so that I can offset them accordingly in the file and ensure they are on different pages of memory.Once thing thought, if a page is erased before write. If I have a page erased and then only write 40 bytes at a time, is the whole page erased everytime there is a write to it?ThanksTrev

author: DmitryL
author_rank: Regular Contributor
timestamp: October 20, 2014, 09:14:54 am
content: I haven't dealt with SD cards fro quite a while, but AFAIK, SD cards don't give you _any_ guarantees about successful write.AFAIR, eMMC and NAND + specific FTL can guarantee you atomic sector (not always 512bytes) writes, i.e. sector is fully written or transaction is reverted on power failure, controller glitch etc. Basing on this it is possible to create some sort of reliable writes, including implementations of journalling FS.SD cards along with USB flash drives don't guarantee anything, e.g. even on a _read_ attempt controller inside it may decide to perform block erase (why not ?) and screw it up, and several megabytes of data will be corrupted. In reality no one cares about it, just format the corrupted file system and go on.So, any attemps to create reliable file systems on such medea are useless. Therefore, no gurantee that you can guarantee your data integrity at all.

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 20, 2014, 10:29:46 am
content: Well the first trick is not to kill the FAT table. That I believe has been done by file expansion at the start when I create the file.My situation is I am only writing small < 100 bytes of data but doing this often. So the writes and reads will mount up by the sounds of it. There must be something I can do. Its such a good source of storage.

author: DmitryL
author_rank: Regular Contributor
timestamp: October 20, 2014, 10:45:49 am
content: <sigh> If you don't want to kill FAT table (which is actually hard, because it _may_ reside in SLC area of media, if any), you just don't write into it.Create a big file (FAT supports files upto 4G-1 bytes). Better to make sure that the file is contiguous, i.e. consists of adjacent clusters). Write your data inside this file in the format you want; you can even try to organise log-like structures there to detect where your write terminated and if it is finished normally, etc, etc. On start up parse your log..Analog of a very simple journaling FS in the file. Boring stuff and very difficult to implement correctly. There should be a lot of info in the internet, I presume.And discover after 3 month of hard work that all your efforts eventually lead to the corrupted irrecoverable data because dodgy implementation of the homebrewed FAT FS didn't flush caches when you power it down, SD card controller didn't write last sector somewhere when you toggle power switch and a cheap noname SD card ran out of replacement blocks and half-died, which lead to corrupted data and half of the file system

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 20, 2014, 11:00:23 am
content: Thanks for your replies, DmitryLI have created a big file so that I do not perform continual writes, I believe I have mentioned this a couple of times. I also stated its the pointer to the end of file that gets me. If I have expanded the file then the end of file ptr is no longer valid for me. So I need to track that position myself. My board powers down and up a lot so I do not want to keep the FAT file open all the time. I open it, write data, close it. I do this many many times. At present the system seems to be writing okay but I do need more testing.I have killed a FAT table already. I have a 1 gig card here that is now read only and its a Samsung card. I will not be using no name cards and I think will stick with SanDisk as they I think are possibly more likely to implement things properly.So at the start of my log file I have a header structure that holds the ptr to the current position of the file. This part is getting updating 10s of 1000s of times. This going to get burnt out. So I decided I needed to use several places to store it but these places need to be on separate pages else I would be writing to the same page and thus have the same problem.

author: DmitryL
author_rank: Regular Contributor
timestamp: October 20, 2014, 11:14:02 am
content: <double sigh> Just imagine the situation, when you started writing your "header" or some portion of valuable data, and because of power loss or dodgy connector in SD slot internal SD card controller turns whole write block (several MB) into a complete garbage. What are you going to do ?And this is just one of the most obvious scenarios.Log (journalling information about data/metadata updates) usually being written sequentially, like records in a circular buffer. This automatically helps wear levelling and allows to "roll back" failed writes. This is an extremely boring and hard-to-implement-correctly stuff.

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 20, 2014, 11:26:03 am
content: I can handle power fail situations. I can also handle connector issues. I have the sdcard soldered to the PCB directly. I have a small power backup for loss of main power so I am able to shut down the system in a controlled way.Maybe I need two files and alternate between them writing data. Write to the first file. Write to the second file. Sleep. Then if the one file is corrupted the second is okay. But is it possible the two files may sit on the same page on the memory card and so both might be corrupted at the same time? To get around this I could put a dummy file in between them that ensures they are separated by more than a page width?What is the alternative for storing 100MB of data over 6 months and doing this for several years? I do not want to keep replacing the sdcard but is that the obvious solution?

author: amyk
author_rank: Super Contributor
timestamp: October 20, 2014, 11:30:45 am
content: Quote from: marshallh on October 20, 2014, 02:06:56 amAn eraseblock is more like 1MB+ for modern high-capacity NAND... but on the controllers I've seen (which are for the older 2K page/128K eraseblock geometry) trying to write 512B will just cause a partial page program of 512B into a different page, since they use a log-structured wear-leveling mechanism. Fill up one block and the write goes into the next one, maybe needing to erase one of the older unused blocks to compensate.QuoteUse a log-structured format, scan once on startup to find the current position and continue writing new records from there. If you have a counter for each record you can always find the "head".

author: JVR
author_rank: Regular Contributor
timestamp: October 20, 2014, 11:51:09 am
content: Having spend, and I shit you not, a year of my life getting this to work, my short answer is; Dont.We did logging to an SD card, using a circular buffer, and it WILL fail. The internal micro erases (on a 4G) card, 8MB when you want to modify a single 512byte sector. Also, if your writes are not at least 4K, the micro's internal wear leveling never wakes up, so you kill an area of the card.Whilst it is cheap and abundant storage, it is a spectacularly bad idea to log binary info to SD cards in an embedded application. As Dimitry said, you cannot control the system, as the card's internal uC is running unknown firmware, and doing what it wants, when it wants, you might think you are shutting down "controlled", but the internal uC might think thats a great time to update its wear leveling, as it is inactive at that time, boom, corrupt data.SD manufacturers are also not exactly truthful when it comes to R/W cycles, as the 100k they "claim" is when used by big files in an OS environment, with the files filling the card etc etc, ie, its a very certain set of variables under which the card will meet its spec. If you manage to get a straight answer out of them, you will be told that a typical 4GB SD card can only handle its flash being erased about 300 times, then your on your own in terms of data integrity, on a 32GB card, that number drops to ~30My company is spending an eye watering amount of money to recall and replace client units with a new solution using NORFlash, as this gives us guaranteed 100k erase cycles.So in short, plonk down a 64MByte NORFlash like the MX66F512, or a few even, and compress your logs in there. You will be saving yourself a shitload of time and money, and you do not have to worry about wear leveling in a normal application.

author: sacherjj
author_rank: Frequent Contributor
timestamp: October 20, 2014, 11:55:08 am
content: We have tested a couple thousand microSD cards for a few things, and found SanDisk to not be so great. Samsung and one other brand (mind failing me) have given us less errors.We had a meeting with representatives from Panasonic a short time ago. While their Industrial SD cards are out of our price range for BoM cost, they are probably the most robust. The build their own controller architecture. Their SD card lifetime is getting much closer to eMMC lifetime.One thing that can be helpful that Panasonic offers is a card that you use in your device. It has normal memory, plus extra logging memory. This then logs the write characteristics of your application. They can advise changes and/or tune the firmware for your application.

author: bktemp
author_rank: Super Contributor
timestamp: October 20, 2014, 12:20:51 pm
content: Quote from: sacherjj on October 20, 2014, 11:55:08 amIt is almost impossible to tell which manufacturers are good or bad:I have about 40 SD cards I am using for all kind of stuff (microcontrollers, digital camera, raspberry pi). 7 of them have failed with bad sectors after only a few month. All of them are Samsung.This shows every manufacturer produces occasionally a bad products.@trevwhiteWhy do you use FAT file system when you only need a single file? Simply use the sd card directly as a large memory with your own file system. Try to get some older sd cards (1GB or less) because modern cards are optimized for burst writes with >1MByte at a time.But if you really want to be able to predict the number of write cycles the system can take, you have to use flash memory directly with your own wear level code, optimized for your needs.

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 20, 2014, 12:36:51 pm
content: Thanks for sharing this information with me, it is certainly an eye opener.I was using FatFS because it allowed me to plug the card into a computer afterwards and check the file, etc. I did not have to manage the underlying memory system. I just wrote data to it.

author: amyk
author_rank: Super Contributor
timestamp: October 20, 2014, 02:15:36 pm
content: Quote from: trevwhite on October 20, 2014, 11:26:03 amThis (or any other 1Gbit SLC NAND):http://www.digikey.com/product-detail/en/S34ML01G100BHI000/1274-1037-ND/3761537...with a simple log-structured wear leveler + ECC. If it is possible to batch your data into sectors of 512 bytes each, then you can do 4 partial page program operations, which fits exactly within the maximum recommended by most SLC NAND flash.

author: DmitryL
author_rank: Regular Contributor
timestamp: October 20, 2014, 03:07:02 pm
content: why not eMMC ? you won't need any FTL suff then..

author: trevwhite
author_rank: Frequent Contributor
timestamp: October 21, 2014, 11:21:43 am
content: Well I already have some code working with Fatfs and I would prefer not to be starting from scratch on this. I will see if I can find some memory with serial interface and a driver for FatFs. I am currently looking at the S25FS-S family from SPANSION and will see if that fits the bill.Thanks again everyone, I think you have all just saved my project from a whole lot of pain and reliability issues.

author: Jeroen3
author_rank: Super Contributor
timestamp: October 22, 2014, 09:10:34 am
content: Are USB flash drives more reliable (or more documented)?

author: DmitryL
author_rank: Regular Contributor
timestamp: October 22, 2014, 11:58:51 am
content: All of them is unreliable garbage that can fail at any time in any unpredictable way.Unless you have a document from device manufacturer that states which guarantees it gives.

author: amyk
author_rank: Super Contributor
timestamp: October 22, 2014, 02:19:48 pm
content: Quote from: DmitryL on October 20, 2014, 03:07:02 pmeMMC basicallyisSD without the DRM stuff that almost no one sane uses - it's the same type of abstracted block-level device with an internal controller for bad block management and wear leveling.

author: DmitryL
author_rank: Regular Contributor
timestamp: October 22, 2014, 02:37:00 pm
content: Quote from: amyk on October 22, 2014, 02:19:48 pmYes, but those eMMCs I dealt with (don't know the low-level details) did provide "atomic sector write" guarantee that allowed us building a fault-tolerant file system for them.Though they might have been prototypes of some sort, it was some time ago..

author: sacherjj
author_rank: Frequent Contributor
timestamp: October 22, 2014, 05:59:11 pm
content: Quote from: amyk on October 22, 2014, 02:19:48 pmeMMC we have looked at is generally a magnitude or better than SD in write life. We have been trying to make the choice between eMMC and microSD for a product. eMMC is about 2x as expensive when hitting 32 and 64 GB.

author: SirNick
author_rank: Frequent Contributor
timestamp: October 22, 2014, 11:35:28 pm
content: If you have some sort of dying-gasp notification anyway, would it be possible to log to RAM and bulk-write on shutdown?

author: trevwhite
author_rank: Frequent Contributor
timestamp: December 15, 2014, 12:33:02 pm
content: Just a follow up on this thread. I used a dedicated flash ic in the end and rolled my own very simple filesystem. I only needed append and read operations so it was relatively straight forward.Thanks everyone for your comments. I think you saved me a lot of problems with the SD Card approach and this flash ic based version is a lot faster and more robust.

author: Jeroen3
author_rank: Super Contributor
timestamp: December 15, 2014, 12:44:59 pm
content: What technique did you use for wear leveling?

author: trevwhite
author_rank: Frequent Contributor
timestamp: December 15, 2014, 04:48:59 pm
content: I do not have wear issues to worry about. My need is just to keep taking measurements and append the data each time to my current position memory. I will probably erase data several times a year. When I do I will just erase all sectors and start again. I am not taxing this memory at all..

author: tonyarkles
author_rank: Regular Contributor
timestamp: December 17, 2014, 04:52:31 pm
content: My somewhat hacky solution would be to have a series of headers like this:Code:header:- block number- address of next block- checksumrecord:- num bytes of data- - checksumWhen you power on, you read the first sector of your file, and follow the pointer to the address of the next header. Try reading the data there, and if it passes the checksum, repeat until you reach a block that doesn't pass the checksum. You now know that you've found the last block of valid data. Go back to the last valid header, and start reading data records. Keep going until you find a record that doesn't pass its checksum. That's where you start writing from.It's not perfect, but given the constraints it should probably work reasonably well.

author: Jeroen3
author_rank: Super Contributor
timestamp: December 17, 2014, 06:51:58 pm
content: A linked list approach is an nice linear way of using the available flash. Better than FAT.I would also use fixed sized blocks, if for some reason the crc fails the next/prev address could be invalid. You don't want to lose all data in the following sectors. If it does, you can still reassemble the remaining blocks by scanning *all* supposed block positions.