diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/kerneltest/e32test/pccd/t_med_writebm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/kerneltest/e32test/pccd/t_med_writebm.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,533 @@ +// Copyright (c) 1996-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_med_writebm.cpp +// +// + +/** + @file +*/ + +#define __E32TEST_EXTENSION__ + +#include +#include +#include + +/* + SD/MMC/other media benchmark test + Writes data to the media and prints out time taken (microseconds). + Works on TBusLocalDrive level. May require a script to filter the results. + + Principle of operation: + In the simple case scenario the user specifies media start and end position in bytes, + write buffer size (window size), the number of write repetitions (optional) and write position increment. + + The test fills buffer with random data, writes it to the media (probably several times); prints out the time taken; + increments or decrements window position; goto begin. Test finishes when the window slides outside specified beginning or end media position. + + It more complex case we have 2 windows. It is useful for FAT emulation. + + ------------------------------------------- + Command line shall look like this: + drv=[0..25] pos=xxx:yyy [wrep=] wn=[1,2] w1sz= w1pi= [w2sz= w2pi=] + + where: + drv=N local drive physical number for 1st MMC slot on H2 & H4 it will be 1, see variantmediadef.h + pos=xxx:yyy xxx start media position, yyy end media position in bytes. The test will be writing data in the range xxx-yyy + wrep=N optional. Specifies how many times the window will be written to the media, just for more precise time calculation. Default is 1. + wn=N Number of data windows being written on the media. can be 1 or 2 + + w1sz=N Size of the data window #1 in bytes. Must be > 0 + w1pi=N Media position increment for the window #1. if positive, the window will be moving from xxx to yyy (see media pos parameter); + if 0, the window won't change its position; if <0, the window will be moving from yyy to xxx + + w2sz the same for the window #2 if it is specified + w2pi the same for the window #2 if it is specified + + The test will finish when one of the windows slides across the media boundaries xxx of yyy. If you specify w1pi=0 or both w1pi=0 w2pi=0 + it may run forever :) + + Be careful, all information on the medium will be lost !!! +*/ + +RTest test(_L("MMC/SD write performance test")); + +TBusLocalDrive BusLocalDrv; +RFs Fs; + +RBuf8 gWriteBuffer1; +RBuf8 gWriteBuffer2; + +TInt gLocalDrvNum = -1; //-- LOCAL physical drive number (see Estart.txt) +TBool gChangeFlag; + +TUint gWindowsNum = 0; //-- number of windows being written + +TUint32 gWriteBufSize1 = 0; //-- write buffer 1 size, bytes +TInt32 gWriteGranularity1 = 0; //-- write granularity 1 (write buffer position increment) + +TUint32 gWriteBufSize2 = 0; //-- write buffer 2 size, bytes +TInt32 gWriteGranularity2 = 0; //-- write granularity 2 (write buffer position increment) + +TInt64 gMediaStartPos = 0; //-- media start position +TInt64 gMediaEndPos = 0; //-- media end position + +TUint gNumWrites = 1; //-- number of buffer writes to the media + + +//--------------------------------------------------------------------------------- + +void RndFillBuf(TDes8& aBuf); + +//--------------------------------------------------------------------------------- + +/** + The main part of the test, actually. Writes 1 or 2 buffers to the media (possibly several times) and + prints out the time taken. +*/ +void DoWriteBMTest(void) +{ + test.Next(_L("Performing write benchmark test.\n")); + + TInt nRes; + TTime timeStart; + TTime timeEnd; + + //-- if window pos increment is <0, it will move from end to the beginning position, backwards + TInt64 currMediaPos1 = (gWriteGranularity1 >=0) ? gMediaStartPos : gMediaEndPos-gWriteBufSize1; + TInt64 currMediaPos2 = (gWriteGranularity2 >=0) ? gMediaStartPos : gMediaEndPos-gWriteBufSize2; + + if(gWindowsNum == 1) //-- we have only 1 window + { + currMediaPos2 = 0; + gWriteGranularity2 = 0; + } + + RndFillBuf(gWriteBuffer1); + if(gWindowsNum == 2) + RndFillBuf(gWriteBuffer2); + + for(;;) + { + if(currMediaPos1 <0 || (currMediaPos1 + gWriteBufSize1) > gMediaEndPos) + break; + + if(currMediaPos2 <0 || (currMediaPos2 + gWriteBufSize2) > gMediaEndPos) + break; + + timeStart.UniversalTime(); //-- take start time + + for(TUint i=0; i= EDriveA) && (gLocalDrvNum <= EDriveZ)); + test(gMediaStartPos >=0 && gMediaEndPos >gMediaStartPos); + test(gWindowsNum == 1 || gWindowsNum == 2); + test(gWriteBufSize1 > 0); + if(gWindowsNum == 2) + { + test(gWriteBufSize2 > 0); + } + test(gNumWrites > 0); + + + TInt nRes; + nRes = Fs.Connect(); + test_KErrNone(nRes); + + //-- connect to the TBusLocalDrive + test.Printf(_L("Connecting to the PHYSICAL drive #%d\n"), gLocalDrvNum); + + nRes = BusLocalDrv.Connect(gLocalDrvNum, gChangeFlag); + test_KErrNone(nRes); + + TLocalDriveCapsV2 info; + TPckg infoPckg(info); + nRes = BusLocalDrv.Caps(infoPckg); + test_KErrNone(nRes); + + //-- create write buffer 1 + nRes=gWriteBuffer1.CreateMax(gWriteBufSize1); + test_KErrNone(nRes); + + + //-- create write buffer 2 + if(gWindowsNum == 2) + { + nRes=gWriteBuffer2.CreateMax(gWriteBufSize2); + test_KErrNone(nRes); + } + + return ETrue; +} + +//--------------------------------------------------------------------------------- + +/** Finalise environment */ +void Finalise(void) +{ + BusLocalDrv.Disconnect(); + BusLocalDrv.Close(); + + gWriteBuffer1.Close(); + gWriteBuffer2.Close(); + + Fs.Close(); +} + + +/** + Just a helper method. Looks for a given pattern in the given string and returns the rest of the found token. + @return KErrNotFound if the aPattern wasn't found in aSrc + KErrNone otherwise and the rest of the token in aToken +*/ +TInt DoFindToken(const TDesC& aSrc, const TDesC& aPattern,TPtrC& aToken) +{ + TLex lex(aSrc); + TPtrC token; + + for(;;) + { + lex.SkipSpace(); + token.Set(lex.NextToken()); + + if(token.Length() == 0) + { + test.Printf(_L("Parameter %S not found!\n"), &aPattern); + return KErrNotFound; + } + + if(token.FindF(aPattern) == 0) + {//-- found a requires patern, extract substring next to it + aToken.Set(token.Right(token.Length() - aPattern.Length())); + break; + } + + + } + + return KErrNone; +} + + +/** + Parse the command line, which shall look like: + drv=[0..25] pos=xxx:yyy [wrep=] wn=[1,2] w1sz= w1pi= [w2sz= w2pi=] +*/ +TBool ParseCommandLine(void) +{ + TBuf<0x100> cmdLine; + User::CommandLine(cmdLine); + + cmdLine.LowerCase(); + + test.Printf(_L("Command line:\n")); + test.Printf(cmdLine); + test.Printf(_L("\n")); + + TLex lexParam; + + TInt nVal; + TUint uVal; + TInt nRes; + + TPtrC token; + + //-- process "drv" parameter. It shall look like: "drv=1" + //-- this is a physical number of a local drive + if(DoFindToken(cmdLine, _L("drv="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + nRes = lexParam.Val(nVal); + if(nRes!= KErrNone || nVal < EDriveA || nVal > EDriveZ) + { + test.Printf(_L("Invalid 'drv' parameter value!\n")); + return EFalse; + } + + gLocalDrvNum = nVal; + + + //-- process "pos" parameter It shall look like: "pos=xxx:yyy" where "xxx" is a start media position, "yyy" end media position + //-- It specifies start and end media position + if(DoFindToken(cmdLine, _L("pos="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + + TInt64 startPos; + TInt64 endPos; + + //-- start media position + nRes = lexParam.Val(startPos); + if(nRes!= KErrNone || startPos< 0) + { + test.Printf(_L("invalid start 'pos' value!\n")); + return EFalse; + } + + //-- delimiter + lexParam.SkipSpace(); + if(lexParam.Get() != ':') + { + test.Printf(_L("invalid 'pos' parameter!\n")); + return EFalse; + } + + //-- end media position + lexParam.SkipSpace(); + nRes = lexParam.Val(endPos); + if(nRes!= KErrNone || endPos < 0) + { + test.Printf(_L("invalid end 'pos' value!\n")); + return EFalse; + } + + gMediaStartPos = startPos; + gMediaEndPos = endPos; + + + //-- process "wn" parameter It shall look like: "wn=1" or "wn=2" + //-- It specifies number of sliding windows. + lexParam.SkipSpace(); + if(DoFindToken(cmdLine, _L("wn="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + + nRes = lexParam.Val(uVal); + if(nRes!= KErrNone || uVal > 2) + { + test.Printf(_L("wrong 'wn' parameter value, it must be 1 or 2 !\n")); + return EFalse; + } + + gWindowsNum = uVal; + + + //-- process "w1sz" & "w1pi" parameters. They shall look like: "w1sz=16384" & "w1pi=512" + //-- these parameters specify size and position increment for the window 1 + //-- if w1pi <0 the window will slide from the media end position to the beginning + lexParam.SkipSpace(); + if(DoFindToken(cmdLine, _L("w1sz="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + + nRes = lexParam.Val(uVal); + if(nRes!= KErrNone || uVal ==0) + { + test.Printf(_L("wrong 'w1sz' parameter value, it must be > 0 !\n")); + return EFalse; + } + + gWriteBufSize1 = uVal; + + + lexParam.SkipSpace(); + if(DoFindToken(cmdLine, _L("w1pi="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + + nRes = lexParam.Val(nVal); + if(nRes!= KErrNone) + { + return EFalse; + } + + gWriteGranularity1 = nVal; + + //-- process "w2sz" & "w2pi" parameters. They shall look like: "w2sz=16384" & "w2pi=512" + //-- these parameters specify size and position increment for the window 1 + //-- if w1pi <0 the window will slide from the media end position to the beginning + if(gWindowsNum == 2) + { + lexParam.SkipSpace(); + if(DoFindToken(cmdLine, _L("w2sz="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + + nRes = lexParam.Val(uVal); + if(nRes!= KErrNone || uVal ==0) + { + test.Printf(_L("wrong 'w2sz' parameter value, it must be > 0 !\n")); + return EFalse; + } + + gWriteBufSize2 = uVal; + + + lexParam.SkipSpace(); + if(DoFindToken(cmdLine, _L("w2pi="), token) != KErrNone) + return EFalse; + + lexParam.Assign(token); + lexParam.SkipSpace(); + + nRes = lexParam.Val(nVal); + if(nRes!= KErrNone) + { + return EFalse; + } + + gWriteGranularity2 = nVal; + } + + //-- extract wrep= parameter. + //-- it specifies how many times buffers will be written to the media + lexParam.SkipSpace(); + if(DoFindToken(cmdLine, _L("wrep="), token) == KErrNone) + { + + + lexParam.Assign(token); + lexParam.SkipSpace(); + + nRes = lexParam.Val(uVal); + if(nRes!= KErrNone || uVal ==0 ) + { + test.Printf(_L("wrong 'wrep' parameter value, it must be >0 !\n")); + return EFalse; + } + + gNumWrites = uVal; + } + else + { + gNumWrites = 1; + } + + + return ETrue; +} + +void PrintInfo() +{ + test.Printf(_L("Media write benchmark test. For use mostly with mmc/sd cards.\n")); + test.Printf(_L("Usage: See source code for command line parameters.\n")); +} + + +//--------------------------------------------------------------------------------- + +void MainL(void) +{ + test.Title(); + test.Start(_L("Start testing...\n")); + + + //-- it will initialise global test parameters + if(!ParseCommandLine()) + { + PrintInfo(); + return; + } + + if(!Initialise()) + { + return; //-- something went wrong + } + + + DoWriteBMTest(); + + Finalise(); + + test.End(); +} + + +TInt E32Main() +{ + + CTrapCleanup* cleanup=CTrapCleanup::New() ; // get clean-up stack + + TRAPD(r,MainL()); + + delete cleanup ; // destroy clean-up stack + + return r; +} + + +