first

Dependencies:   SDFileSystemDMA mbed

Refer to:
https://developer.mbed.org/users/mimi3/code/SDFileSystemDMA

Caution

If your board has SRAM less than or equal to 8KB, the 'buffer' size must be set to 512 Bytes.

NUCLEO-F411RE
About 2.5MBytes/sec
/media/uploads/mimi3/sdfilesystemdma-speed-test-teraterm-output-f411re.png
NUCLEO-L152RE
About 1MBytes/sec
/media/uploads/mimi3/sdfilesystemdma-l152re-cui.png

main.cpp

Committer:
dinau
Date:
2016-09-03
Revision:
24:bea03d091636
Parent:
22:5c133291a01d
Child:
25:1e42edbeacca

File content as of revision 24:bea03d091636:

#include "mbed.h"
#include "SDFileSystemDMA.h"

/* SD card Interface connection
 *           :  aitendo   :  General
 *  MCU sig. : IFB-254-SD :  PIN name
     ---     :    1       :   9 dat2
       CS    :    2       :   1 cs/dat3
      MOSI   :    3       :   2 di/cmd
       GND   :    4       :   3 vss1
       VCC   :    5       :   4 vdd
       CLK   :    6       :   5 clk
       GND   :    7       :   6 vss2
      MISO   :    8       :   7 do/dat0
       ---   :    9       :   8 dat1
       ---   :   10       :  11 wp
       ---   :   11       :  10 cd1
       ---   :   12       :  - case GND
*/
/* SD card pin
Pin side
--------------\
        9     = \    DAT2/NC
            1 ===|   CS/DAT3    [CS]
            2 ===|   CMD/DI     [DI]
            3 ===|   VSS1
Bottom      4 ===|   VDD
View        5 ===|   CLK        [CLK]
            6 ===|   VSS2
            7 ===|   DO/DAT0    [DO]
            8   =|   DAT1/IRQ
-----------------

                                        Arduino      NUCLEO-F411       NUCLEO-F030R8
Logo side
-----------------
            8   =|   DAT1/IRQ
            7 ===|   DO/DAT0    [DO]     D12           D12/PA_6           D5/PB_4
            6 ===|   VSS2
Top         5 ===|   CLK        [CLK]    D13           D13/PA_5           D3/PB_3
View        4 ===|   VDD
            3 ===|   VSS1
            2 ===|   CMD/DI     [DI]     D11           D11/PA_7           D4/PB_5
            1 ===|   CS/DAT3    [CS]     D8            D10/PB_6           D10/PB_6
        9     = /    DAT2/NC
--------------/
*/


/* You should confirm SPI_DEV macro in "spi_device.h" to specify SPI device number.
 * (default is 1 (SPI1))
 */
#include "spi_device.h"
#define UART_KEY_PRESS  1

#define SPI_CLOCK_HZ    ( 12 * 1000000 ) 

Timer timer;
//Serial pc(PA_9,PA_10);
Serial pc(USBTX,USBRX); /* Baudrate is 9600bps*/

SDFileSystem sd( MOSI, MISO, SCLK, CS, "sd", SPI_CLOCK_HZ);  

//char buffer[512*1]  __attribute__ ((aligned (4))) ;    /*   512 bytes */
//char buffer[512*2]  __attribute__ ((aligned (4))) ;    /*  1024 bytes */
char buffer[512*4]  __attribute__ ((aligned (4))) ;      /*  2048 bytes */
//char buffer[512*8]  __attribute__ ((aligned (4))) ;    /*  4096 bytes */
//char buffer[512*16] __attribute__ ((aligned (4))) ;    /*  8192 bytes */
//char buffer[512*32] __attribute__ ((aligned (4))) ;    /* 16384 bytes */

#define X_MEGA_BYTE     ((1)*1024*1024) /* 1Mbyte */
#define FILE_NAME   "GPATH"

#if defined(__CC_ARM)     /* ARMCC      */ 
#define TOOLCHAIN   "ARM/uARM"
#elif defined(__GNUC__)       /* GCC        */ 
#define TOOLCHAIN   "GCC_ARM"
#elif defined(__ICCARM__)   /* IAR        */
#define TOOLCHAIN   "IAR"
#else
#define TOOLCHAIN   "Unknown"
#warning "This compiler is not yet supported."
#endif

int wait_key_press(){
#if UART_KEY_PRESS
	while(!pc.readable());
	return  pc.getc();
#endif
}

