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"
25 #define TESTBASEDIR "/__TEST__"
26 #define TEST_FILE TESTBASEDIR "/test_disk.tmp"
27 #define FRND_SEED 0x78C3 /* arbirary */
30 #define TEST_SIZE (20*1024*1024)
32 #define TEST_SIZE (300*1024*1024)
34 #define TEST_TIME 10 /* in seconds */
36 static struct plugin_api
* rb
;
37 static unsigned char* audiobuf
;
38 static ssize_t audiobuflen
;
40 static unsigned short frnd_buffer
;
42 static int max_line
= 0;
44 static char logfilename
[MAX_PATH
];
45 static const char testbasedir
[] = TESTBASEDIR
;
47 static void mem_fill_frnd(unsigned char *addr
, int len
)
49 unsigned char *end
= addr
+ len
;
50 unsigned random
= frnd_buffer
;
54 random
= 75 * random
+ 74;
55 *addr
++ = random
>> 8;
60 static bool mem_cmp_frnd(unsigned char *addr
, int len
)
62 unsigned char *end
= addr
+ len
;
63 unsigned random
= frnd_buffer
;
67 random
= 75 * random
+ 74;
68 if (*addr
++ != ((random
>> 8) & 0xff))
75 static bool log_init(void)
79 rb
->lcd_setmargins(0, 0);
80 rb
->lcd_getstringsize("A", NULL
, &h
);
81 max_line
= LCD_HEIGHT
/ h
;
83 rb
->lcd_clear_display();
86 rb
->create_numbered_filename(logfilename
, "/", "test_disk_log_", ".txt",
87 2 IF_CNFN_NUM_(, NULL
));
88 log_fd
= rb
->open(logfilename
, O_RDWR
|O_CREAT
|O_TRUNC
);
92 static void log_text(char *text
, bool advance
)
94 rb
->lcd_puts(0, line
, text
);
98 if (++line
>= max_line
)
100 rb
->fdprintf(log_fd
, "%s\n", text
);
104 static void log_close(void)
109 static bool test_fs(void)
111 unsigned char text_buf
[32];
112 int total
, current
, align
;
116 log_text("test_disk WRITE&VERIFY", true);
117 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
119 log_text(text_buf
, true);
120 log_text("----------------------", true);
121 rb
->snprintf(text_buf
, sizeof text_buf
, "Data size: %dKB", (TEST_SIZE
>>10));
122 log_text(text_buf
, true);
124 fd
= rb
->creat(TEST_FILE
);
127 rb
->splash(HZ
, "creat() failed.");
131 frnd_buffer
= FRND_SEED
;
135 current
= rb
->rand() % (audiobuflen
- 4);
136 current
= MIN(current
, total
);
137 align
= rb
->rand() & 3;
138 rb
->snprintf(text_buf
, sizeof text_buf
, "Wrt %dKB, %dKB left",
139 current
>> 10, total
>> 10);
140 log_text(text_buf
, false);
142 mem_fill_frnd(audiobuf
+ align
, current
);
143 if (current
!= rb
->write(fd
, audiobuf
+ align
, current
))
145 rb
->splash(0, "write() failed.");
153 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
156 rb
->splash(0, "open() failed.");
160 frnd_buffer
= FRND_SEED
;
164 current
= rb
->rand() % (audiobuflen
- 4);
165 current
= MIN(current
, total
);
166 align
= rb
->rand() & 3;
167 rb
->snprintf(text_buf
, sizeof text_buf
, "Cmp %dKB, %dKB left",
168 current
>> 10, total
>> 10);
169 log_text(text_buf
, false);
171 if (current
!= rb
->read(fd
, audiobuf
+ align
, current
))
173 rb
->splash(0, "read() failed.");
177 if (!mem_cmp_frnd(audiobuf
+ align
, current
))
179 log_text(text_buf
, true);
180 log_text("Compare error.", true);
187 log_text(text_buf
, true);
188 log_text("Test passed.", true);
192 rb
->remove(TEST_FILE
);
193 rb
->button_clear_queue();
194 rb
->button_get(true);
199 static bool file_speed(int chunksize
, bool align
)
201 unsigned char text_buf
[64];
206 if (chunksize
>= audiobuflen
)
209 log_text("--------------------", true);
211 /* File creation write speed */
212 fd
= rb
->creat(TEST_FILE
);
215 rb
->splash(HZ
, "creat() failed.");
218 time
= *rb
->current_tick
;
219 while (TIME_BEFORE(*rb
->current_tick
, time
+ TEST_TIME
*HZ
))
221 if (chunksize
!= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
223 rb
->splash(HZ
, "write() failed.");
227 filesize
+= chunksize
;
229 time
= *rb
->current_tick
- time
;
231 rb
->snprintf(text_buf
, sizeof text_buf
, "Create (%d,%c): %ld KB/s",
232 chunksize
, align
? 'A' : 'U', (25 * filesize
/ time
) >> 8);
233 log_text(text_buf
, true);
235 /* Existing file write speed */
236 fd
= rb
->open(TEST_FILE
, O_WRONLY
);
239 rb
->splash(0, "open() failed.");
242 time
= *rb
->current_tick
;
243 for (size
= filesize
; size
> 0; size
-= chunksize
)
245 if (chunksize
!= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
247 rb
->splash(0, "write() failed.");
252 time
= *rb
->current_tick
- time
;
254 rb
->snprintf(text_buf
, sizeof text_buf
, "Write (%d,%c): %ld KB/s",
255 chunksize
, align
? 'A' : 'U', (25 * filesize
/ time
) >> 8);
256 log_text(text_buf
, true);
258 /* File read speed */
259 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
262 rb
->splash(0, "open() failed.");
265 time
= *rb
->current_tick
;
266 for (size
= filesize
; size
> 0; size
-= chunksize
)
268 if (chunksize
!= rb
->read(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
270 rb
->splash(0, "read() failed.");
275 time
= *rb
->current_tick
- time
;
277 rb
->snprintf(text_buf
, sizeof text_buf
, "Read (%d,%c): %ld KB/s",
278 chunksize
, align
? 'A' : 'U', (25 * filesize
/ time
) >> 8);
279 log_text(text_buf
, true);
280 rb
->remove(TEST_FILE
);
284 rb
->remove(TEST_FILE
);
288 static bool test_speed(void)
290 unsigned char text_buf
[64];
292 struct dirent
*entry
= NULL
;
297 rb
->memset(audiobuf
, 'T', audiobuflen
);
299 log_text("test_disk SPEED TEST", true);
300 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
302 log_text(text_buf
, true);
303 log_text("--------------------", true);
305 /* File creation speed */
306 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
307 for (i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); i
++)
309 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
310 fd
= rb
->creat(text_buf
);
314 rb
->splash(HZ
, "creat() failed.");
320 rb
->snprintf(text_buf
, sizeof(text_buf
), "Create: %d files/s",
321 last_file
/ TEST_TIME
);
322 log_text(text_buf
, true);
324 /* File open speed */
325 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
326 for (n
= 0, i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++, i
++)
330 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
331 fd
= rb
->open(text_buf
, O_RDONLY
);
334 rb
->splash(HZ
, "open() failed.");
339 rb
->snprintf(text_buf
, sizeof(text_buf
), "Open: %d files/s", n
/ TEST_TIME
);
340 log_text(text_buf
, true);
342 /* Directory scan speed */
343 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
344 for (n
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++)
350 dir
= rb
->opendir(testbasedir
);
353 rb
->splash(HZ
, "opendir() failed.");
357 entry
= rb
->readdir(dir
);
360 rb
->snprintf(text_buf
, sizeof(text_buf
), "Dirscan: %d files/s", n
/ TEST_TIME
);
361 log_text(text_buf
, true);
363 /* File delete speed */
364 time
= *rb
->current_tick
;
365 for (i
= 0; i
< last_file
; i
++)
367 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
368 rb
->remove(text_buf
);
370 rb
->snprintf(text_buf
, sizeof(text_buf
), "Delete: %ld files/s",
371 last_file
* HZ
/ (*rb
->current_tick
- time
));
372 log_text(text_buf
, true);
374 if (file_speed(512, true)
375 && file_speed(512, false)
376 && file_speed(4096, true)
377 && file_speed(4096, false)
378 && file_speed(1048576, true))
379 file_speed(1048576, false);
381 log_text("DONE", false);
383 rb
->button_clear_queue();
384 rb
->button_get(true);
388 for (i
= 0; i
< last_file
; i
++)
390 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
391 rb
->remove(text_buf
);
393 log_text("DONE", false);
395 rb
->button_clear_queue();
396 rb
->button_get(true);
401 /* this is the plugin entry point */
402 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
404 static const struct menu_item items
[] = {
405 { "Disk speed", test_speed
},
406 { "Write & verify", test_fs
},
415 if ((dir
= rb
->opendir(testbasedir
)) == NULL
)
417 if (rb
->mkdir(testbasedir
) < 0)
419 rb
->splash(HZ
*2, "Can't create test directory.");
428 audiobuf
= rb
->plugin_get_audio_buffer((size_t *)&audiobuflen
);
429 /* align start and length to 32 bit */
430 align
= (-(int)audiobuf
) & 3;
432 audiobuflen
= (audiobuflen
- align
) & ~3;
434 rb
->srand(*rb
->current_tick
);
436 if (rb
->global_settings
->backlight_timeout
> 0)
437 rb
->backlight_set_timeout(1); /* keep the light on */
439 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
), NULL
,
444 /* restore normal backlight setting */
445 rb
->backlight_set_timeout(rb
->global_settings
->backlight_timeout
);
447 rb
->rmdir(testbasedir
);