More SD Card issues

Robert S. Grimes rsg at
Wed Oct 15 23:44:12 UTC 2008

The SD card driver seems to be working pretty well.  A simple test where 
I write one megabyte of data in 256 byte chunks takes about 57 seconds, 
for ~18.5 kilobytes/second to disk  This seems pretty reasonable, as the 
data sheet says the "Block Write Access Time" for "Binary Products" is 
24 milliseconds typical, 250 milliseconds max; using the 24 ms for 512 
byte blocks, which translates to 21,333 kilobytes per second.  Seem right?

Does anyone know what "Binary Products" means?

One thing is a little disconcerting: while writing the megabyte, I get 
tons of printk() output from the driver.  My first response was to 
disable #define DEBUG, but I then I still get a bunch of "real" errors.  
However, if I wrote less data, the number of errors would decrease 
proportionately; without the printk() overload, I noticed everything 
actually got written properly. So I thought the driver was recovering 
from the errors, so I eventually tried this near the top of spi-sd-card.c:

    #define QUIET_ERRORS

    //#define DEBUG
    #include <rtems/status-checks.h>

    #ifdef QUIET_ERRORS
    # undef SYSLOG_PRINT
    # define SYSLOG_PRINT( fmt, ...)

This cleaned up the output, and then I was able to measure the 
aforementioned throughput.  This was the state at the end of last week.

Today, however, I wondered about how many errors were occurring, and 
where.  So I added some instrumentation, and found I was getting 200-400 
errors per megabyte.  After a while, I've narrowed it down to the 
function sd_card_send_command(), and specifically to the code that 
checks the response.  I added some printk here, like this:

    ++r) {
      DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, e->response [r]);
      e->response_index = r;
      if (SD_CARD_IS_RESPONSE( e->response [r])) {
        if (SD_CARD_IS_ERRORLESS_RESPONSE( e->response [r])) {
          return 0;
        } else {
          SYSLOG_ERROR( "Command error [%02i]: 0x%02" PRIx8 "\n", r,
    e->response [r]);
          printk("CmdErr(0x%02x, 0x%x) [%02i]: 0x%02" PRIx8 "\n",
    command, argument,
                         r, e->response [r]);
          goto sd_card_send_command_error;
      } else if (e->response [r] != SD_CARD_IDLE_TOKEN) {
        SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r,
    e->response [r]);
        goto sd_card_send_command_error;
      . . .

Some of the output looks like this:

    CmdErr(0x0D, 0x0) [07]: 0x6C
    CmdErr(0x18, 0x9C800) [07]: 0x21
    CmdErr(0x11, 0xA7800) [07]: 0x6F
    CmdErr(0x11, 0xA7A00) [07]: 0x20
    CmdErr(0x11, 0xA7C00) [07]: 0x6F
    CmdErr(0x11, 0xA7E00) [07]: 0x6C
    CmdErr(0x11, 0xA8000) [07]: 0x21
    CmdErr(0x18, 0x9DC00) [07]: 0x21
    CmdErr(0x0D, 0x0) [07]: 0x48
    CmdErr(0x18, 0x9DE00) [07]: 0x6C
    CmdErr(0x0D, 0x0) [07]: 0x6F
    CmdErr(0x18, 0x9E000) [07]: 0x20
    CmdErr(0x0D, 0x0) [07]: 0x6F
    CmdErr(0x18, 0x9E200) [07]: 0x6C
    CmdErr(0x0D, 0x0) [07]: 0x21
    CmdErr(0x18, 0x9E400) [07]: 0x21
    CmdErr(0x0D, 0x0) [07]: 0x48
    CmdErr(0x18, 0x9E600) [07]: 0x6C
    CmdErr(0x0D, 0x0) [07]: 0x6F
    CmdErr(0x18, 0x9E800) [07]: 0x20
    CmdErr(0x0D, 0x0) [07]: 0x6F
    CmdErr(0x18, 0x9EA00) [07]: 0x6C
    CmdErr(0x0D, 0x0) [07]: 0x21

commands, but it seems the driver recovers from them.  Nice.  But the 
question is: should I worry?

Is the byte being reported after the "[07]:" an error code?

I don't believe the driver is using CRC - is that right?   Should it be?

Signals look pretty good, though I can't rule out noise right now - my 
setup is a bit of a kludge.

Any ideas, or is this normal?


More information about the users mailing list