Writing to absolute sectors on SD Card

Chris Johns chrisj at rtems.org
Sat Oct 25 21:53:25 UTC 2008

Robert S. Grimes wrote:
> Thanks for all the information, which would normally give me plenty of 
> new questions to ask.  However, rather than pursue this further, I 
> discovered some new information late yesterday that probably eliminates 
> any urge, on my part, to pursue this any further.  Please allow me to 
> elaborate.
> I've been bothered a bit by my performance measurements (~18. 
> kbytes/second), which seemed to agree with a number on the SanDisk data 
> sheet - though I could get by with it for my current application.  A 
> colleague (Hi Ed!) wondered why that number was so low, given the fact 
> that SD cards are widely used in digital cameras.  I couldn't really 
> come with any explanation, so I did some experiments yesterday.  One was 
> the attempt to write absolute sectors, and by-pass the MS-DOS driver.  
> Why?  Well, because I noticed the calls to sd_read_sector (not the real 
> function name, but I don't have my sources with me) always preceeded 
> calls to sd_write_sector.  So I wanted to get rid of that potential time 
> sink (potential because reading is much faster than writing).  After a 
> while, however, I gave up and sent my post for help.

If you write less than a block size the file system will have to read the 
block to update the data in it. There is not concept of the block having never 
been used before. If you write as single bytes quickly there should still be 
only one block read and one block write. The remaining updates of the block 
occur at the cache level.

> Then, I decided to see if my write() calls were causing the problem back 
> on the MS-DOS test program.  My original test was writing 256 bytes 
> (half an SD card sector, by the way); I was assuming the driver would 
> attempt to coalesce writes to sector writes.

It should do this but it needs to read the block first because it does not 
know if the 2nd half of the block will be written.

The cache will read ahead a configured number of blocks so you can use the 
multi-block reading feature of some devices. This means you should see a burst 
of blocks read then a number of writes.

> To test this assumption, I 
> changed my write() sizes to 512, 1024, 2048, 4096, and 8192 bytes.  
> Interestingly, the write throughput for size 512 writes doubled (~40 
> kbytes/sec), but so did the other larger sizes.

What if you write 768 bytes ?

>  I didn't look "under 
> the hood" at this point, because I was running out of time, and I could 
> easily use larger write calls anyway.  But someone else may be interested.

It would be nice to know if all the timing figures add up and the code is 
working as it should.

> Finally, I noticed a blurb in the SanDisk manual that said writing to a 
> sector that has already been erased was significantly faster, as the 
> erase that is normally done during a "normal write" is skipped.  This 
> triggered my memory - isn't it true that writing is much faster than 
> erasing for most flash?

Where can I find this manual ?

> So, is there a way to pre-erase sectors? Simple enough on the 
> low-level, but how could that fit into the picture when MS-DOS is involved?

I do not think it does. The flash file system has the same problem. Let me try 
and explain with another question. How do you know a block is not being used 
any more by the file system and could be erased ? Below the file system at the 
cache and lower you do not. The file system may toggle a bit somewhere and 
perform a write but it does not erase the block. The idea of erasing a block 
on a real disk means nothing. There is no point. In the flash driver the block 
sits with data until it is written again and at that point you know the 
current block is not being used.

My point which I suspect I am not making in a clear way is pre-erasing only 
helps once and after that it does not. The way the disk is used at the block 
level become complex and depends on the file and directories created and erased.

> One thing I didn't see was how the SD card distinguishes a "normal 
> write" from one that doesn't require a pre-format.  If this is handled 
> by the card itself, then whatever we do in software will automatically 
> see the speed-up if the sectors are pre-erased, but still work correctly 
> if the erase cycle is needed.  If not, then things become much more 
> difficult on the software side, I suppose.
> If the card recognizes erased sectors, then we could simply prepare the 
> disk at some user-selected point by erasing all sectors, then formatting 
> the disk.  This would likely be acceptable for a good number of cases, 
> as it would be for me.

The file system, cache and drivers currently have no way to pass the info a 
block is not in use any more and could be queued to be erased. Maybe it should.

> I would appreciate any insight people can provide into how the SD card 
> and the MS-DOS file system operate, such that I can optimize how my 
> system uses these things.  Of course, I wouldn't mind putting in some 
> effort myself, if given a bit of guidance - right now, I have more 
> questions than answers!

I hope this helps.


More information about the users mailing list