summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/test_disk.c325
1 files changed, 224 insertions, 101 deletions
diff --git a/apps/plugins/test_disk.c b/apps/plugins/test_disk.c
index c46774d8a0..5799f4ce0b 100644
--- a/apps/plugins/test_disk.c
+++ b/apps/plugins/test_disk.c
@@ -22,22 +22,27 @@
22 22
23PLUGIN_HEADER 23PLUGIN_HEADER
24 24
25#define TEST_FILE "/test_disk.tmp" 25#define TESTBASEDIR "/__TEST__"
26#define FRND_SEED 0x78C3 /* arbirary */ 26#define TEST_FILE TESTBASEDIR "/test_disk.tmp"
27#define FRND_SEED 0x78C3 /* arbirary */
27 28
28#ifdef HAVE_MMC 29#ifdef HAVE_MMC
29#define TEST_SIZE (20*1024*1024) 30#define TEST_SIZE (20*1024*1024)
30#else 31#else
31#define TEST_SIZE (300*1024*1024) 32#define TEST_SIZE (300*1024*1024)
32#endif 33#endif
34#define TEST_TIME 10 /* in seconds */
33 35
34static struct plugin_api* rb; 36static struct plugin_api* rb;
35static unsigned char* audiobuf; 37static unsigned char* audiobuf;
36static ssize_t audiobufsize; 38static ssize_t audiobuflen;
37 39
38static unsigned short frnd_buffer; 40static unsigned short frnd_buffer;
39static int line = 0; 41static int line = 0;
40static int max_line = 0; 42static int max_line = 0;
43static int log_fd;
44static char logfilename[MAX_PATH];
45static const char testbasedir[] = TESTBASEDIR;
41 46
42static void mem_fill_frnd(unsigned char *addr, int len) 47static void mem_fill_frnd(unsigned char *addr, int len)
43{ 48{
@@ -67,46 +72,59 @@ static bool mem_cmp_frnd(unsigned char *addr, int len)
67 return true; 72 return true;
68} 73}
69 74
70static void log_init(void) 75static bool log_init(void)
71{ 76{
72 int h; 77 int h;
73 78
79 rb->lcd_setmargins(0, 0);
74 rb->lcd_getstringsize("A", NULL, &h); 80 rb->lcd_getstringsize("A", NULL, &h);
75 max_line = LCD_HEIGHT / h; 81 max_line = LCD_HEIGHT / h;
76 line = 0; 82 line = 0;
77 rb->lcd_clear_display(); 83 rb->lcd_clear_display();
78 rb->lcd_update(); 84 rb->lcd_update();
85
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);
89 return log_fd >= 0;
79} 90}
80 91
81static void log_lcd(char *text, bool advance) 92static void log_text(char *text, bool advance)
82{ 93{
83 rb->lcd_puts(0, line, text); 94 rb->lcd_puts(0, line, text);
84 rb->lcd_update(); 95 rb->lcd_update();
85 if (advance) 96 if (advance)
97 {
86 if (++line >= max_line) 98 if (++line >= max_line)
87 line = 0; 99 line = 0;
100 rb->fdprintf(log_fd, "%s\n", text);
101 }
102}
103
104static void log_close(void)
105{
106 rb->close(log_fd);
88} 107}
89 108
90static bool test_fs(void) 109static bool test_fs(void)
91{ 110{
92 unsigned char text_buf[32]; 111 unsigned char text_buf[32];
93 unsigned char *buf_start; 112 int total, current, align;
94 int align, buf_len;
95 int total, current;
96 int fd; 113 int fd;
97 114
98 align = (-(int)audiobuf) & 3;
99 buf_start = audiobuf + align;
100 buf_len = (audiobufsize - align - 4) & ~3;
101
102 log_init(); 115 log_init();
103 rb->snprintf(text_buf, sizeof text_buf, "FS stress test: %dKB", (TEST_SIZE>>10)); 116 log_text("test_disk WRITE&VERIFY", true);
104 log_lcd(text_buf, true); 117 rb->snprintf(text_buf, sizeof(text_buf), "CPU clock: %ld Hz",
118 *rb->cpu_frequency);
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);
105 123
106 fd = rb->creat(TEST_FILE); 124 fd = rb->creat(TEST_FILE);
107 if (fd < 0) 125 if (fd < 0)
108 { 126 {
109 rb->splash(0, "Couldn't create testfile."); 127 rb->splash(HZ, "creat() failed.");
110 goto error; 128 goto error;
111 } 129 }
112 130
@@ -114,17 +132,17 @@ static bool test_fs(void)
114 total = TEST_SIZE; 132 total = TEST_SIZE;
115 while (total > 0) 133 while (total > 0)
116 { 134 {
117 current = rb->rand() % buf_len; 135 current = rb->rand() % (audiobuflen - 4);
118 current = MIN(current, total); 136 current = MIN(current, total);
119 align = rb->rand() & 3; 137 align = rb->rand() & 3;
120 rb->snprintf(text_buf, sizeof text_buf, "Wrt %dKB, %dKB left", 138 rb->snprintf(text_buf, sizeof text_buf, "Wrt %dKB, %dKB left",
121 current >> 10, total >> 10); 139 current >> 10, total >> 10);
122 log_lcd(text_buf, false); 140 log_text(text_buf, false);
123 141
124 mem_fill_frnd(buf_start + align, current); 142 mem_fill_frnd(audiobuf + align, current);
125 if (current != rb->write(fd, buf_start + align, current)) 143 if (current != rb->write(fd, audiobuf + align, current))
126 { 144 {
127 rb->splash(0, "Write error."); 145 rb->splash(0, "write() failed.");
128 rb->close(fd); 146 rb->close(fd);
129 goto error; 147 goto error;
130 } 148 }
@@ -135,7 +153,7 @@ static bool test_fs(void)
135 fd = rb->open(TEST_FILE, O_RDONLY); 153 fd = rb->open(TEST_FILE, O_RDONLY);
136 if (fd < 0) 154 if (fd < 0)
137 { 155 {
138 rb->splash(0, "Couldn't open testfile."); 156 rb->splash(0, "open() failed.");
139 goto error; 157 goto error;
140 } 158 }
141 159
@@ -143,33 +161,34 @@ static bool test_fs(void)
143 total = TEST_SIZE; 161 total = TEST_SIZE;
144 while (total > 0) 162 while (total > 0)
145 { 163 {
146 current = rb->rand() % buf_len; 164 current = rb->rand() % (audiobuflen - 4);
147 current = MIN(current, total); 165 current = MIN(current, total);
148 align = rb->rand() & 3; 166 align = rb->rand() & 3;
149 rb->snprintf(text_buf, sizeof text_buf, "Cmp %dKB, %dKB left", 167 rb->snprintf(text_buf, sizeof text_buf, "Cmp %dKB, %dKB left",
150 current >> 10, total >> 10); 168 current >> 10, total >> 10);
151 log_lcd(text_buf, false); 169 log_text(text_buf, false);
152 170
153 if (current != rb->read(fd, buf_start + align, current)) 171 if (current != rb->read(fd, audiobuf + align, current))
154 { 172 {
155 rb->splash(0, "Read error."); 173 rb->splash(0, "read() failed.");
156 rb->close(fd); 174 rb->close(fd);
157 goto error; 175 goto error;
158 } 176 }
159 if (!mem_cmp_frnd(buf_start + align, current)) 177 if (!mem_cmp_frnd(audiobuf + align, current))
160 { 178 {
161 log_lcd(text_buf, true); 179 log_text(text_buf, true);
162 log_lcd("Compare error.", true); 180 log_text("Compare error.", true);
163 rb->close(fd); 181 rb->close(fd);
164 goto error; 182 goto error;
165 } 183 }
166 total -= current; 184 total -= current;
167 } 185 }
168 rb->close(fd); 186 rb->close(fd);
169 log_lcd(text_buf, true); 187 log_text(text_buf, true);
170 log_lcd("Test passed.", true); 188 log_text("Test passed.", true);
171 189
172error: 190error:
191 log_close();
173 rb->remove(TEST_FILE); 192 rb->remove(TEST_FILE);
174 rb->button_clear_queue(); 193 rb->button_clear_queue();
175 rb->button_get(true); 194 rb->button_get(true);
@@ -177,123 +196,204 @@ error:
177 return false; 196 return false;
178} 197}
179 198
180static bool test_speed(void) 199static bool file_speed(int chunksize, bool align)
181{ 200{
182 unsigned char text_buf[32]; 201 unsigned char text_buf[64];
183 unsigned char *buf_start;
184 long time;
185 int buf_len;
186 int fd; 202 int fd;
203 long filesize = 0;
204 long size, time;
205
206 if (chunksize >= audiobuflen)
207 return false;
187 208
188 buf_len = (-(int)audiobuf) & 3; 209 log_text("--------------------", true);
189 buf_start = audiobuf + buf_len;
190 buf_len = (audiobufsize - buf_len) & ~3;
191 rb->memset(buf_start, 'T', buf_len);
192 buf_len -= 2;
193
194 log_init();
195 log_lcd("Disk speed test", true);
196 210
211 /* File creation write speed */
197 fd = rb->creat(TEST_FILE); 212 fd = rb->creat(TEST_FILE);
198 if (fd < 0) 213 if (fd < 0)
199 { 214 {
200 rb->splash(0, "Couldn't create testfile."); 215 rb->splash(HZ, "creat() failed.");
201 goto error; 216 goto error;
202 } 217 }
203 time = *rb->current_tick; 218 time = *rb->current_tick;
204 if (buf_len != rb->write(fd, buf_start, buf_len)) 219 while (TIME_BEFORE(*rb->current_tick, time + TEST_TIME*HZ))
205 { 220 {
206 rb->splash(0, "Write error."); 221 if (chunksize != rb->write(fd, audiobuf + (align ? 0 : 1), chunksize))
207 rb->close(fd); 222 {
208 goto error; 223 rb->splash(HZ, "write() failed.");
224 rb->close(fd);
225 goto error;
226 }
227 filesize += chunksize;
209 } 228 }
210 time = *rb->current_tick - time; 229 time = *rb->current_tick - time;
211 rb->snprintf(text_buf, sizeof text_buf, "Create: %ld KByte/s",
212 (25 * buf_len / time) >> 8);
213 log_lcd(text_buf, true);
214 rb->close(fd); 230 rb->close(fd);
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);
215 234
235 /* Existing file write speed */
216 fd = rb->open(TEST_FILE, O_WRONLY); 236 fd = rb->open(TEST_FILE, O_WRONLY);
217 if (fd < 0) 237 if (fd < 0)
218 { 238 {
219 rb->splash(0, "Couldn't open testfile."); 239 rb->splash(0, "open() failed.");
220 goto error; 240 goto error;
221 } 241 }
222 time = *rb->current_tick; 242 time = *rb->current_tick;
223 if (buf_len != rb->write(fd, buf_start, buf_len)) 243 for (size = filesize; size > 0; size -= chunksize)
224 { 244 {
225 rb->splash(0, "Write error."); 245 if (chunksize != rb->write(fd, audiobuf + (align ? 0 : 1), chunksize))
226 rb->close(fd); 246 {
227 goto error; 247 rb->splash(0, "write() failed.");
248 rb->close(fd);
249 goto error;
250 }
228 } 251 }
229 time = *rb->current_tick - time; 252 time = *rb->current_tick - time;
230 rb->snprintf(text_buf, sizeof text_buf, "Write A: %ld KByte/s",
231 (25 * buf_len / time) >> 8);
232 log_lcd(text_buf, true);
233 rb->close(fd); 253 rb->close(fd);
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);
234 257
235 fd = rb->open(TEST_FILE, O_WRONLY); 258 /* File read speed */
259 fd = rb->open(TEST_FILE, O_RDONLY);
236 if (fd < 0) 260 if (fd < 0)
237 { 261 {
238 rb->splash(0, "Couldn't open testfile."); 262 rb->splash(0, "open() failed.");
239 goto error; 263 goto error;
240 } 264 }
241 time = *rb->current_tick; 265 time = *rb->current_tick;
242 if (buf_len != rb->write(fd, buf_start + 1, buf_len)) 266 for (size = filesize; size > 0; size -= chunksize)
243 { 267 {
244 rb->splash(0, "Write error."); 268 if (chunksize != rb->read(fd, audiobuf + (align ? 0 : 1), chunksize))
245 rb->close(fd); 269 {
246 goto error; 270 rb->splash(0, "read() failed.");
271 rb->close(fd);
272 goto error;
273 }
247 } 274 }
248 time = *rb->current_tick - time; 275 time = *rb->current_tick - time;
249 rb->snprintf(text_buf, sizeof text_buf, "Write U: %ld KByte/s",
250 (25 * buf_len / time) >> 8);
251 log_lcd(text_buf, true);
252 rb->close(fd); 276 rb->close(fd);
253 277 rb->snprintf(text_buf, sizeof text_buf, "Read (%d,%c): %ld KB/s",
254 fd = rb->open(TEST_FILE, O_RDONLY); 278 chunksize, align ? 'A' : 'U', (25 * filesize / time) >> 8);
255 if (fd < 0) 279 log_text(text_buf, true);
280 rb->remove(TEST_FILE);
281 return true;
282
283 error:
284 rb->remove(TEST_FILE);
285 return false;
286}
287
288static bool test_speed(void)
289{
290 unsigned char text_buf[64];
291 DIR *dir = NULL;
292 struct dirent *entry = NULL;
293 int fd, last_file;
294 int i, n;
295 long time;
296
297 rb->memset(audiobuf, 'T', audiobuflen);
298 log_init();
299 log_text("test_disk SPEED TEST", true);
300 rb->snprintf(text_buf, sizeof(text_buf), "CPU clock: %ld Hz",
301 *rb->cpu_frequency);
302 log_text(text_buf, true);
303 log_text("--------------------", true);
304
305 /* File creation speed */
306 time = *rb->current_tick + TEST_TIME*HZ;
307 for (i = 0; TIME_BEFORE(*rb->current_tick, time); i++)
256 { 308 {
257 rb->splash(0, "Couldn't open testfile."); 309 rb->snprintf(text_buf, sizeof(text_buf), TESTBASEDIR "/%08x.tmp", i);
258 goto error; 310 fd = rb->creat(text_buf);
311 if (fd < 0)
312 {
313 last_file = i;
314 rb->splash(HZ, "creat() failed.");
315 goto error;
316 }
317 rb->close(fd);
259 } 318 }
260 time = *rb->current_tick; 319 last_file = i;
261 if (buf_len != rb->read(fd, buf_start, buf_len)) 320 rb->snprintf(text_buf, sizeof(text_buf), "Create: %d files/s",
321 last_file / TEST_TIME);
322 log_text(text_buf, true);
323
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++)
262 { 327 {
263 rb->splash(0, "Read error."); 328 if (i >= last_file)
329 i = 0;
330 rb->snprintf(text_buf, sizeof(text_buf), TESTBASEDIR "/%08x.tmp", i);
331 fd = rb->open(text_buf, O_RDONLY);
332 if (fd < 0)
333 {
334 rb->splash(HZ, "open() failed.");
335 goto error;
336 }
264 rb->close(fd); 337 rb->close(fd);
265 goto error;
266 } 338 }
267 time = *rb->current_tick - time; 339 rb->snprintf(text_buf, sizeof(text_buf), "Open: %d files/s", n / TEST_TIME);
268 rb->snprintf(text_buf, sizeof text_buf, "Read A: %ld KByte/s", 340 log_text(text_buf, true);
269 (25 * buf_len / time) >> 8); 341
270 log_lcd(text_buf, true); 342 /* Directory scan speed */
271 rb->close(fd); 343 time = *rb->current_tick + TEST_TIME*HZ;
272 344 for (n = 0; TIME_BEFORE(*rb->current_tick, time); n++)
273 fd = rb->open(TEST_FILE, O_RDONLY);
274 if (fd < 0)
275 { 345 {
276 rb->splash(0, "Couldn't open testfile."); 346 if (entry == NULL)
277 goto error; 347 {
348 if (dir != NULL)
349 rb->closedir(dir);
350 dir = rb->opendir(testbasedir);
351 if (dir == NULL)
352 {
353 rb->splash(HZ, "opendir() failed.");
354 goto error;
355 }
356 }
357 entry = rb->readdir(dir);
278 } 358 }
359 rb->closedir(dir);
360 rb->snprintf(text_buf, sizeof(text_buf), "Dirscan: %d files/s", n / TEST_TIME);
361 log_text(text_buf, true);
362
363 /* File delete speed */
279 time = *rb->current_tick; 364 time = *rb->current_tick;
280 if (buf_len != rb->read(fd, buf_start + 1, buf_len)) 365 for (i = 0; i < last_file; i++)
281 { 366 {
282 rb->splash(0, "Read error."); 367 rb->snprintf(text_buf, sizeof(text_buf), TESTBASEDIR "/%08x.tmp", i);
283 rb->close(fd); 368 rb->remove(text_buf);
284 goto error;
285 } 369 }
286 time = *rb->current_tick - time; 370 rb->snprintf(text_buf, sizeof(text_buf), "Delete: %ld files/s",
287 rb->snprintf(text_buf, sizeof text_buf, "Read U: %ld KByte/s", 371 last_file * HZ / (*rb->current_tick - time));
288 (25 * buf_len / time) >> 8); 372 log_text(text_buf, true);
289 log_lcd(text_buf, true); 373
290 rb->close(fd); 374 if (file_speed(512, true)
291 375 && file_speed(512, false)
292error: 376 && file_speed(4096, true)
293 rb->remove(TEST_FILE); 377 && file_speed(4096, false)
378 && file_speed(1048576, true))
379 file_speed(1048576, false);
380
381 log_text("DONE", false);
382 log_close();
294 rb->button_clear_queue(); 383 rb->button_clear_queue();
295 rb->button_get(true); 384 rb->button_get(true);
385 return false;
296 386
387 error:
388 for (i = 0; i < last_file; i++)
389 {
390 rb->snprintf(text_buf, sizeof(text_buf), TESTBASEDIR "/%08x.tmp", i);
391 rb->remove(text_buf);
392 }
393 log_text("DONE", false);
394 log_close();
395 rb->button_clear_queue();
396 rb->button_get(true);
297 return false; 397 return false;
298} 398}
299 399
@@ -303,13 +403,34 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
303{ 403{
304 static const struct menu_item items[] = { 404 static const struct menu_item items[] = {
305 { "Disk speed", test_speed }, 405 { "Disk speed", test_speed },
306 { "FS stress test", test_fs }, 406 { "Write & verify", test_fs },
307 }; 407 };
308 int m; 408 int m;
409 int align;
410 DIR *dir;
309 411
310 (void)parameter; 412 (void)parameter;
311 rb = api; 413 rb = api;
312 audiobuf = rb->plugin_get_audio_buffer((size_t *)&audiobufsize); 414
415 if ((dir = rb->opendir(testbasedir)) == NULL)
416 {
417 if (rb->mkdir(testbasedir) < 0)
418 {
419 rb->splash(HZ*2, "Can't create test directory.");
420 return PLUGIN_ERROR;
421 }
422 }
423 else
424 {
425 rb->closedir(dir);
426 }
427
428 audiobuf = rb->plugin_get_audio_buffer((size_t *)&audiobuflen);
429 /* align start and length to 32 bit */
430 align = (-(int)audiobuf) & 3;
431 audiobuf += align;
432 audiobuflen = (audiobuflen - align) & ~3;
433
313 rb->srand(*rb->current_tick); 434 rb->srand(*rb->current_tick);
314 435
315 if (rb->global_settings->backlight_timeout > 0) 436 if (rb->global_settings->backlight_timeout > 0)
@@ -322,6 +443,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
322 443
323 /* restore normal backlight setting */ 444 /* restore normal backlight setting */
324 rb->backlight_set_timeout(rb->global_settings->backlight_timeout); 445 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
446
447 rb->rmdir(testbasedir);
325 448
326 return PLUGIN_OK; 449 return PLUGIN_OK;
327} 450}