1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Jens Arnold
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 #include "oldmenuapi.h"
26 #define TESTBASEDIR "/__TEST__"
27 #define TEST_FILE TESTBASEDIR "/test_disk.tmp"
28 #define FRND_SEED 0x78C3 /* arbirary */
31 #define TEST_SIZE (20*1024*1024)
33 #define TEST_SIZE (300*1024*1024)
35 #define TEST_TIME 10 /* in seconds */
37 static struct plugin_api
* rb
;
38 static unsigned char* audiobuf
;
39 static ssize_t audiobuflen
;
41 static unsigned short frnd_buffer
;
43 static int max_line
= 0;
45 static char logfilename
[MAX_PATH
];
46 static const char testbasedir
[] = TESTBASEDIR
;
48 static void mem_fill_frnd(unsigned char *addr
, int len
)
50 unsigned char *end
= addr
+ len
;
51 unsigned random
= frnd_buffer
;
55 random
= 75 * random
+ 74;
56 *addr
++ = random
>> 8;
61 static bool mem_cmp_frnd(unsigned char *addr
, int len
)
63 unsigned char *end
= addr
+ len
;
64 unsigned random
= frnd_buffer
;
68 random
= 75 * random
+ 74;
69 if (*addr
++ != ((random
>> 8) & 0xff))
76 static bool log_init(void)
80 rb
->lcd_setmargins(0, 0);
81 rb
->lcd_getstringsize("A", NULL
, &h
);
82 max_line
= LCD_HEIGHT
/ h
;
84 rb
->lcd_clear_display();
87 rb
->create_numbered_filename(logfilename
, "/", "test_disk_log_", ".txt",
88 2 IF_CNFN_NUM_(, NULL
));
89 log_fd
= rb
->open(logfilename
, O_RDWR
|O_CREAT
|O_TRUNC
);
93 static void log_text(char *text
, bool advance
)
95 rb
->lcd_puts(0, line
, text
);
99 if (++line
>= max_line
)
101 rb
->fdprintf(log_fd
, "%s\n", text
);
105 static void log_close(void)
110 static bool test_fs(void)
112 unsigned char text_buf
[32];
113 int total
, current
, align
;
117 log_text("test_disk WRITE&VERIFY", true);
119 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
121 log_text(text_buf
, true);
123 log_text("----------------------", true);
124 rb
->snprintf(text_buf
, sizeof text_buf
, "Data size: %dKB", (TEST_SIZE
>>10));
125 log_text(text_buf
, true);
127 fd
= rb
->creat(TEST_FILE
);
130 rb
->splash(HZ
, "creat() failed.");
134 frnd_buffer
= FRND_SEED
;
138 current
= rb
->rand() % (audiobuflen
- 4);
139 current
= MIN(current
, total
);
140 align
= rb
->rand() & 3;
141 rb
->snprintf(text_buf
, sizeof text_buf
, "Wrt %dKB, %dKB left",
142 current
>> 10, total
>> 10);
143 log_text(text_buf
, false);
145 mem_fill_frnd(audiobuf
+ align
, current
);
146 if (current
!= rb
->write(fd
, audiobuf
+ align
, current
))
148 rb
->splash(0, "write() failed.");
156 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
159 rb
->splash(0, "open() failed.");
163 frnd_buffer
= FRND_SEED
;
167 current
= rb
->rand() % (audiobuflen
- 4);
168 current
= MIN(current
, total
);
169 align
= rb
->rand() & 3;
170 rb
->snprintf(text_buf
, sizeof text_buf
, "Cmp %dKB, %dKB left",
171 current
>> 10, total
>> 10);
172 log_text(text_buf
, false);
174 if (current
!= rb
->read(fd
, audiobuf
+ align
, current
))
176 rb
->splash(0, "read() failed.");
180 if (!mem_cmp_frnd(audiobuf
+ align
, current
))
182 log_text(text_buf
, true);
183 log_text("Compare error.", true);
190 log_text(text_buf
, true);
191 log_text("Test passed.", true);
195 rb
->remove(TEST_FILE
);
196 rb
->button_clear_queue();
197 rb
->button_get(true);
202 static bool file_speed(int chunksize
, bool align
)
204 unsigned char text_buf
[64];
209 if (chunksize
>= audiobuflen
)
212 log_text("--------------------", true);
214 /* File creation write speed */
215 fd
= rb
->creat(TEST_FILE
);
218 rb
->splash(HZ
, "creat() failed.");
221 time
= *rb
->current_tick
;
222 while (TIME_BEFORE(*rb
->current_tick
, time
+ TEST_TIME
*HZ
))
224 if (chunksize
!= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
226 rb
->splash(HZ
, "write() failed.");
230 filesize
+= chunksize
;
232 time
= *rb
->current_tick
- time
;
234 rb
->snprintf(text_buf
, sizeof text_buf
, "Create (%d,%c): %ld KB/s",
235 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
236 log_text(text_buf
, true);
238 /* Existing file write speed */
239 fd
= rb
->open(TEST_FILE
, O_WRONLY
);
242 rb
->splash(0, "open() failed.");
245 time
= *rb
->current_tick
;
246 for (size
= filesize
; size
> 0; size
-= chunksize
)
248 if (chunksize
!= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
250 rb
->splash(0, "write() failed.");
255 time
= *rb
->current_tick
- time
;
257 rb
->snprintf(text_buf
, sizeof text_buf
, "Write (%d,%c): %ld KB/s",
258 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
259 log_text(text_buf
, true);
261 /* File read speed */
262 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
265 rb
->splash(0, "open() failed.");
268 time
= *rb
->current_tick
;
269 for (size
= filesize
; size
> 0; size
-= chunksize
)
271 if (chunksize
!= rb
->read(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
273 rb
->splash(0, "read() failed.");
278 time
= *rb
->current_tick
- time
;
280 rb
->snprintf(text_buf
, sizeof text_buf
, "Read (%d,%c): %ld KB/s",
281 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
282 log_text(text_buf
, true);
283 rb
->remove(TEST_FILE
);
287 rb
->remove(TEST_FILE
);
291 static bool test_speed(void)
293 unsigned char text_buf
[64];
295 struct dirent
*entry
= NULL
;
300 rb
->memset(audiobuf
, 'T', audiobuflen
);
302 log_text("test_disk SPEED TEST", true);
304 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
306 log_text(text_buf
, true);
308 log_text("--------------------", true);
310 /* File creation speed */
311 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
312 for (i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); i
++)
314 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
315 fd
= rb
->creat(text_buf
);
319 rb
->splash(HZ
, "creat() failed.");
325 rb
->snprintf(text_buf
, sizeof(text_buf
), "Create: %d files/s",
326 last_file
/ TEST_TIME
);
327 log_text(text_buf
, true);
329 /* File open speed */
330 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
331 for (n
= 0, i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++, i
++)
335 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
336 fd
= rb
->open(text_buf
, O_RDONLY
);
339 rb
->splash(HZ
, "open() failed.");
344 rb
->snprintf(text_buf
, sizeof(text_buf
), "Open: %d files/s", n
/ TEST_TIME
);
345 log_text(text_buf
, true);
347 /* Directory scan speed */
348 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
349 for (n
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++)
355 dir
= rb
->opendir(testbasedir
);
358 rb
->splash(HZ
, "opendir() failed.");
362 entry
= rb
->readdir(dir
);
365 rb
->snprintf(text_buf
, sizeof(text_buf
), "Dirscan: %d files/s", n
/ TEST_TIME
);
366 log_text(text_buf
, true);
368 /* File delete speed */
369 time
= *rb
->current_tick
;
370 for (i
= 0; i
< last_file
; i
++)
372 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
373 rb
->remove(text_buf
);
375 rb
->snprintf(text_buf
, sizeof(text_buf
), "Delete: %ld files/s",
376 last_file
* HZ
/ (*rb
->current_tick
- time
));
377 log_text(text_buf
, true);
379 if (file_speed(512, true)
380 && file_speed(512, false)
381 && file_speed(4096, true)
382 && file_speed(4096, false)
383 && file_speed(1048576, true))
384 file_speed(1048576, false);
386 log_text("DONE", false);
388 rb
->button_clear_queue();
389 rb
->button_get(true);
393 for (i
= 0; i
< last_file
; i
++)
395 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
396 rb
->remove(text_buf
);
398 log_text("DONE", false);
400 rb
->button_clear_queue();
401 rb
->button_get(true);
406 /* this is the plugin entry point */
407 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
409 static const struct menu_item items
[] = {
410 { "Disk speed", test_speed
},
411 { "Write & verify", test_fs
},
420 if ((dir
= rb
->opendir(testbasedir
)) == NULL
)
422 if (rb
->mkdir(testbasedir
) < 0)
424 rb
->splash(HZ
*2, "Can't create test directory.");
433 audiobuf
= rb
->plugin_get_audio_buffer((size_t *)&audiobuflen
);
434 /* align start and length to 32 bit */
435 align
= (-(int)audiobuf
) & 3;
437 audiobuflen
= (audiobuflen
- align
) & ~3;
439 rb
->srand(*rb
->current_tick
);
441 /* Turn off backlight timeout */
442 backlight_force_on(rb
); /* backlight control in lib/helper.c */
444 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
), NULL
,
449 /* Turn on backlight timeout (revert to settings) */
450 backlight_use_settings(rb
); /* backlight control in lib/helper.c */
452 rb
->rmdir(testbasedir
);