Running out of stack space

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Lele
Active Member
Posts: 52
Joined: Mon Oct 31, 2011 4:08 pm

Post by Lele »

I published the SD module some time ago and actually re-compiling it now I'm getting some issue:
1) in SDCardHost4bit.c line 364
DRESULT disk_write(BYTE IfNum, BYTE buff[],DWORD sector, BYTE count)
must be replaced with
DRESULT disk_write(BYTE IfNum, const BYTE buff[], DWORD sector, BYTE count)

2) in SDCardHost4bit.c line 373
if(SendCmd(IfNum, 25, SDif[IfNum].Ccs ? sector : 512 * sector, R1, -count, buff, Resp)) return RES_ERROR; // multiblock write
must be replaced with
if(SendCmd(IfNum, 25, SDif[IfNum].Ccs ? sector : 512 * sector, R1, -count, (buff, BYTE[]), Resp)) return RES_ERROR; // multiblock write

3) in SDCardHost4bit.c line 377
if(SendCmd(IfNum, 24, SDif[IfNum].Ccs ? sector : 512 * sector, R1, -1, buff, Resp)) return RES_ERROR; // single block write
must be replaced with
if(SendCmd(IfNum, 24, SDif[IfNum].Ccs ? sector : 512 * sector, R1, -1, (buff, BYTE[]), Resp)) return RES_ERROR; // single block write

4) when compiling in debug mode the test buffer in sdcard_test.c:
BYTE Buff[512*50];
should be reduced to
BYTE Buff[512*40];
this buffer was made so big just for performance testing. In real application you should read/write the files in smaller chunks to avoid such waste of memory

There is also another pending issue if you run the program in a processor other than XS1-G:
there are 4 calls to set_port_pull_up function that is not supported by XS1-L devices and will cause a runtime exception.
In SDCardHost4bit.c I think that you can remove the 2 occurences of set_port_pull_up at line 294 and 295.
The occurrence at line 100 replaced with a dummy read like this:
SDif[IfNum].Cmd :> void; (but probably can be just deleted)
in a similar way replace line 254 with
SDif[IfNum].Dat:> void;
and, of course, you must put external pull-up resistor (about 2K should be fine) for Cmd pin and at least D0 pin


User avatar
jb007
Active Member
Posts: 33
Joined: Fri Jul 23, 2010 5:10 am

Post by jb007 »

Thanks Lele and others for your feedback/changes. I't now compiles OK. I'll get a chance to see if it access the SDCard OK later today after work.

Thanks for your help everyone.

Jim
User avatar
jb007
Active Member
Posts: 33
Joined: Fri Jul 23, 2010 5:10 am

Post by jb007 »

jb007 wrote:Thanks Lele and others for your feedback/changes. I't now compiles OK. I'll get a chance to see if it access the SDCard OK later today after work.

Thanks for your help everyone.

Jim
Couldn't wait for after work (I'm in Melbourne, Australia and I work shift work in case your wondering why the funny times), so quickly soldered up a SD adapter to the XC-1A.

It works!

Code: Select all

3904096 KB total drive space.
3906560 KB available.

Deleting file Data.bin if existing...done.

Creating a new file Data.bin...done.

Writing data to the file...20480 bytes written. Write rate: 623KBytes/Sec

Closing the file...done.

Opening an existing file: Data.bin...done.

Reading file content...20480 bytes read. Read rate: 967KBytes/Sec

Closing the file...done.

Open root directory.

Directory listing...
    4096  _~1.TRA
   20480  DATA.BIN
   <dir>  TRASHE~1
   <dir>  FSEVEN~1
   <dir>  SPOTLI~1

Test completed.
Now I wonder what I could do to improve the speed.

Thanks Lele for your code!

Jim
User avatar
Lele
Active Member
Posts: 52
Joined: Mon Oct 31, 2011 4:08 pm

Post by Lele »

Speed is influenced by card type and formatting parameter and compiler option.
For example I run the code in release mode (i.e. optimization -O3) using an SDHC 4GB class4 (by Emtec).
I keep the "set_port_pull_up" as is in the code because I'm using an XC-1A board (but shouldn't change speed if you use external pull-up).
The card formatted FAT32 with 64K allocation unit. That is what I get:

Code: Select all

3933120 KB total drive space.
3933184 KB available.

Deleting file Data.bin if existing...deleted.

Creating a new file Data.bin...done.

Writing data to the file...20480 bytes written. Write rate: 1428KBytes/Sec

Closing the file...done.

Opening an existing file: Data.bin...done.

Reading file content...20480 bytes read. Read rate: 3625KBytes/Sec

Closing the file...done.

Open root directory.

Directory listing...
   20480  DATA.BIN

Test completed.
--Formatting with FAT32 4K allocation unit is slower (because more fragmentation for the file system to manage):

Code: Select all

3929064 KB total drive space.
3929088 KB available.

