Interesting SD Card experiment with dosfs driver

Robert S. Grimes rsg at
Wed Oct 29 21:15:44 UTC 2008

This is probably not terribly useful, I found it interesting.   I'm not 
reporting a problem here; rather, this is more of an example of how the 
dosfs file-system works on top of the spi-sd-card driver. 

My simple test is with a (mostly) empty SD card.  I write 1 MByte of 
data, in 32 chunks.  Each chunk consists of 4 calls to write(), each of 
8,192 bytes.  Then, I close the file and unmount the partition. 

To get a bit of insight, I print out a string like this on entry to the 
spi-sd-card.c driver:

    ReadN @ $0001F800

or of course, WriteN.  In both cases, N is replaced by the number of SD 
card "blocks" (512 bytes) to read or write. 

Here is some (edited) output for this experiment.

First, I create the file - seems the driver reads 32 blocks (from the FAT?).

    Creating tst4.txt, returned 4
    Write1 @ $00060200
    Write1 @ $00064200

Now I begin the four 8,192 byte write()

    Writing 1 MBytes
    BufferSize: 8192
    Chunk 0             <== First chunk starts here
    Read64 @ $0001F800
    Read1 @ $0001FA00
    Read1 @ $0001FC00
        <snip>          <== 28 other calls to Read1
    Read1 @ $00023600

Note that the reads, other than the first, are all for consecutive 
single blocks.  Did the Read64 not work? Or are the subsequent Read1's 

Now comes the next 15 "chunks" of 32,768 bytes at the application level

    Chunk 1
    Chunk 2
        <snip>          <== 12 other chunks here
    Chunk 15

Now comes 32 single, consecutive, block writes

    Write1 @ $08264200
    Write1 @ $08264400
        <snip>          <== 28 other writes here
    Write1 @ $08267E00
    Write1 @ $08268000

This pattern of a number of chunks (4 writes of 8192 from the 
application), followed by the driver writing some number of single, 
consecutive blocks.  Here is what I observed:

    Chunk 16
    Write1 @ $08268200
        <snip>          <==  62 others
    Write1 @ $08270000

    Chunk 17
    Write1 @ $08270200
        <snip>          <== 924 others
    Write1 @ $082E3C00
    Chunk 18
        <snip>          <== 13 other chunks here
    Chunk 32
    Write1 @ $082E3E00
        <snip>          <== 30 others
    Write1 @ $082E7C00

    Read1 @ $00060200   <== What is this for?

    Done writing        <== Message from application indicating
                            last write() has returned
    Unmounting SD card  <== Here is the call to unmount the card

Now, it gets interesting: first, there are 64 block writes, followed by 
2 writes that do not appear to be part of the file, followed by 926 more 

    Write1 @ $082E7E00
        <snip>          <== 62 others
    Write1 @ $082EFC00

    Write1 @ $00023600  <== What are these...
    Write1 @ $00041C00  <== two writes for?

    Write1 @ $082EFE00
        <snip>          <== 924 others
    Write1 @ $08363800

    Done!               <== unmount() donw

    Tests done - reboot now  <== Application enters infinite loop here

Now, the application simple idles, but there are five more writes:

    Write1 @ $00060200  <== Directory update?
    Write1 @ $08363A00  <== Final four blocks of file!
    Write1 @ $08363C00
    Write1 @ $08363E00
    Write1 @ $08364000

Note that all the "Write1" messages with addresses 0x08XXXXXX add up to 
2048 blocks of 512 bytes, or the expected 1 megabyte.

Notice that the last five writes occur after the unmount() call returns, 
which is a bit scary - I would have thought that it would be save to 
shutdown immediately after it returned.

Other than those two writes in the middle to locations I don't 
understand, this seems to make sense.  It also means that, if it really 
is true that pre-erased blocks write more quickly without software 
assistance, then preparing a card by erasing first will help 
applications like mine!

Hope I haven't bored you all too much on this!

More information about the users mailing list