I am currently experimenting with the mmcsd_fatfs example in the biospsp_03_00_01_00 release. I've gotten the project to run correctly and I can see files show up on my SD Card, however the time to write files seems extraordinarily long. I am using a SanDisk Ultra 64GB microSDXC Class 10 UHS-1 which the vendor claims should be capable of 40MB/s (I know it's hard to achieve this) but using the project in the psp folder I'm seeing more like 300KB/s.
I've increased the write sectors to 500 which in the example program increases the buffer size to 256000 bytes. This buffer is then directly passed to the fwrite call.
What am I missing? I'm assuming that the psp driver using the FatFs can go faster and hopefully it's just a configuration setting that I'm missing.
Any help would be appreciated.
Thanks
David
Here's the code I modified in the mmcsd_fatfs project:
/*
* mmcsdSample_io.c
*
* This sample application, is a representative test program. This application
* tests MMCSD driver on Bios 6.
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/** \file mmcsdSample_io.c
*
* \brief Demo fatfs application for the MMCSD driver
*
* This sample application, is a representative test program.
* This application test MMCSD driver on Bios.
*
* (C) Copyright 2010, Texas Instruments, Inc
*
*/
#include <xdc/std.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/io/iom.h>
#include <ti/sysbios/knl/Semaphore.h>
#include "ti/sysbios/knl/task.h"
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Log.h>
#include <xdc/runtime/Timestamp.h>
#include <xdc/runtime/Types.h>
#include <string.h>
#include <file.h>
#include <stdio.h>
#include <stdlib.h>
#include "platforms/evm6748/Mmcsd_evmInit.h"
#include "mmcsd/include/psp_mmcsd.h"
#include "blkmedia/include/psp_blkdev.h"
#include "ti/sysbios/fatfs/ff.h"
#include "ti/sysbios/fatfs/diskio.h"
#define PSP_MMCSD_SAMPLE_DRIVE 1U
/* This is the driver number associated with MMCSD drive */
#define MMC_INST_ID 0U
/*Instance no of mmcsd */
/*#define NUM_SECTORS 6144U*/
#define NUM_SECTORS 6144U
/*No of Bytes in drive to format */
#define FILESYS_BYTE_COUNT (NUM_SECTORS * 512U)
/*No of sectors read or written */
#define WRITE_SECTORS 500
/* No of bytes to write or read */
#define BYTE_COUNT (WRITE_SECTORS * 512U)
#define INCLUDE_MEDIA_WP_TEST 0
/*This will enable the WP test on the media. */
#define INCLUDE_ACTUAL_CARD_FREQ_IOCTL 0
/*This will actually alter the freq of the card.
Please note that the further operation of the card takes place at this freq*/
#define BUFFER_ALINED_CACHE_LENGTH
/* Enable this if user want to pass cache length aligned buffer, In polled mode
buffer must be 4 byte aligned */
#define DATA_ALIGN 128
#define MMCSD_SAMPLE_PRINT printf
char *filename = "fat:1:sample.txt";
TCHAR *path = "fat:1:sample.txt";
#define READ_BLOCK_SIZE 64
/*
* Global Static references
*/
UInt32 sectorCount = WRITE_SECTORS;
Ptr handle;
PSP_BlkDevOps_t* pDevOps = NULL;
/*
* Note: Buffer alignment is required only when working in DMA Mode.
*/
static UInt8 srcmmcsdBufOrg[BYTE_COUNT + DATA_ALIGN];
/*+128 if need to make unalign for testing purpose*/
static UInt8 dstmmcsdBufOrg[BYTE_COUNT + DATA_ALIGN];
/*+128 if need to make unalign for testing purpose*/
static UInt8 *srcmmcsdBuf = NULL;
static UInt8 *dstmmcsdBuf = NULL;
UInt32 loop = 0;
UInt32 addr = 0;
Void checkMediaCard(UInt32 instanceId);
Void checkMediaCard(UInt32 instanceId)
{
Int32 result = IOM_COMPLETED, flag = 1;
PSP_MmcsdCardType cardType = PSP_MMCSD_CARDTYPE_NONE;
while (flag)
{
result = PSP_mmcsdCheckCard(&cardType, instanceId);
if (IOM_COMPLETED == result)
{
if ((PSP_MMCSD_CARDTYPE_MMC == cardType)
|| (PSP_MMCSD_CARDTYPE_SD == cardType))
{
break;
}
else
{
MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE: Please insert the card\r\n");
Task_sleep(1000U);
}
}
else
{
MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE: checkCard failed\r\n");
}
}
}
/**
* \brief Demonstrates use of PSP drivers.
*/
Void runMmcsdSample()
{
UInt8 *tempSrcMmcsdBuf = NULL;
UInt8 *tempDstMmcsdBuf = NULL;
Int32 retVal = IOM_COMPLETED;
FILE *pFile;
UInt32 readSize = 0, writeSize = 0;
UInt32 cnt = 0, i = 0, loopCnt = 5;
//FIL fileptr;
//FRESULT result;
//BYTE mode = 0;
UInt ts1, ts2;
Types_FreqHz freq;
/* aligning srcmmcsdBuf & dstmmcsdBuf on CACHE line size boundary */
memset(srcmmcsdBufOrg, 0xFF, sizeof(srcmmcsdBufOrg));
memset(dstmmcsdBufOrg, 0xFF, sizeof(dstmmcsdBufOrg));
tempSrcMmcsdBuf = srcmmcsdBufOrg;
tempDstMmcsdBuf = dstmmcsdBufOrg;
/* Align the buffer on the cache line length */
srcmmcsdBuf = (Ptr) ((UInt32) (tempSrcMmcsdBuf + DATA_ALIGN - 1)
& ~(DATA_ALIGN - 1));
dstmmcsdBuf = (Ptr) ((UInt32) (tempDstMmcsdBuf + DATA_ALIGN - 1)
& ~(DATA_ALIGN - 1));
if ((NULL == srcmmcsdBuf) || (NULL == dstmmcsdBuf))
{
MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE:Buffer is NULL\r\n");
}
checkMediaCard(MMC_INST_ID);
MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE:Card is inserted\r\n");
#ifndef BUFFER_ALINED_CACHE_LENGTH
srcmmcsdBuf += 4;
dstmmcsdBuf += 4;
#endif /* BUFFER_ALINED_CACHE_LENGTH */
retVal = PSP_blkmediaFATfsRegister(MMC_INST_ID, PSP_MMCSD_SAMPLE_DRIVE);
if (IOM_COMPLETED == retVal)
{
MMCSD_SAMPLE_PRINT(
" MMCSD_SAMPLE: Media is registered with FATfs \r\n");
}
else
{
MMCSD_SAMPLE_PRINT(
" MMCSD_SAMPLE: Media is registering with FATfs FAILED\r\n");
return;
}
cnt = sectorCount * 512U;
for (i = 0; i < cnt; i++)
{
srcmmcsdBuf[i] = i;
dstmmcsdBuf[i] = 0;
}
MMCSD_SAMPLE_PRINT("MMCSD_SAMPLE: Create Fat format on MMCSD\n");
/* Format the Nand drive */
retVal = f_mkfs(PSP_MMCSD_SAMPLE_DRIVE, 1, FILESYS_BYTE_COUNT);
if (retVal == 0)
{
MMCSD_SAMPLE_PRINT("MMCSD_SAMPLE: create partition successful\n");
}
else
{
MMCSD_SAMPLE_PRINT(
"MMCSD_SAMPLE: partition creation failed errno: %d\n", retVal);
}
/* open the mmcsd file for reading */
pFile = fopen(filename, "w+");
if (NULL == pFile)
{
MMCSD_SAMPLE_PRINT("ERROR: FatFs fxn 'fopen' returned NULL.\n");
return;
}
Timestamp_getFreq(&freq);
ts1 = Timestamp_get32();
writeSize = fwrite(srcmmcsdBuf, 1, cnt, pFile);
ts2 = Timestamp_get32();
System_printf("T1: %u\n"
"T2: %u\n"
"dT: %u\n"
"dT(us): %u\n"
"Freq: %u\n",
ts1,
ts2,
ts2-ts1,
(ts2-ts1) / (freq.lo / 1000000), //delta t in us
freq.lo);
if (cnt != writeSize)
{
MMCSD_SAMPLE_PRINT(
"ERROR: FatFs fxn 'fwrite' returned write size %d.\n",
writeSize);
return;
}
/* seek the file pointer to begining location */
if ((fflush(pFile)) != 0)
{
MMCSD_SAMPLE_PRINT("ERROR: FatFs fxn 'fflush' returned error.\n");
return;
}
// while (loop < loopCnt)
// {
// /* write contents of the file into a buffer */
// writeSize = fwrite(srcmmcsdBuf, 1, cnt, pFile);
// if (cnt != writeSize)
// {
// MMCSD_SAMPLE_PRINT(
// "ERROR: FatFs fxn 'fwrite' returned write size %d.\n",
// writeSize);
// break;
// }
//
// /* seek the file pointer to begining location */
// if ((fflush(pFile)) != 0)
// {
// MMCSD_SAMPLE_PRINT("ERROR: FatFs fxn 'fflush' returned error.\n");
// break;
// }
//
// /* seek the file pointer to begining location */
// if ((fseek(pFile, 0, SEEK_SET)) != 0)
// {
// MMCSD_SAMPLE_PRINT("ERROR: FatFs fxn 'fseek' returned error.\n");
// break;
// }
//
// /* read contents of the file into a buffer */
// readSize = fread(dstmmcsdBuf, 1, cnt, pFile);
// if (cnt != readSize)
// {
// MMCSD_SAMPLE_PRINT(
// "ERROR: FatFs fxn 'fread' returned read size %d.\n",
// readSize);
// break;
// }
//
// /* seek the file pointer to begining location */
// if ((fseek(pFile, 0, SEEK_SET)) != 0)
// {
// MMCSD_SAMPLE_PRINT("ERROR: FatFs fxn 'fseek' returned error.\n");
// break;
// }
//
// for (i = 0; i < cnt; i++)
// {
// if (srcmmcsdBuf[i] != dstmmcsdBuf[i])
// {
// break;
// }
// }
// if (i == cnt)
// {
// MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE: FILE Data write-read"
// " matching passed\r\n");
// }
// else
// {
// MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE: FILE Data write-read matching"
// " failed in loop count %d at i = %d\r\n", loop, i);
// }
// loop++;
// }
if ((fclose(pFile)) != 0)
{
MMCSD_SAMPLE_PRINT("ERROR: FatFs fxn 'fclose' returned error.\n");
}
/*The Media Driver clients like Mass Storage drivers shall use this
function to un-register from a Block media device*/
retVal = PSP_blkmediaFATfsUnregister(PSP_MMCSD_SAMPLE_DRIVE);
if (IOM_COMPLETED == retVal)
{
MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE: Media for remote client is"
" unregsitered\r\n");
}
else
{
MMCSD_SAMPLE_PRINT(" MMCSD_SAMPLE: Media for remote client is"
" not unregsitered\r\n");
}
}
/* ========================================================================== */
/* END OF FILE */
/* ========================================================================== */