Deleting file Data.bin if existing...deleted.

Creating a new file Data.bin...done.

Writing data to the file...20480 bytes written. Write rate: 758KBytes/Sec

Closing the file...done.

Opening an existing file: Data.bin...done.

Reading file content...20480 bytes read. Read rate: 2679KBytes/Sec

Closing the file...done.

Open root directory.

Directory listing...
   20480  DATA.BIN

Test completed.
For best performances you can get rid of filesystem; you need to initialize the card once with disk_initialize function
then use direct call to disk_read and disk_write to read/write data buffer multiple of 512bytes thus using the SD like a flash memory.
You will save a lot of ram too.
User avatar
jb007
Active Member
Posts: 33
Joined: Fri Jul 23, 2010 5:10 am

Post by jb007 »

Lele, thanks again for your input. I'll do some more testing in the next few days.
In your experience, do you think it's possible on a XC-1A to reach a write speed of 6-7MB/sec using the raw mode and 64KB sector size on a Core 10 SD card etc?

TIA Jim.
User avatar
Lele
Active Member
Posts: 52
Joined: Mon Oct 31, 2011 4:08 pm

Post by Lele »

Hi Jim,
I had some spare time and finally updated the sd module in the github with the fix told in my previous post.
As far as speed I'm going to do a try. At moment I'm afraid that it won't go faster than 4MBytes/sec.
There is some optimization to do in the code, may be with some assembly here and there.... but I'm not experienced with it.

Lele
User avatar
jb007
Active Member
Posts: 33
Joined: Fri Jul 23, 2010 5:10 am

Post by jb007 »

Hi Lele. Was that 4MB/sec writing using FAT or raw? Is the limitation in speed anything to do with the speed that the SD card clock is going at? I'll try the same when I get my weekend; I'm working shift, so my weekend starts on Monday!

TIA Jim.
User avatar
Lele
Active Member
Posts: 52
Joined: Mon Oct 31, 2011 4:08 pm

Post by Lele »

Hi Jim, I used this code to do the raw access test:

Code: Select all

#include <stdio.h> /* for the printf function */
#include "timing.h"
#include "diskio.h"

#define NUM_BLOCK 40
BYTE Buff[512*NUM_BLOCK]; /* File read buffer (40 SD card blocks) */

extern DRESULT disk_write(BYTE IfNum, const BYTE buff[],DWORD sector, BYTE count);
extern DRESULT disk_read(BYTE IfNum, BYTE buff[], DWORD sector, BYTE count);
extern DSTATUS disk_initialize(BYTE IfNum);

int main(void)
{
  unsigned int T, i;
  DRESULT R1;

  for( i = 0; i < sizeof(Buff); i++) Buff[i] = i + i / 512; // fill the buffer with some data

  R1 = disk_initialize(0); // initialize interface 0
  if(R1 != RES_OK) printf("Init Failed\n");

  /* raw access write speed test */
  T = get_time();
  disk_write(0, Buff, 10, NUM_BLOCK); // write NUM_BLOCK blocks (512bytes each) to interface 0 starting from block 10
  T = get_time() - T;
  printf("%d bytes written. Write rate: %dKBytes/Sec\n", sizeof(Buff), (sizeof(Buff)*100000)/T);

  /* raw access read speed test */
  T = get_time();
  disk_read(0, Buff, 10, NUM_BLOCK); // read NUM_BLOCK blocks (512bytes each) from interface 0 starting from block 10
  T = get_time() - T;
  printf("%d bytes read. Read rate: %dKBytes/Sec\n", sizeof(Buff), (sizeof(Buff)*100000)/T);
  
  return 0;
}
and got :

20480 bytes written. Write rate: 1916KBytes/Sec
20480 bytes read. Read rate: 3834KBytes/Sec

Consider that the same card used in a PC with a card reader has a sustained write speed of 5MBytes/Sec so I think this is the limit for the card.
Bottleneck for writing is the busy indication that is returned by the card at the end of each block transfer (the time that the card need to manage the block mapping, erasing and programming the data in the flash). During that time one could prepare the data for next block to write; the 4 interleaved CRCs require a lot of computation but at moment they are evaluated while sending data.
In read operation CRC is ignored, that is why write speed is half of read speed.

Lele
jagspaul
Experienced Member
Posts: 117
Joined: Tue Oct 18, 2011 3:28 pm

Post by jagspaul »

Lele,

See me & TIA Jim both getting less then 1MByte/sec reading speed where as you are getting 4 times more. Can you figure out what wrong we are doing.

Using raw sector read write (using your code) I am getting following result
20480 bytes written. Write rate: 723KBytes/Sec
20480 bytes read. Read rate: 942KBytes/Sec
Please note that I am using 2GB Micro SD and on my PC I am getting 8.5 MByte/sec reading speed & 3.5 MByte/sec writing speed.

jags