1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include "lib/helper.h"
27 #define TESTBASEDIR "/__TEST__"
28 #define TEST_FILE TESTBASEDIR "/test_disk.tmp"
29 #define FRND_SEED 0x78C3 /* arbirary */
31 #if (CONFIG_STORAGE & STORAGE_MMC)
32 #define TEST_SIZE (20*1024*1024)
34 #define TEST_SIZE (300*1024*1024)
36 #define TEST_TIME 10 /* in seconds */
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_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);
118 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
120 log_text(text_buf
, true);
122 log_text("----------------------", true);
123 rb
->snprintf(text_buf
, sizeof text_buf
, "Data size: %dKB", (TEST_SIZE
>>10));
124 log_text(text_buf
, true);
126 fd
= rb
->creat(TEST_FILE
);
129 rb
->splash(HZ
, "creat() failed.");
133 frnd_buffer
= FRND_SEED
;
137 current
= rb
->rand() % (audiobuflen
- 4);
138 current
= MIN(current
, total
);
139 align
= rb
->rand() & 3;
140 rb
->snprintf(text_buf
, sizeof text_buf
, "Wrt %dKB, %dKB left",
141 current
>> 10, total
>> 10);
142 log_text(text_buf
, false);
144 mem_fill_frnd(audiobuf
+ align
, current
);
145 if (current
!= rb
->write(fd
, audiobuf
+ align
, current
))
147 rb
->splash(0, "write() failed.");
155 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
158 rb
->splash(0, "open() failed.");
162 frnd_buffer
= FRND_SEED
;
166 current
= rb
->rand() % (audiobuflen
- 4);
167 current
= MIN(current
, total
);
168 align
= rb
->rand() & 3;
169 rb
->snprintf(text_buf
, sizeof text_buf
, "Cmp %dKB, %dKB left",
170 current
>> 10, total
>> 10);
171 log_text(text_buf
, false);
173 if (current
!= rb
->read(fd
, audiobuf
+ align
, current
))
175 rb
->splash(0, "read() failed.");
179 if (!mem_cmp_frnd(audiobuf
+ align
, current
))
181 log_text(text_buf
, true);
182 log_text("Compare error.", true);
189 log_text(text_buf
, true);
190 log_text("Test passed.", true);
194 rb
->remove(TEST_FILE
);
195 rb
->button_clear_queue();
196 rb
->button_get(true);
201 static bool file_speed(int chunksize
, bool align
)
203 unsigned char text_buf
[64];
208 if (chunksize
>= audiobuflen
)
211 log_text("--------------------", true);
213 /* File creation write speed */
214 fd
= rb
->creat(TEST_FILE
);
217 rb
->splash(HZ
, "creat() failed.");
220 time
= *rb
->current_tick
;
221 while (TIME_BEFORE(*rb
->current_tick
, time
+ TEST_TIME
*HZ
))
223 if (chunksize
!= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
225 rb
->splash(HZ
, "write() failed.");
229 filesize
+= chunksize
;
231 time
= *rb
->current_tick
- time
;
233 rb
->snprintf(text_buf
, sizeof text_buf
, "Create (%d,%c): %ld KB/s",
234 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
235 log_text(text_buf
, true);
237 /* Existing file write speed */
238 fd
= rb
->open(TEST_FILE
, O_WRONLY
);
241 rb
->splash(0, "open() failed.");
244 time
= *rb
->current_tick
;
245 for (size
= filesize
; size
> 0; size
-= chunksize
)
247 if (chunksize
!= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
249 rb
->splash(0, "write() failed.");
254 time
= *rb
->current_tick
- time
;
256 rb
->snprintf(text_buf
, sizeof text_buf
, "Write (%d,%c): %ld KB/s",
257 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
258 log_text(text_buf
, true);
260 /* File read speed */
261 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
264 rb
->splash(0, "open() failed.");
267 time
= *rb
->current_tick
;
268 for (size
= filesize
; size
> 0; size
-= chunksize
)
270 if (chunksize
!= rb
->read(fd
, audiobuf
+ (align
? 0 : 1), chunksize
))
272 rb
->splash(0, "read() failed.");
277 time
= *rb
->current_tick
- time
;
279 rb
->snprintf(text_buf
, sizeof text_buf
, "Read (%d,%c): %ld KB/s",
280 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
281 log_text(text_buf
, true);
282 rb
->remove(TEST_FILE
);
286 rb
->remove(TEST_FILE
);
290 static bool test_speed(void)
292 unsigned char text_buf
[64];
294 struct dirent
*entry
= NULL
;
299 rb
->memset(audiobuf
, 'T', audiobuflen
);
301 log_text("test_disk SPEED TEST", true);
303 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
305 log_text(text_buf
, true);
307 log_text("--------------------", true);
309 /* File creation speed */
310 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
311 for (i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); i
++)
313 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
314 fd
= rb
->creat(text_buf
);
318 rb
->splash(HZ
, "creat() failed.");
324 rb
->snprintf(text_buf
, sizeof(text_buf
), "Create: %d files/s",
325 last_file
/ TEST_TIME
);
326 log_text(text_buf
, true);
328 /* File open speed */
329 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
330 for (n
= 0, i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++, i
++)
334 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
335 fd
= rb
->open(text_buf
, O_RDONLY
);
338 rb
->splash(HZ
, "open() failed.");
343 rb
->snprintf(text_buf
, sizeof(text_buf
), "Open: %d files/s", n
/ TEST_TIME
);
344 log_text(text_buf
, true);
346 /* Directory scan speed */
347 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
348 for (n
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++)
354 dir
= rb
->opendir(testbasedir
);
357 rb
->splash(HZ
, "opendir() failed.");
361 entry
= rb
->readdir(dir
);
364 rb
->snprintf(text_buf
, sizeof(text_buf
), "Dirscan: %d files/s", n
/ TEST_TIME
);
365 log_text(text_buf
, true);
367 /* File delete speed */
368 time
= *rb
->current_tick
;
369 for (i
= 0; i
< last_file
; i
++)
371 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
372 rb
->remove(text_buf
);
374 rb
->snprintf(text_buf
, sizeof(text_buf
), "Delete: %ld files/s",
375 last_file
* HZ
/ (*rb
->current_tick
- time
));
376 log_text(text_buf
, true);
378 if (file_speed(512, true)
379 && file_speed(512, false)
380 && file_speed(4096, true)
381 && file_speed(4096, false)
382 && file_speed(1048576, true))
383 file_speed(1048576, false);
385 log_text("DONE", false);
387 rb
->button_clear_queue();
388 rb
->button_get(true);
392 for (i
= 0; i
< last_file
; i
++)
394 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
395 rb
->remove(text_buf
);
397 log_text("DONE", false);
399 rb
->button_clear_queue();
400 rb
->button_get(true);
405 /* this is the plugin entry point */
406 enum plugin_status
plugin_start(const void* parameter
)
408 MENUITEM_STRINGLIST(menu
, "Test Disk Menu", NULL
,
409 "Disk speed", "Write & verify");
417 if ((dir
= rb
->opendir(testbasedir
)) == NULL
)
419 if (rb
->mkdir(testbasedir
) < 0)
421 rb
->splash(HZ
*2, "Can't create test directory.");
430 audiobuf
= rb
->plugin_get_audio_buffer((size_t *)&audiobuflen
);
431 /* align start and length to 32 bit */
432 align
= (-(int)audiobuf
) & 3;
434 audiobuflen
= (audiobuflen
- align
) & ~3;
436 rb
->srand(*rb
->current_tick
);
438 /* Turn off backlight timeout */
439 backlight_force_on(); /* backlight control in lib/helper.c */
443 switch(rb
->do_menu(&menu
, &selected
, NULL
, false))
457 /* Turn on backlight timeout (revert to settings) */
458 backlight_use_settings(); /* backlight control in lib/helper.c */
460 rb
->rmdir(testbasedir
);