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 size_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
, 0666);
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 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
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
, 0666);
129 rb
->splashf(HZ
, "creat() failed: %d", fd
);
133 frnd_buffer
= FRND_SEED
;
137 align
= rb
->rand() & 0xf;
138 current
= rb
->rand() % (audiobuflen
- align
);
139 current
= MIN(current
, total
);
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 ret
= rb
->write(fd
, audiobuf
+ align
, current
);
148 rb
->splashf(0, "write() failed: %d/%d", ret
, current
);
156 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
159 rb
->splashf(0, "open() failed: %d", ret
);
163 frnd_buffer
= FRND_SEED
;
167 align
= rb
->rand() & 0xf;
168 current
= rb
->rand() % (audiobuflen
- align
);
169 current
= MIN(current
, total
);
170 rb
->snprintf(text_buf
, sizeof text_buf
, "Cmp %dKB, %dKB left",
171 current
>> 10, total
>> 10);
172 log_text(text_buf
, false);
174 ret
= rb
->read(fd
, audiobuf
+ align
, current
);
177 rb
->splashf(0, "read() failed: %d/%d", ret
, current
);
181 if (!mem_cmp_frnd(audiobuf
+ align
, current
))
183 log_text(text_buf
, true);
184 log_text("Compare error.", true);
191 log_text(text_buf
, true);
192 log_text("Test passed.", true);
196 rb
->remove(TEST_FILE
);
197 rb
->button_clear_queue();
198 rb
->button_get(true);
203 static bool file_speed(int chunksize
, bool align
)
205 unsigned char text_buf
[64];
210 if ((unsigned)chunksize
>= audiobuflen
)
213 log_text("--------------------", true);
215 /* File creation write speed */
216 fd
= rb
->creat(TEST_FILE
, 0666);
219 rb
->splashf(HZ
, "creat() failed: %d", fd
);
222 time
= *rb
->current_tick
;
223 while (TIME_BEFORE(*rb
->current_tick
, time
+ TEST_TIME
*HZ
))
225 ret
= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
);
226 if (chunksize
!= ret
)
228 rb
->splashf(HZ
, "write() failed: %d/%d", ret
, chunksize
);
232 filesize
+= chunksize
;
234 time
= *rb
->current_tick
- time
;
236 rb
->snprintf(text_buf
, sizeof text_buf
, "Create (%d,%c): %ld KB/s",
237 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
238 log_text(text_buf
, true);
240 /* Existing file write speed */
241 fd
= rb
->open(TEST_FILE
, O_WRONLY
);
244 rb
->splashf(0, "open() failed: %d", fd
);
247 time
= *rb
->current_tick
;
248 for (size
= filesize
; size
> 0; size
-= chunksize
)
250 ret
= rb
->write(fd
, audiobuf
+ (align
? 0 : 1), chunksize
);
251 if (chunksize
!= ret
)
253 rb
->splashf(0, "write() failed: %d/%d", ret
, chunksize
);
258 time
= *rb
->current_tick
- time
;
260 rb
->snprintf(text_buf
, sizeof text_buf
, "Write (%d,%c): %ld KB/s",
261 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
262 log_text(text_buf
, true);
264 /* File read speed */
265 fd
= rb
->open(TEST_FILE
, O_RDONLY
);
268 rb
->splashf(0, "open() failed: %d", fd
);
271 time
= *rb
->current_tick
;
272 for (size
= filesize
; size
> 0; size
-= chunksize
)
274 ret
= rb
->read(fd
, audiobuf
+ (align
? 0 : 1), chunksize
);
275 if (chunksize
!= ret
)
277 rb
->splashf(0, "read() failed: %d/%d", ret
, chunksize
);
282 time
= *rb
->current_tick
- time
;
284 rb
->snprintf(text_buf
, sizeof text_buf
, "Read (%d,%c): %ld KB/s",
285 chunksize
, align
? 'A' : 'U', (25 * (filesize
>>8) / time
) );
286 log_text(text_buf
, true);
287 rb
->remove(TEST_FILE
);
291 rb
->remove(TEST_FILE
);
295 static bool test_speed(void)
297 unsigned char text_buf
[64];
299 struct dirent
*entry
= NULL
;
304 rb
->memset(audiobuf
, 'T', audiobuflen
);
306 log_text("test_disk SPEED TEST", true);
307 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
308 rb
->snprintf(text_buf
, sizeof(text_buf
), "CPU clock: %ld Hz",
310 log_text(text_buf
, true);
312 log_text("--------------------", true);
314 /* File creation speed */
315 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
316 for (i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); i
++)
318 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
319 fd
= rb
->creat(text_buf
, 0666);
323 rb
->splashf(HZ
, "creat() failed: %d", fd
);
329 rb
->snprintf(text_buf
, sizeof(text_buf
), "Create: %d files/s",
330 last_file
/ TEST_TIME
);
331 log_text(text_buf
, true);
333 /* File open speed */
334 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
335 for (n
= 0, i
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++, i
++)
339 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
340 fd
= rb
->open(text_buf
, O_RDONLY
);
343 rb
->splashf(HZ
, "open() failed: %d", fd
);
348 rb
->snprintf(text_buf
, sizeof(text_buf
), "Open: %d files/s", n
/ TEST_TIME
);
349 log_text(text_buf
, true);
351 /* Directory scan speed */
352 time
= *rb
->current_tick
+ TEST_TIME
*HZ
;
353 for (n
= 0; TIME_BEFORE(*rb
->current_tick
, time
); n
++)
359 dir
= rb
->opendir(testbasedir
);
362 rb
->splash(HZ
, "opendir() failed.");
366 entry
= rb
->readdir(dir
);
369 rb
->snprintf(text_buf
, sizeof(text_buf
), "Dirscan: %d files/s", n
/ TEST_TIME
);
370 log_text(text_buf
, true);
372 /* File delete speed */
373 time
= *rb
->current_tick
;
374 for (i
= 0; i
< last_file
; i
++)
376 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
377 rb
->remove(text_buf
);
379 rb
->snprintf(text_buf
, sizeof(text_buf
), "Delete: %ld files/s",
380 last_file
* HZ
/ (*rb
->current_tick
- time
));
381 log_text(text_buf
, true);
383 if (file_speed(512, true)
384 && file_speed(512, false)
385 && file_speed(4096, true)
386 && file_speed(4096, false)
387 && file_speed(1048576, true))
388 file_speed(1048576, false);
390 log_text("DONE", false);
392 rb
->button_clear_queue();
393 rb
->button_get(true);
397 for (i
= 0; i
< last_file
; i
++)
399 rb
->snprintf(text_buf
, sizeof(text_buf
), TESTBASEDIR
"/%08x.tmp", i
);
400 rb
->remove(text_buf
);
402 log_text("DONE", false);
404 rb
->button_clear_queue();
405 rb
->button_get(true);
410 /* this is the plugin entry point */
411 enum plugin_status
plugin_start(const void* parameter
)
413 MENUITEM_STRINGLIST(menu
, "Test Disk Menu", NULL
,
414 "Disk speed", "Write & verify");
422 if ((dir
= rb
->opendir(testbasedir
)) == NULL
)
424 if (rb
->mkdir(testbasedir
) < 0)
426 rb
->splash(HZ
*2, "Can't create test directory.");
435 audiobuf
= rb
->plugin_get_audio_buffer(&audiobuflen
);
436 /* align start and length to 32 bit */
437 align
= (-(intptr_t)audiobuf
) & 3;
439 audiobuflen
= (audiobuflen
- align
) & ~3;
441 rb
->srand(*rb
->current_tick
);
443 /* Turn off backlight timeout */
444 backlight_force_on(); /* backlight control in lib/helper.c */
448 switch(rb
->do_menu(&menu
, &selected
, NULL
, false))
462 /* Turn on backlight timeout (revert to settings) */
463 backlight_use_settings(); /* backlight control in lib/helper.c */
465 rb
->rmdir(testbasedir
);