diff -r 000000000000 -r a41df078684a kerneltest/e32test/pccd/t_nandbm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/pccd/t_nandbm.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,280 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\pccd\t_nandbm.cpp +// Test read/write performance for NAND drives accessed directly +// through the Local Media Sub-System +// When no command parameter is supplied search for first +// writeable NAND drive that can be found +// If a drive number parameter in the range 0 - F is provided, +// interpret this as a local drive number in the range 0 - 15 +// and test the drive if it is a writeable NAND drive +// Please note that local drive numbers at the Local Media Sub-System +// level are not the same as drive numbers / drive letters at the +// File Server level. File Server drive numbers / drive letters fall +// in the range 0 - 25 / a - z. The mapping between local drive numbers +// and File Server drive numbers / drive letters is defined in +// estart.txt or its equivalent +// Use TBusLocalDrive directly and bypass the File Server +// Fill NAND user data drive with data prior to executing actual +// performance tests. TBusLocalDrive should read from areas that have +// been written to and are therefore assigned. Where areas are +// unassigned, XSR FTL returns FFs without accessing the NAND flash +// hardware. This type of behaviour generates misleadingly quick +// performance figures +// Test various block sizes in the range 16 - 65536 bytes +// +// + + +#include +#include +#include +#include +#include + + +LOCAL_D TBuf<1048576> DataBuf; +LOCAL_D TBusLocalDrive TheDrive; +LOCAL_D TBool ChangedFlag; +LOCAL_D RFs TheFs; + +RTest test(_L("Local NAND Drive BenchMark Test")); + +LOCAL_C void DoRead(TInt aReadBlockSize) +// +// Do Read benchmark +// + { + TInt msgHandle = KLocalMessageHandle; + TLocalDriveCapsV2 info; + TPckg infoPckg(info); + TInt maxSize; + TheDrive.Caps(infoPckg); + maxSize=I64LOW(info.iSize); + TInt count,pos,err; + count=pos=err=0; + + RTimer timer; + timer.CreateLocal(); + TRequestStatus reqStat; + timer.After(reqStat,10000000); // After 10 secs + while(reqStat==KRequestPending) + { + if (TheDrive.Read(pos,aReadBlockSize,&DataBuf,msgHandle,0)==KErrNone) + count++; + else + err++; + pos+=aReadBlockSize; + if (pos>=(maxSize-aReadBlockSize)) + pos=0; + } +#if defined (__WINS__) + test.Printf(_L("Read %d %d byte blocks in 10 secs\n"),count,aReadBlockSize); +#else + TBuf<60> buf; + TReal32 rate=((TReal32)(count*aReadBlockSize))/10240.0F; + TRealFormat rf(10,2); + buf.Format(_L("Read %d %d byte blocks in 10 secs ("),count,aReadBlockSize); + buf.AppendNum(rate,rf); + buf.Append(_L("Kb/s)\n")); + test.Printf(buf); +#endif + test.Printf(_L("Errors:%d\n"),err); + } + +LOCAL_C void DoWrite(TInt aWriteBlockSize) +// +// Do write benchmark +// + { + TInt msgHandle = KLocalMessageHandle; + TLocalDriveCapsV2 info; + TPckg infoPckg(info); + TInt maxSize; + TheDrive.Caps(infoPckg); + maxSize=I64LOW(info.iSize); + TInt count,pos,err; + count=pos=err=0; + + RTimer timer; + timer.CreateLocal(); + TRequestStatus reqStat; + timer.After(reqStat,10000000); // After 10 secs + while(reqStat==KRequestPending) + { + if (TheDrive.Write(pos,aWriteBlockSize,&DataBuf,msgHandle,0)==KErrNone) + count++; + else + err++; + pos+=aWriteBlockSize; + if (pos>=(maxSize-aWriteBlockSize)) + pos=0; + } +#if defined (__WINS__) + test.Printf(_L("Write %d %d byte blocks in 10 secs\n"),count,aWriteBlockSize); +#else + TBuf<60> buf; + TReal32 rate=((TReal32)(count*aWriteBlockSize))/10240.0F; + TRealFormat rf(10,2); + buf.Format(_L("Write %d %d byte blocks in 10 secs ("),count,aWriteBlockSize); + buf.AppendNum(rate,rf); + buf.Append(_L("Kb/s)\n")); + test.Printf(buf); +#endif + test.Printf(_L("Errors:%d\n"),err); + } + +GLDEF_C TInt E32Main() + { + test.Title(); + + TBuf<0x100> cmd; + User::CommandLine(cmd); // put command line into decriptor + TLex lex(cmd); + TPtrC param=lex.NextToken(); // point token at local drive number if any + test.Printf(_L("Local Drive = %S\r\n"),¶m); + + TChar localDrv; + TInt localDrvNum; + TBusLocalDrive drive; + TBool changeFlag; + TLocalDriveCapsV4 driveCaps; + TPckg capsPckg(driveCaps); + TInt r; + + if (param.Length()==0) + { + // locate writeable NAND drive + for (localDrvNum=0; localDrvNum='0'&&localDrv<='9') + { + localDrvNum=((TInt)localDrv-'0'); + } + else if (localDrv>='A'&&localDrv<='F') + { + localDrvNum=((TInt)localDrv-'A'+10); + } + else + { + test.Printf(_L("Commandline %S invalid\r\n"), &cmd); + test.Printf(_L("Usage:\r\n")); + test.Printf(_L("t_nandbm with no arguments, test first suitable NAND drive \r\n")); + test.Printf(_L("t_nandbm x, where x = 0-F test local drive number 0-15\r\n")); + return(KErrGeneral); + } + // is selected drive suitable for test + r = drive.Connect(localDrvNum,changeFlag); + if(r!=KErrNone) + { + test.Printf(_L("Can't connect to drive %d\r\n"), localDrvNum); + return(KErrGeneral); + } + r = drive.Caps(capsPckg); + if(r!=KErrNone) + { + test.Printf(_L("Drive %d caps method error\r\n"), localDrvNum); + return(KErrGeneral); + } + drive.Disconnect(); + if ((driveCaps.iType!=EMediaNANDFlash) + ||(driveCaps.iMediaAtt&KMediaAttWriteProtected) + ||(driveCaps.iPartitionType==KPartitionTypeSymbianCrashLog)) + { + test.Printf(_L("Drive %d has unsuitable capabilities\r\n"), localDrvNum); + test.Printf(_L("Writeable NAND drive required for test\r\n")); + return(KErrGeneral); + } + + } + + // Fill the nand user data drive with data so TBusLocalDrive reads + // from areas that have been written to and are therefore assigned. + // Where areas are unassigned, XSR FTL returns FFs without accessing + // the NAND flash hardware. This type of behaviour generates misleadingly + // quick performance figures. + TInt writesize=1048576; + TInt pos = 0; + TInt msgHandle = KLocalMessageHandle; + + TheDrive.Connect(localDrvNum,ChangedFlag); + test.Printf( _L("Fill up NAND drive %d\r\n"),localDrvNum); + while(writesize>=1) + { + test.Printf( _L("%d byte write to pos %d of NAND drive\r\n"),writesize,pos); + if (TheDrive.Write(pos,writesize,&DataBuf,msgHandle,0)!=KErrNone) + { + writesize/=16; + } + else + { + pos += writesize; + } + } + + test.Start(_L("Start Benchmarking ...")); + + DoRead(16); + DoRead(256); + DoRead(512); + DoRead(513); + DoRead(2048); + DoRead(4096); + DoRead(16384); + DoRead(32768); + DoRead(65536); + + DoWrite(16); + DoWrite(256); + DoWrite(512); + DoWrite(513); + DoWrite(2048); + DoWrite(4096); + DoWrite(16384); + DoWrite(32768); + DoWrite(65536); + + test.End(); + + TheFs.Close(); + + return(KErrNone); + } +