SD Shell_write_test hangs on 512 byte

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SD Shell_write_test hangs on 512 byte

1,289 Views
pbanta
Contributor IV

Has anyone used the Shell_write_test command with an SD card or eMMC?  In both cases I see problems when writing a 512 byte buffer.  512 bytes happens to be the sector size.  The DLA bit in PRSSTAT is not clearing.  I named the command "writetest" in my shell.

shell> writetest test

Test Iteration #8 Passed

Test Iteration #16 Passed

Test Iteration #32 Passed

Test Iteration #64 Passed

Test Iteration #128 Passed

Test Iteration #256 Passed

Test Iteration #512 Error, unable to open file to read

shell>

Labels (1)
Tags (5)
0 Kudos
Reply
5 Replies

872 Views
RadekS
NXP Employee
NXP Employee

It seems that you found already known issue.

I suppose that you use append mode.

Unfortunately, append mode is implemented wrongly.

Problem with append mode appears when file size is multiply of cluster size. See also:

https://community.freescale.com/message/441854

As workaround, please use r+/w/w+ modes instead of append mode and seeks manually according your needs.

Next MQX release will contain complete redesigned MFS subsystem which will solve this issue.

I hope it helps you.


Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

872 Views
pbanta
Contributor IV

Thanks for the prompt reply.

I took a look at the source code for Shell_write_test and it opens file in "w" mode.  The bug may not be only with append mode.

Paul

0 Kudos
Reply

872 Views
pbanta
Contributor IV

I have done more investigation on this issue.  It looks like the problem is in the sdcard/esdhc drivers.  The problem happens on the first write to a new file.  The buffer to write is 512 bytes.  It is 1 block in the SD card.  The driver issues a CMD24.  In _esdhc_write() when the buffered CMD24 is finally sent to the device there is an ESDHC_LWEVENT_TRANSFER_ERROR.  In the code below from _esdhc_write(),  should line 5 be >= ?

if(_lwevent_get_signalled() & ESDHC_LWEVENT_TRANSFER_ERROR)

{

  esdhc_ptr->SYSCTL |= SDHC_SYSCTL_RSTD_MASK;

  if(esdhc_device_ptr->BUFFERED_CMD.BLOCKS > 1)

  {

    /* In this case the peripheral doesn't automatically send the CMD12, so MUST be sent manually */

    ESDHC_COMMAND_STRUCT command;

    command.COMMAND = ESDHC_CREATE_CMD(12, ESDHC_COMMAND_TYPE_NORMAL, ESDHC_COMMAND_RESPONSE_R1b, (ESDHC_COMMAND_NONE_FLAG));

    command.ARGUMENT = 0;

    command.BLOCKS = 0;

    _esdhc_send_command(esdhc_device_ptr, &command, NULL);

    /* Don't care about the result because the operation ends always by IO_ERROR. */

  }

  return IO_ERROR;

}

Paul

0 Kudos
Reply

872 Views
RadekS
NXP Employee
NXP Employee

Thank you for your bug report.

I could confirm that writetest function has problem with write more than 511 bytes (511 works, 512 and more not work).

It has nothing to do with FAT sector size. The problem is the same even when sector size is 8196bytes.

It must be probably somehow connected to SD card block size.

Strange is that standard write function (Shell_write) doesn’t suffer by this issue. Till now I didn’t found root cause of this issue. I will report it.

Note: Your modification in esdhc.c file didn't help

0 Kudos
Reply

872 Views
pbanta
Contributor IV

Hi Radek,


Thank you for doing more investigation.  I have new information to report today.  I set a breakpoint in the _edshc_isr() function and I'm getting a DMA error when I try to write a single buffer of 512bytes.  (See line 12 in code below.) 512 is the sector size of the device. It doesn't matter if the device is microSD or eMMC. (I have a board with microSD and another board with eMMC.)  That tells me it's a K70 issue.

  /*

      DMA Error

    Occurs when an Internal DMA transfer has failed. This bit is set to 1, when some error occurs in the data

    transfer. This error can be caused by either Simple DMA or ADMA, depending on which DMA is in use.

    The value in DMA System Address register is the next fetch address where the error occurs. Since any

    error corrupts the whole data block, the host driver shall re-start the transfer from the corrupted block

    boundary. The address of the block boundary can be calculated either from the current DSADDR value or

    from the remaining number of blocks and the block size.

  */

  if((esdhc_ptr->IRQSIGEN & SDHC_IRQSIGEN_DMAEIEN_MASK) && (sdhc_irqstat & SDHC_IRQSTAT_DMAE_MASK))

  {

    _lwevent_set( &esdhc_device_ptr->LWEVENT, ESDHC_LWEVENT_TRANSFER_ERROR);

  }

Thanks,

Paul

0 Kudos
Reply