void writeTest()
{
#if !_FS_READONLY
	//Test write performance by creating a 1MB file
	pc.printf("[Write]: Testing %d bytes buffer: write performance...", sizeof(buffer));
	fflush(stdout); 
	for(uint32_t k = 0; k < sizeof(buffer); k++){
		buffer[k] = k & 0xff;
	}

	FileHandle* file = sd.open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC);
	if (file != NULL) {
		timer.start();
		for (uint32_t i = 0; i < (X_MEGA_BYTE / sizeof(buffer)); i++) {
			if (file->write(buffer, sizeof(buffer)) != sizeof(buffer)) {
				timer.stop();
				pc.printf("write error!\n");
				timer.reset();
				return;
			}
		}
		timer.stop();
		if (file->close())
			pc.printf("failed to close file!\n");
		else{
			pc.printf("done!\n\tResult: %d KB/s\n", (  1024 * 1000000 ) / timer.read_us() );
		}
		timer.reset();
	} else {
		pc.printf("failed to create file!\n");
	}
#endif
}

void readTest()
{
	//Test read performance by reading the 1MB file created by writeTest()
	pc.printf("[Read]: Testing %d bytes buffer: read performance...", sizeof(buffer));
	fflush(stdout); 
	FileHandle* file = sd.open(FILE_NAME, O_RDONLY);
	if (file != NULL) {
		timer.start();
		int iterations = 0;
		while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)){
			iterations++;
		}
		timer.stop();
		if (iterations != (X_MEGA_BYTE / sizeof(buffer))){
			pc.printf("read error!\n");
		}
		else if (file->close()){
			pc.printf("failed to close file!\n");
		}
		else{
			pc.printf("done!\n\tResult: %d KB/s\n",  (  1024 * 1000000 ) / timer.read_us());
		}
		timer.reset();
	} else {
		pc.printf("failed to open file!\n");
	}
}

void verifyTest()
{
	int errorCount = 0;
	//Test read performance by reading the 1MB file created by writeTest()
	pc.printf("[Read]: Verifying %d bytes buffer ...", sizeof(buffer));
	fflush(stdout); 
	FileHandle* file = sd.open(FILE_NAME, O_RDONLY);
	if (file != NULL) {
		timer.start();
		int iterations = 0;
		while (file->read(buffer, sizeof(buffer)) == sizeof(buffer)){
			iterations++;
			for(uint32_t k = 0; k < sizeof(buffer); k++){
				if ( buffer[k] != (k & 0xff) ){
					errorCount++;    
				}
			}
		}
		timer.stop();
		if (iterations != (X_MEGA_BYTE / sizeof(buffer))){
			pc.printf("read error!\n");
		}
		else if (file->close()){
			pc.printf("failed to close file!\n");
		}
		else{
			//    pc.printf("done!\n\tResult: %d KB/s\n",  (  1024 * 1000000 ) / timer.read_us());

		}
		timer.reset();
	} else {
		pc.printf("failed to open file!\n");
	}
	pc.printf("\n     Error Count : %d", errorCount);
}


int main(){
    int i = 1;
	while(1){
		pc.printf("\n(%2d)------- SDFileSystemDMA --------------------------------",i++);
		pc.printf("\nR/W Buffer size         = %8d Bytes", sizeof(buffer) );
		pc.printf("\nSystemClock             = %d Hz",SystemCoreClock);
		pc.printf("\nSPI(%d),  Max SPI Clock  = %d Hz",SPI_DEV,SystemCoreClock>>1);
		pc.printf("\nCompiler: %s", TOOLCHAIN);
		pc.printf("\nmbed-lib: Rev.%d", MBED_LIBRARY_VERSION);
		pc.printf("\n\nStart SD card accsess test !");
		pc.printf("\n[r]: Start Read Test. At least execute [w] onece");
		pc.printf("\n[w]: Start Write and Read Test");
		pc.printf("\n[v]: Start Read Verify Test. At least execute [w] onece");
		pc.printf("\nWriting is very slow, wait tens of seconds."); 
		pc.printf("\n--- Select [r] or [w] or [v]---\n");  
		fflush(stdout); 
		char ch = wait_key_press();
		if( ch =='r' ){
			readTest();
		} else if( ch =='w' ){
			writeTest();
			readTest();
		} else if( ch =='v' ){
			verifyTest();
		}
        else{
            continue;
        }
		pc.printf("\n--- Press any key ---\n");  
		fflush(stdout); 
		wait_key_press();
	}
}