|
1 // Copyright (c) 2007-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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\pccd\t_nandbm.cpp |
|
15 // Test read/write performance for NAND drives accessed directly |
|
16 // through the Local Media Sub-System |
|
17 // When no command parameter is supplied search for first |
|
18 // writeable NAND drive that can be found |
|
19 // If a drive number parameter in the range 0 - F is provided, |
|
20 // interpret this as a local drive number in the range 0 - 15 |
|
21 // and test the drive if it is a writeable NAND drive |
|
22 // Please note that local drive numbers at the Local Media Sub-System |
|
23 // level are not the same as drive numbers / drive letters at the |
|
24 // File Server level. File Server drive numbers / drive letters fall |
|
25 // in the range 0 - 25 / a - z. The mapping between local drive numbers |
|
26 // and File Server drive numbers / drive letters is defined in |
|
27 // estart.txt or its equivalent |
|
28 // Use TBusLocalDrive directly and bypass the File Server |
|
29 // Fill NAND user data drive with data prior to executing actual |
|
30 // performance tests. TBusLocalDrive should read from areas that have |
|
31 // been written to and are therefore assigned. Where areas are |
|
32 // unassigned, XSR FTL returns FFs without accessing the NAND flash |
|
33 // hardware. This type of behaviour generates misleadingly quick |
|
34 // performance figures |
|
35 // Test various block sizes in the range 16 - 65536 bytes |
|
36 // |
|
37 // |
|
38 |
|
39 |
|
40 #include <e32test.h> |
|
41 #include <f32fsys.h> |
|
42 #include <e32hal.h> |
|
43 #include <e32uid.h> |
|
44 #include <f32dbg.h> |
|
45 |
|
46 |
|
47 LOCAL_D TBuf<1048576> DataBuf; |
|
48 LOCAL_D TBusLocalDrive TheDrive; |
|
49 LOCAL_D TBool ChangedFlag; |
|
50 LOCAL_D RFs TheFs; |
|
51 |
|
52 RTest test(_L("Local NAND Drive BenchMark Test")); |
|
53 |
|
54 LOCAL_C void DoRead(TInt aReadBlockSize) |
|
55 // |
|
56 // Do Read benchmark |
|
57 // |
|
58 { |
|
59 TInt msgHandle = KLocalMessageHandle; |
|
60 TLocalDriveCapsV2 info; |
|
61 TPckg<TLocalDriveCapsV2> infoPckg(info); |
|
62 TInt maxSize; |
|
63 TheDrive.Caps(infoPckg); |
|
64 maxSize=I64LOW(info.iSize); |
|
65 TInt count,pos,err; |
|
66 count=pos=err=0; |
|
67 |
|
68 RTimer timer; |
|
69 timer.CreateLocal(); |
|
70 TRequestStatus reqStat; |
|
71 timer.After(reqStat,10000000); // After 10 secs |
|
72 while(reqStat==KRequestPending) |
|
73 { |
|
74 if (TheDrive.Read(pos,aReadBlockSize,&DataBuf,msgHandle,0)==KErrNone) |
|
75 count++; |
|
76 else |
|
77 err++; |
|
78 pos+=aReadBlockSize; |
|
79 if (pos>=(maxSize-aReadBlockSize)) |
|
80 pos=0; |
|
81 } |
|
82 #if defined (__WINS__) |
|
83 test.Printf(_L("Read %d %d byte blocks in 10 secs\n"),count,aReadBlockSize); |
|
84 #else |
|
85 TBuf<60> buf; |
|
86 TReal32 rate=((TReal32)(count*aReadBlockSize))/10240.0F; |
|
87 TRealFormat rf(10,2); |
|
88 buf.Format(_L("Read %d %d byte blocks in 10 secs ("),count,aReadBlockSize); |
|
89 buf.AppendNum(rate,rf); |
|
90 buf.Append(_L("Kb/s)\n")); |
|
91 test.Printf(buf); |
|
92 #endif |
|
93 test.Printf(_L("Errors:%d\n"),err); |
|
94 } |
|
95 |
|
96 LOCAL_C void DoWrite(TInt aWriteBlockSize) |
|
97 // |
|
98 // Do write benchmark |
|
99 // |
|
100 { |
|
101 TInt msgHandle = KLocalMessageHandle; |
|
102 TLocalDriveCapsV2 info; |
|
103 TPckg<TLocalDriveCapsV2> infoPckg(info); |
|
104 TInt maxSize; |
|
105 TheDrive.Caps(infoPckg); |
|
106 maxSize=I64LOW(info.iSize); |
|
107 TInt count,pos,err; |
|
108 count=pos=err=0; |
|
109 |
|
110 RTimer timer; |
|
111 timer.CreateLocal(); |
|
112 TRequestStatus reqStat; |
|
113 timer.After(reqStat,10000000); // After 10 secs |
|
114 while(reqStat==KRequestPending) |
|
115 { |
|
116 if (TheDrive.Write(pos,aWriteBlockSize,&DataBuf,msgHandle,0)==KErrNone) |
|
117 count++; |
|
118 else |
|
119 err++; |
|
120 pos+=aWriteBlockSize; |
|
121 if (pos>=(maxSize-aWriteBlockSize)) |
|
122 pos=0; |
|
123 } |
|
124 #if defined (__WINS__) |
|
125 test.Printf(_L("Write %d %d byte blocks in 10 secs\n"),count,aWriteBlockSize); |
|
126 #else |
|
127 TBuf<60> buf; |
|
128 TReal32 rate=((TReal32)(count*aWriteBlockSize))/10240.0F; |
|
129 TRealFormat rf(10,2); |
|
130 buf.Format(_L("Write %d %d byte blocks in 10 secs ("),count,aWriteBlockSize); |
|
131 buf.AppendNum(rate,rf); |
|
132 buf.Append(_L("Kb/s)\n")); |
|
133 test.Printf(buf); |
|
134 #endif |
|
135 test.Printf(_L("Errors:%d\n"),err); |
|
136 } |
|
137 |
|
138 GLDEF_C TInt E32Main() |
|
139 { |
|
140 test.Title(); |
|
141 |
|
142 TBuf<0x100> cmd; |
|
143 User::CommandLine(cmd); // put command line into decriptor |
|
144 TLex lex(cmd); |
|
145 TPtrC param=lex.NextToken(); // point token at local drive number if any |
|
146 test.Printf(_L("Local Drive = %S\r\n"),¶m); |
|
147 |
|
148 TChar localDrv; |
|
149 TInt localDrvNum; |
|
150 TBusLocalDrive drive; |
|
151 TBool changeFlag; |
|
152 TLocalDriveCapsV4 driveCaps; |
|
153 TPckg<TLocalDriveCapsV4> capsPckg(driveCaps); |
|
154 TInt r; |
|
155 |
|
156 if (param.Length()==0) |
|
157 { |
|
158 // locate writeable NAND drive |
|
159 for (localDrvNum=0; localDrvNum<KMaxLocalDrives; localDrvNum++) |
|
160 { |
|
161 |
|
162 r = drive.Connect(localDrvNum,changeFlag); |
|
163 |
|
164 if (r!=KErrNone) |
|
165 continue; |
|
166 |
|
167 r = drive.Caps(capsPckg); |
|
168 drive.Disconnect(); |
|
169 if ((r==KErrNone) |
|
170 &&(driveCaps.iType==EMediaNANDFlash) |
|
171 &&!(driveCaps.iMediaAtt&KMediaAttWriteProtected) |
|
172 &&(driveCaps.iPartitionType!=KPartitionTypeSymbianCrashLog)) |
|
173 break; |
|
174 } |
|
175 if (localDrvNum==16) |
|
176 { |
|
177 test.Printf(_L("Suitable drive could not be found\r\n")); |
|
178 test.Printf(_L("Writeable NAND drive required for test\r\n")); |
|
179 return(KErrGeneral); |
|
180 } |
|
181 } |
|
182 else |
|
183 { |
|
184 // is selected local drive number in the range 0-15 |
|
185 localDrv=param[0]; |
|
186 localDrv.UpperCase(); |
|
187 if (localDrv>='0'&&localDrv<='9') |
|
188 { |
|
189 localDrvNum=((TInt)localDrv-'0'); |
|
190 } |
|
191 else if (localDrv>='A'&&localDrv<='F') |
|
192 { |
|
193 localDrvNum=((TInt)localDrv-'A'+10); |
|
194 } |
|
195 else |
|
196 { |
|
197 test.Printf(_L("Commandline %S invalid\r\n"), &cmd); |
|
198 test.Printf(_L("Usage:\r\n")); |
|
199 test.Printf(_L("t_nandbm with no arguments, test first suitable NAND drive \r\n")); |
|
200 test.Printf(_L("t_nandbm x, where x = 0-F test local drive number 0-15\r\n")); |
|
201 return(KErrGeneral); |
|
202 } |
|
203 // is selected drive suitable for test |
|
204 r = drive.Connect(localDrvNum,changeFlag); |
|
205 if(r!=KErrNone) |
|
206 { |
|
207 test.Printf(_L("Can't connect to drive %d\r\n"), localDrvNum); |
|
208 return(KErrGeneral); |
|
209 } |
|
210 r = drive.Caps(capsPckg); |
|
211 if(r!=KErrNone) |
|
212 { |
|
213 test.Printf(_L("Drive %d caps method error\r\n"), localDrvNum); |
|
214 return(KErrGeneral); |
|
215 } |
|
216 drive.Disconnect(); |
|
217 if ((driveCaps.iType!=EMediaNANDFlash) |
|
218 ||(driveCaps.iMediaAtt&KMediaAttWriteProtected) |
|
219 ||(driveCaps.iPartitionType==KPartitionTypeSymbianCrashLog)) |
|
220 { |
|
221 test.Printf(_L("Drive %d has unsuitable capabilities\r\n"), localDrvNum); |
|
222 test.Printf(_L("Writeable NAND drive required for test\r\n")); |
|
223 return(KErrGeneral); |
|
224 } |
|
225 |
|
226 } |
|
227 |
|
228 // Fill the nand user data drive with data so TBusLocalDrive reads |
|
229 // from areas that have been written to and are therefore assigned. |
|
230 // Where areas are unassigned, XSR FTL returns FFs without accessing |
|
231 // the NAND flash hardware. This type of behaviour generates misleadingly |
|
232 // quick performance figures. |
|
233 TInt writesize=1048576; |
|
234 TInt pos = 0; |
|
235 TInt msgHandle = KLocalMessageHandle; |
|
236 |
|
237 TheDrive.Connect(localDrvNum,ChangedFlag); |
|
238 test.Printf( _L("Fill up NAND drive %d\r\n"),localDrvNum); |
|
239 while(writesize>=1) |
|
240 { |
|
241 test.Printf( _L("%d byte write to pos %d of NAND drive\r\n"),writesize,pos); |
|
242 if (TheDrive.Write(pos,writesize,&DataBuf,msgHandle,0)!=KErrNone) |
|
243 { |
|
244 writesize/=16; |
|
245 } |
|
246 else |
|
247 { |
|
248 pos += writesize; |
|
249 } |
|
250 } |
|
251 |
|
252 test.Start(_L("Start Benchmarking ...")); |
|
253 |
|
254 DoRead(16); |
|
255 DoRead(256); |
|
256 DoRead(512); |
|
257 DoRead(513); |
|
258 DoRead(2048); |
|
259 DoRead(4096); |
|
260 DoRead(16384); |
|
261 DoRead(32768); |
|
262 DoRead(65536); |
|
263 |
|
264 DoWrite(16); |
|
265 DoWrite(256); |
|
266 DoWrite(512); |
|
267 DoWrite(513); |
|
268 DoWrite(2048); |
|
269 DoWrite(4096); |
|
270 DoWrite(16384); |
|
271 DoWrite(32768); |
|
272 DoWrite(65536); |
|
273 |
|
274 test.End(); |
|
275 |
|
276 TheFs.Close(); |
|
277 |
|
278 return(KErrNone); |
|
279 } |
|
280 |