Update contrib.
1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\pccd\t_med_writebm.cpp
22 #define __E32TEST_EXTENSION__
29 SD/MMC/other media benchmark test
30 Writes data to the media and prints out time taken (microseconds).
31 Works on TBusLocalDrive level. May require a script to filter the results.
33 Principle of operation:
34 In the simple case scenario the user specifies media start and end position in bytes,
35 write buffer size (window size), the number of write repetitions (optional) and write position increment.
37 The test fills buffer with random data, writes it to the media (probably several times); prints out the time taken;
38 increments or decrements window position; goto begin. Test finishes when the window slides outside specified beginning or end media position.
40 It more complex case we have 2 windows. It is useful for FAT emulation.
42 -------------------------------------------
43 Command line shall look like this:
44 drv=[0..25] pos=xxx:yyy [wrep=<number>] wn=[1,2] w1sz=<number> w1pi=<number> [w2sz=<number> w2pi=<number>]
47 drv=N local drive physical number for 1st MMC slot on H2 & H4 it will be 1, see variantmediadef.h
48 pos=xxx:yyy xxx start media position, yyy end media position in bytes. The test will be writing data in the range xxx-yyy
49 wrep=N optional. Specifies how many times the window will be written to the media, just for more precise time calculation. Default is 1.
50 wn=N Number of data windows being written on the media. can be 1 or 2
52 w1sz=N Size of the data window #1 in bytes. Must be > 0
53 w1pi=N Media position increment for the window #1. if positive, the window will be moving from xxx to yyy (see media pos parameter);
54 if 0, the window won't change its position; if <0, the window will be moving from yyy to xxx
56 w2sz the same for the window #2 if it is specified
57 w2pi the same for the window #2 if it is specified
59 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
62 Be careful, all information on the medium will be lost !!!
65 RTest test(_L("MMC/SD write performance test"));
67 TBusLocalDrive BusLocalDrv;
73 TInt gLocalDrvNum = -1; //-- LOCAL physical drive number (see Estart.txt)
76 TUint gWindowsNum = 0; //-- number of windows being written
78 TUint32 gWriteBufSize1 = 0; //-- write buffer 1 size, bytes
79 TInt32 gWriteGranularity1 = 0; //-- write granularity 1 (write buffer position increment)
81 TUint32 gWriteBufSize2 = 0; //-- write buffer 2 size, bytes
82 TInt32 gWriteGranularity2 = 0; //-- write granularity 2 (write buffer position increment)
84 TInt64 gMediaStartPos = 0; //-- media start position
85 TInt64 gMediaEndPos = 0; //-- media end position
87 TUint gNumWrites = 1; //-- number of buffer writes to the media
90 //---------------------------------------------------------------------------------
92 void RndFillBuf(TDes8& aBuf);
94 //---------------------------------------------------------------------------------
97 The main part of the test, actually. Writes 1 or 2 buffers to the media (possibly several times) and
98 prints out the time taken.
100 void DoWriteBMTest(void)
102 test.Next(_L("Performing write benchmark test.\n"));
108 //-- if window pos increment is <0, it will move from end to the beginning position, backwards
109 TInt64 currMediaPos1 = (gWriteGranularity1 >=0) ? gMediaStartPos : gMediaEndPos-gWriteBufSize1;
110 TInt64 currMediaPos2 = (gWriteGranularity2 >=0) ? gMediaStartPos : gMediaEndPos-gWriteBufSize2;
112 if(gWindowsNum == 1) //-- we have only 1 window
115 gWriteGranularity2 = 0;
118 RndFillBuf(gWriteBuffer1);
120 RndFillBuf(gWriteBuffer2);
124 if(currMediaPos1 <0 || (currMediaPos1 + gWriteBufSize1) > gMediaEndPos)
127 if(currMediaPos2 <0 || (currMediaPos2 + gWriteBufSize2) > gMediaEndPos)
130 timeStart.UniversalTime(); //-- take start time
132 for(TUint i=0; i<gNumWrites; ++i)
134 nRes = BusLocalDrv.Write(currMediaPos1, gWriteBuffer1); //-- write window 1
139 nRes = BusLocalDrv.Write(currMediaPos2, gWriteBuffer2); //-- write window 2
142 }//for(TUint i=0; i<gNumWrites; ++i)
144 timeEnd.UniversalTime(); //-- take end time
146 TTimeIntervalMicroSeconds usElapsed=timeEnd.MicroSecondsFrom(timeStart);
147 TInt64 usTaken = usElapsed.Int64()/gNumWrites;
149 //-- print out the result
151 test.Printf(_L("~#pos:%lu:%lu, time:%d us\n"), currMediaPos1, currMediaPos2, (TInt32)usTaken);
154 currMediaPos1 += gWriteGranularity1;
155 currMediaPos2 += gWriteGranularity2;
161 //---------------------------------------------------------------------------------
163 /** fill a given buffer with random bytes */
164 void RndFillBuf(TDes8& aBuf)
166 static TInt64 rndSeed = Math::Random();
168 //-- ?? optimise here ??
169 for(TInt i=0; i<aBuf.Size(); ++i)
171 aBuf[i] = (TUint8)Math::Rand(rndSeed);
176 //---------------------------------------------------------------------------------
178 /** Initialise environment */
181 //-- print out some parameters:
182 test.Printf(_L("~#Local Drive:%d\n"), gLocalDrvNum);
183 test.Printf(_L("~#MediaPos:%lu:%lu\n"), gMediaStartPos, gMediaEndPos);
184 test.Printf(_L("~#WinNum:%d\n"), gWindowsNum);
185 test.Printf(_L("~#NumWrites:%d\n"), gNumWrites);
186 test.Printf(_L("~#Window1 sz:%d, posInc:%d \n"), gWriteBufSize1, gWriteGranularity1);
190 test.Printf(_L("~#Window2 sz:%d, posInc:%d \n"), gWriteBufSize2, gWriteGranularity2);
194 test((gLocalDrvNum >= EDriveA) && (gLocalDrvNum <= EDriveZ));
195 test(gMediaStartPos >=0 && gMediaEndPos >gMediaStartPos);
196 test(gWindowsNum == 1 || gWindowsNum == 2);
197 test(gWriteBufSize1 > 0);
200 test(gWriteBufSize2 > 0);
202 test(gNumWrites > 0);
209 //-- connect to the TBusLocalDrive
210 test.Printf(_L("Connecting to the PHYSICAL drive #%d\n"), gLocalDrvNum);
212 nRes = BusLocalDrv.Connect(gLocalDrvNum, gChangeFlag);
215 TLocalDriveCapsV2 info;
216 TPckg<TLocalDriveCapsV2> infoPckg(info);
217 nRes = BusLocalDrv.Caps(infoPckg);
220 //-- create write buffer 1
221 nRes=gWriteBuffer1.CreateMax(gWriteBufSize1);
225 //-- create write buffer 2
228 nRes=gWriteBuffer2.CreateMax(gWriteBufSize2);
235 //---------------------------------------------------------------------------------
237 /** Finalise environment */
240 BusLocalDrv.Disconnect();
243 gWriteBuffer1.Close();
244 gWriteBuffer2.Close();
251 Just a helper method. Looks for a given pattern in the given string and returns the rest of the found token.
252 @return KErrNotFound if the aPattern wasn't found in aSrc
253 KErrNone otherwise and the rest of the token in aToken
255 TInt DoFindToken(const TDesC& aSrc, const TDesC& aPattern,TPtrC& aToken)
263 token.Set(lex.NextToken());
265 if(token.Length() == 0)
267 test.Printf(_L("Parameter %S not found!\n"), &aPattern);
271 if(token.FindF(aPattern) == 0)
272 {//-- found a requires patern, extract substring next to it
273 aToken.Set(token.Right(token.Length() - aPattern.Length()));
285 Parse the command line, which shall look like:
286 drv=[0..25] pos=xxx:yyy [wrep=<number>] wn=[1,2] w1sz=<number> w1pi=<number> [w2sz=<number> w2pi=<number>]
288 TBool ParseCommandLine(void)
291 User::CommandLine(cmdLine);
295 test.Printf(_L("Command line:\n"));
296 test.Printf(cmdLine);
297 test.Printf(_L("\n"));
307 //-- process "drv" parameter. It shall look like: "drv=1"
308 //-- this is a physical number of a local drive
309 if(DoFindToken(cmdLine, _L("drv="), token) != KErrNone)
312 lexParam.Assign(token);
313 lexParam.SkipSpace();
314 nRes = lexParam.Val(nVal);
315 if(nRes!= KErrNone || nVal < EDriveA || nVal > EDriveZ)
317 test.Printf(_L("Invalid 'drv' parameter value!\n"));
324 //-- process "pos" parameter It shall look like: "pos=xxx:yyy" where "xxx" is a start media position, "yyy" end media position
325 //-- It specifies start and end media position
326 if(DoFindToken(cmdLine, _L("pos="), token) != KErrNone)
329 lexParam.Assign(token);
330 lexParam.SkipSpace();
335 //-- start media position
336 nRes = lexParam.Val(startPos);
337 if(nRes!= KErrNone || startPos< 0)
339 test.Printf(_L("invalid start 'pos' value!\n"));
344 lexParam.SkipSpace();
345 if(lexParam.Get() != ':')
347 test.Printf(_L("invalid 'pos' parameter!\n"));
351 //-- end media position
352 lexParam.SkipSpace();
353 nRes = lexParam.Val(endPos);
354 if(nRes!= KErrNone || endPos < 0)
356 test.Printf(_L("invalid end 'pos' value!\n"));
360 gMediaStartPos = startPos;
361 gMediaEndPos = endPos;
364 //-- process "wn" parameter It shall look like: "wn=1" or "wn=2"
365 //-- It specifies number of sliding windows.
366 lexParam.SkipSpace();
367 if(DoFindToken(cmdLine, _L("wn="), token) != KErrNone)
370 lexParam.Assign(token);
371 lexParam.SkipSpace();
373 nRes = lexParam.Val(uVal);
374 if(nRes!= KErrNone || uVal > 2)
376 test.Printf(_L("wrong 'wn' parameter value, it must be 1 or 2 !\n"));
383 //-- process "w1sz" & "w1pi" parameters. They shall look like: "w1sz=16384" & "w1pi=512"
384 //-- these parameters specify size and position increment for the window 1
385 //-- if w1pi <0 the window will slide from the media end position to the beginning
386 lexParam.SkipSpace();
387 if(DoFindToken(cmdLine, _L("w1sz="), token) != KErrNone)
390 lexParam.Assign(token);
391 lexParam.SkipSpace();
393 nRes = lexParam.Val(uVal);
394 if(nRes!= KErrNone || uVal ==0)
396 test.Printf(_L("wrong 'w1sz' parameter value, it must be > 0 !\n"));
400 gWriteBufSize1 = uVal;
403 lexParam.SkipSpace();
404 if(DoFindToken(cmdLine, _L("w1pi="), token) != KErrNone)
407 lexParam.Assign(token);
408 lexParam.SkipSpace();
410 nRes = lexParam.Val(nVal);
416 gWriteGranularity1 = nVal;
418 //-- process "w2sz" & "w2pi" parameters. They shall look like: "w2sz=16384" & "w2pi=512"
419 //-- these parameters specify size and position increment for the window 1
420 //-- if w1pi <0 the window will slide from the media end position to the beginning
423 lexParam.SkipSpace();
424 if(DoFindToken(cmdLine, _L("w2sz="), token) != KErrNone)
427 lexParam.Assign(token);
428 lexParam.SkipSpace();
430 nRes = lexParam.Val(uVal);
431 if(nRes!= KErrNone || uVal ==0)
433 test.Printf(_L("wrong 'w2sz' parameter value, it must be > 0 !\n"));
437 gWriteBufSize2 = uVal;
440 lexParam.SkipSpace();
441 if(DoFindToken(cmdLine, _L("w2pi="), token) != KErrNone)
444 lexParam.Assign(token);
445 lexParam.SkipSpace();
447 nRes = lexParam.Val(nVal);
453 gWriteGranularity2 = nVal;
456 //-- extract wrep=<number> parameter.
457 //-- it specifies how many times buffers will be written to the media
458 lexParam.SkipSpace();
459 if(DoFindToken(cmdLine, _L("wrep="), token) == KErrNone)
463 lexParam.Assign(token);
464 lexParam.SkipSpace();
466 nRes = lexParam.Val(uVal);
467 if(nRes!= KErrNone || uVal ==0 )
469 test.Printf(_L("wrong 'wrep' parameter value, it must be >0 !\n"));
486 test.Printf(_L("Media write benchmark test. For use mostly with mmc/sd cards.\n"));
487 test.Printf(_L("Usage: See source code for command line parameters.\n"));
491 //---------------------------------------------------------------------------------
496 test.Start(_L("Start testing...\n"));
499 //-- it will initialise global test parameters
500 if(!ParseCommandLine())
508 return; //-- something went wrong
523 CTrapCleanup* cleanup=CTrapCleanup::New() ; // get clean-up stack
527 delete cleanup ; // destroy clean-up stack