1 /* This FileX test concentrates on the Fault-Tolerant FAT write interrupt operation. */
2 /*
3 For FAT 12, 16, 32, one cluster size is 1024 bytes;
4
5 Check fat interrupt for fx_file_delete():
6 Step1: Format and open the media;
7 Step2: Enable fault tolerant feature;
8 Step3: Create and write 28 bytes into TEST.TXT;
9 Step4: Create and write 26 bytes into TEST1.TXT;
10 Step5: Create and write 19 bytes into TEST2.TXT;
11 Step6: Create new thread to delete TEST2.TXT;
12 Step7: Terminate the new thread to simulate poweroff when update the fat after record the redo log.
13 Step8: Open the media;
14 Step9: Enable fault tolerant feature to recover the data(redo operation);
15 Step10: Check the test files.
16 */
17
18 #ifndef FX_STANDALONE_ENABLE
19 #include "tx_api.h"
20 #else
21 #define _GNU_SOURCE
22 #define _DEFAULT_SOURCE
23 #include <pthread.h>
24 #include <unistd.h>
25 #endif
26 #include "fx_api.h"
27 #include "fx_system.h"
28 #include "fx_fault_tolerant.h"
29 #include <stdio.h>
30 #include "fx_ram_driver_test.h"
31 extern void test_control_return(UINT status);
32 void filex_fault_tolerant_file_delete_fat_interrupt_test_application_define(void *first_unused_memory);
33
34 #if defined (FX_ENABLE_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT_DATA)
35
36 #define DEMO_STACK_SIZE 4096
37 #define CACHE_SIZE 2048
38 #define FAULT_TOLERANT_SIZE FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
39
40
41
42
43 /* Define the ThreadX and FileX object control blocks... */
44
45 #ifndef FX_STANDALONE_ENABLE
46 static TX_THREAD ftest_0;
47 static TX_THREAD ftest_1;
48 #else
49 static pthread_t ptid1;
50 #endif
51 static FX_MEDIA ram_disk;
52 static FX_FILE my_file;
53 static UCHAR *pointer;
54
55 /* Define the counters used in the test application... */
56
57 #ifndef FX_STANDALONE_ENABLE
58 static UCHAR *cache_buffer;
59 static UCHAR *fault_tolerant_buffer;
60 static UCHAR *thread_buffer;
61 #else
62 static UCHAR cache_buffer[CACHE_SIZE];
63 static UCHAR fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
64 #endif
65 static UINT error_couter = 0;
66 static UINT fat_write_interrupt = FX_FALSE;
67 static CHAR read_buffer[1024];
68 static UINT read_buffer_size = 1024;
69
70 #define TEST_COUNT 3
71
72 /* Define thread prototypes. */
73
74 static void ftest_0_entry(ULONG thread_input);
75 #ifndef FX_STANDALONE_ENABLE
76 static void ftest_1_entry(ULONG thread_input);
77 #else
78 static void * ftest_1_entry(void * thread_input);
79 #endif
80
81 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
82 extern void test_control_return(UINT status);
83 extern UINT _filex_fault_tolerant_log_check(FX_MEDIA *media_ptr);
84 extern UINT (*driver_write_callback)(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
85 static UINT my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
86
87
88
89 /* Define what the initial system looks like. */
90
91 #ifdef CTEST
test_application_define(void * first_unused_memory)92 void test_application_define(void *first_unused_memory)
93 #else
94 void filex_fault_tolerant_file_delete_fat_interrupt_test_application_define(void *first_unused_memory)
95 #endif
96 {
97
98
99 #ifndef FX_STANDALONE_ENABLE
100 /* Setup the working pointer. */
101 pointer = (UCHAR *) first_unused_memory;
102
103 /* Create the main thread. */
104
105 tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
106 pointer, DEMO_STACK_SIZE,
107 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
108
109 pointer = pointer + DEMO_STACK_SIZE;
110
111 /* Setup memory for the RAM disk and the sector cache. */
112 cache_buffer = pointer;
113 pointer += CACHE_SIZE;
114 fault_tolerant_buffer = pointer;
115 pointer += FAULT_TOLERANT_SIZE;
116 thread_buffer = pointer;
117 pointer += DEMO_STACK_SIZE;
118 #endif
119
120 /* Initialize the FileX system. */
121 fx_system_initialize();
122 #ifdef FX_STANDALONE_ENABLE
123 ftest_0_entry(0);
124 #endif
125 }
126
127
128
129 /* Define the test threads. */
130
ftest_0_entry(ULONG thread_input)131 static void ftest_0_entry(ULONG thread_input)
132 {
133
134 UINT status;
135 ULONG actual;
136 UINT i;
137
138 FX_PARAMETER_NOT_USED(thread_input);
139
140 /* Print out some test information banners. */
141 printf("FileX Test: Fault Tolerant File Delete FAT Interrupt Test..........");
142
143 /* Loop to test FAT 12, 16, 32. */
144 for (i = 0; i < TEST_COUNT; i ++)
145 {
146 if (i == 0)
147 {
148 /* Format the media with FAT12. This needs to be done before opening it! */
149 status = fx_media_format(&ram_disk,
150 _fx_ram_driver, // Driver entry
151 ram_disk_memory_large, // RAM disk memory pointer
152 cache_buffer, // Media buffer pointer
153 CACHE_SIZE, // Media buffer size
154 "MY_RAM_DISK", // Volume Name
155 1, // Number of FATs
156 32, // Directory Entries
157 0, // Hidden sectors
158 256, // Total sectors
159 256, // Sector size
160 8, // Sectors per cluster
161 1, // Heads
162 1); // Sectors per track
163 }
164 else if (i == 1)
165 {
166 /* Format the media with FAT16. This needs to be done before opening it! */
167 status = fx_media_format(&ram_disk,
168 _fx_ram_driver, // Driver entry
169 ram_disk_memory_large, // RAM disk memory pointer
170 cache_buffer, // Media buffer pointer
171 CACHE_SIZE, // Media buffer size
172 "MY_RAM_DISK", // Volume Name
173 1, // Number of FATs
174 32, // Directory Entries
175 0, // Hidden sectors
176 4200 * 8, // Total sectors
177 256, // Sector size
178 8, // Sectors per cluster
179 1, // Heads
180 1); // Sectors per track
181 }
182 else if (i == 2)
183 {
184 /* Format the media with FAT32. This needs to be done before opening it! */
185 status = fx_media_format(&ram_disk,
186 _fx_ram_driver, // Driver entry
187 ram_disk_memory_large, // RAM disk memory pointer
188 cache_buffer, // Media buffer pointer
189 CACHE_SIZE, // Media buffer size
190 "MY_RAM_DISK", // Volume Name
191 1, // Number of FATs
192 32, // Directory Entries
193 0, // Hidden sectors
194 70000 * 8, // Total sectors
195 256, // Sector size
196 8, // Sectors per cluster
197 1, // Heads
198 1); // Sectors per track
199 }
200
201 /* Determine if the format had an error. */
202 if (status)
203 {
204
205 printf("ERROR!\n");
206 test_control_return(1);
207 }
208
209 /* Open the ram_disk. */
210 status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
211
212 /* Check the status. */
213 if (status != FX_SUCCESS)
214 {
215
216 /* Error, return error code. */
217 printf("ERROR!\n");
218 test_control_return(2);
219 }
220
221 /* Enable the Fault-tolerant feature. */
222 status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
223
224 /* Check status. */
225 if (status)
226 {
227
228 printf("ERROR!\n");
229 test_control_return(3);
230 }
231
232 /* Create a file called TEST.TXT in the root directory. */
233 status = fx_file_create(&ram_disk, "TEST.TXT");
234
235 /* Check the create status. */
236 if (status != FX_SUCCESS)
237 {
238
239 printf("ERROR!\n");
240 test_control_return(4);
241 }
242
243 /* Open the test file. */
244 status = fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
245
246 /* Check the file open status. */
247 if (status != FX_SUCCESS)
248 {
249
250 printf("ERROR!\n");
251 test_control_return(5);
252 }
253
254 /* Write a string to the test file. */
255 status = fx_file_write(&my_file, " ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 28);
256
257 /* Check the file write status. */
258 if (status != FX_SUCCESS)
259 {
260
261 printf("ERROR!\n");
262 test_control_return(6);
263 }
264
265 /* Seek to the beginning of the test file. */
266 status = fx_file_seek(&my_file, 0);
267
268 /* Check the file seek status. */
269 if (status != FX_SUCCESS)
270 {
271
272 printf("ERROR!\n");
273 test_control_return(7);
274 }
275
276 /* Read the bytes of the test file. */
277 status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
278
279 /* Check the file read status. */
280 if ((status != FX_SUCCESS) || (actual != 28))
281 {
282
283 printf("ERROR!\n");
284 test_control_return(8);
285 }
286
287 /* Close the test file. */
288 status = fx_file_close(&my_file);
289
290 /* Check the file close status. */
291 if (status != FX_SUCCESS)
292 {
293
294 printf("ERROR!\n");
295 test_control_return(9);
296 }
297
298 /* Create a file called TEST1.TXT in the root directory. */
299 status = fx_file_create(&ram_disk, "TEST1.TXT");
300
301 /* Check the create status. */
302 if (status != FX_SUCCESS)
303 {
304
305 printf("ERROR!\n");
306 test_control_return(10);
307 }
308
309 /* Open the test file. */
310 status = fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
311
312 /* Check the file open status. */
313 if (status != FX_SUCCESS)
314 {
315
316 printf("ERROR!\n");
317 test_control_return(11);
318 }
319
320 /* Write a string to the test file. */
321 status = fx_file_write(&my_file, " 012345678901234567890123\n", 26);
322
323 /* Check the file write status. */
324 if (status != FX_SUCCESS)
325 {
326
327 printf("ERROR!\n");
328 test_control_return(12);
329 }
330
331 /* Seek to the beginning of the test file. */
332 status = fx_file_seek(&my_file, 0);
333
334 /* Check the file seek status. */
335 if (status != FX_SUCCESS)
336 {
337
338 printf("ERROR!\n");
339 test_control_return(13);
340 }
341
342 /* Read the bytes of the test file. */
343 status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
344
345 /* Check the file read status. */
346 if ((status != FX_SUCCESS) || (actual != 26))
347 {
348
349 printf("ERROR!\n");
350 test_control_return(14);
351 }
352
353 /* Close the test file. */
354 status = fx_file_close(&my_file);
355
356 /* Check the file close status. */
357 if (status != FX_SUCCESS)
358 {
359
360 printf("ERROR!\n");
361 test_control_return(15);
362 }
363
364 /* Create a file called TEST2.TXT in the root directory. */
365 status = fx_file_create(&ram_disk, "TEST2.TXT");
366
367 /* Check the create status. */
368 if (status != FX_SUCCESS)
369 {
370
371 printf("ERROR!\n");
372 test_control_return(16);
373 }
374
375 /* Open the test file. */
376 status = fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
377
378 /* Check the file open status. */
379 if (status != FX_SUCCESS)
380 {
381
382 printf("ERROR!\n");
383 test_control_return(17);
384 }
385
386 /* Write a string to the test file. */
387 status = fx_file_write(&my_file, " EXPRESSLOGIC_TEST\n", 19);
388
389 /* Check the file write status. */
390 if (status != FX_SUCCESS)
391 {
392
393 printf("ERROR!\n");
394 test_control_return(18);
395 }
396
397 /* Seek to the beginning of the test file. */
398 status = fx_file_seek(&my_file, 0);
399
400 /* Check the file seek status. */
401 if (status != FX_SUCCESS)
402 {
403
404 printf("ERROR!\n");
405 test_control_return(19);
406 }
407
408 /* Read the bytes of the test file. */
409 status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
410
411 /* Check the file read status. */
412 if ((status != FX_SUCCESS) || (actual != 19))
413 {
414
415 printf("ERROR!\n");
416 test_control_return(20);
417 }
418
419 /* Close the test file. */
420 status = fx_file_close(&my_file);
421
422 /* Check the file close status. */
423 if (status != FX_SUCCESS)
424 {
425
426 printf("ERROR!\n");
427 test_control_return(21);
428 }
429
430 /* Create the main thread. */
431 #ifndef FX_STANDALONE_ENABLE
432 tx_thread_create(&ftest_1, "thread 1", ftest_1_entry, 0,
433 thread_buffer, DEMO_STACK_SIZE,
434 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
435 #endif
436
437 /* directory_write_interrupt */
438 fat_write_interrupt = FX_FALSE;
439
440 /* Let the other thread run. */
441 #ifndef FX_STANDALONE_ENABLE
442 tx_thread_relinquish();
443 #else
444 pthread_create(&ptid1, NULL, &ftest_1_entry, NULL);
445 usleep(10);
446 pthread_join(ptid1,NULL);
447
448 #endif
449
450 /* After write interrupt, reread the files. */
451
452 /* Open the ram_disk. */
453 status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
454
455 /* Check the status. */
456 if (status != FX_SUCCESS)
457 {
458
459 /* Error, return error code. */
460 printf("ERROR!\n");
461 test_control_return(22);
462 }
463
464 /* Enable the Fault-tolerant feature to recover the media. */
465 status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
466
467 /* Check status. */
468 if (status)
469 {
470
471 printf("ERROR!\n");
472 test_control_return(23);
473 }
474
475 /* Open the test file. */
476 status = fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
477
478 /* Check the file open status. */
479 if (status != FX_SUCCESS)
480 {
481
482 printf("ERROR!\n");
483 test_control_return(24);
484 }
485
486 /* Seek to the beginning of the test file. */
487 status = fx_file_seek(&my_file, 0);
488
489 /* Check the file seek status. */
490 if (status != FX_SUCCESS)
491 {
492
493 printf("ERROR!\n");
494 test_control_return(25);
495 }
496
497 /* Read the bytes of the test file. */
498 status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
499
500 /* Check the file read status. */
501 if ((status != FX_SUCCESS) || (actual != 28))
502 {
503
504 printf("ERROR!\n");
505 test_control_return(26);
506 }
507
508 /* Close the test file. */
509 status = fx_file_close(&my_file);
510
511 /* Check the file close status. */
512 if (status != FX_SUCCESS)
513 {
514
515 printf("ERROR!\n");
516 test_control_return(27);
517 }
518
519 /* Open the test file. */
520 status = fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
521
522 /* Check the file open status. */
523 if (status != FX_SUCCESS)
524 {
525
526 printf("ERROR!\n");
527 test_control_return(28);
528 }
529
530 /* Seek to the beginning of the test file. */
531 status = fx_file_seek(&my_file, 0);
532
533 /* Check the file seek status. */
534 if (status != FX_SUCCESS)
535 {
536
537 printf("ERROR!\n");
538 test_control_return(29);
539 }
540
541 /* Read the bytes of the test file. */
542 status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
543
544 /* Check the file read status. */
545 if ((status != FX_SUCCESS) || (actual != 26))
546 {
547
548 printf("ERROR!\n");
549 test_control_return(30);
550 }
551
552 /* Close the test file. */
553 status = fx_file_close(&my_file);
554
555 /* Check the file close status. */
556 if (status != FX_SUCCESS)
557 {
558
559 printf("ERROR!\n");
560 test_control_return(31);
561 }
562
563 /* Open the test file. */
564 status = fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
565
566 /* Check the file open status. */
567 if (status == FX_SUCCESS)
568 {
569
570 printf("ERROR!\n");
571 test_control_return(32);
572 }
573
574 /* Close the media. */
575 status = fx_media_close(&ram_disk);
576
577 /* Determine if the test was successful. */
578 if ((status != FX_SUCCESS) || (fat_write_interrupt != FX_TRUE) || (error_couter))
579 {
580
581 printf("ERROR!\n");
582 test_control_return(33);
583 }
584
585 /* Delete the thread. */
586 #ifndef FX_STANDALONE_ENABLE
587 tx_thread_delete(&ftest_1);
588 #else
589 pthread_cancel(ptid1);
590 #endif
591 }
592
593 /* Output successful. */
594 printf("SUCCESS!\n");
595 test_control_return(0);
596
597 }
598
599 /* Define the test threads. */
600 #ifndef FX_STANDALONE_ENABLE
ftest_1_entry(ULONG thread_input)601 static void ftest_1_entry(ULONG thread_input)
602 #else
603 void * ftest_1_entry(void * thread_input)
604 #endif
605 {
606 #ifdef FX_STANDALONE_ENABLE
607 UINT oldtype;
608 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
609 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
610 #endif
611
612 FX_PARAMETER_NOT_USED(thread_input);
613
614 /* Set the callback function to simulate poweoff operation when write FAT entry. */
615 driver_write_callback = my_driver_write;
616
617 /* Create a file called TEST2.TXT in the root directory. */
618 fx_file_delete(&ram_disk, "TEST2.TXT");
619 }
620
my_driver_write(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)621 static UINT my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
622 {
623
624 FX_PARAMETER_NOT_USED(block_ptr);
625
626 /* Interrupt the FAT write operation after record the redo log. */
627 if ((sector_type == FX_FAT_SECTOR) && (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_DONE))
628 {
629
630 /* Set the write interrupt operation. */
631 *operation_ptr = FX_OP_WRITE_INTERRUPT;
632
633 /* Update the flag. */
634 fat_write_interrupt = FX_TRUE;
635
636 /* Clean the callback function. */
637 driver_write_callback = FX_NULL;
638
639 /* Delete the media protection structure if FX_SINGLE_THREAD is not
640 defined. */
641 #ifndef FX_SINGLE_THREAD
642 #ifndef FX_DONT_CREATE_MUTEX
643
644 /* Note that the protection is never released. The mutex delete
645 service will handle all threads waiting access to this media
646 control block. */
647 tx_mutex_delete(&(media_ptr -> fx_media_protect));
648 #endif
649 #endif
650
651 /* Clean the media data. */
652 _fx_system_media_opened_ptr = FX_NULL;
653 _fx_system_media_opened_count = 0;
654
655 /* Clean the media. */
656 memset(media_ptr, 0, sizeof(FX_MEDIA));
657
658 /* Simulate poweroff. */
659 /* First terminate the thread to ensure it is ready for deletion. */
660 #ifndef FX_STANDALONE_ENABLE
661 tx_thread_terminate(&ftest_1);
662 #else
663 pthread_cancel(ptid1);
664 #endif
665 }
666
667 /* Return. */
668 return FX_SUCCESS;
669 }
670 #else
671
672 #ifdef CTEST
test_application_define(void * first_unused_memory)673 void test_application_define(void *first_unused_memory)
674 #else
675 void filex_fault_tolerant_file_delete_fat_interrupt_test_application_define(void *first_unused_memory)
676 #endif
677 {
678
679 FX_PARAMETER_NOT_USED(first_unused_memory);
680
681 /* Print out some test information banners. */
682 printf("FileX Test: Fault Tolerant File Delete FAT Interrupt Test..........N/A\n");
683
684 test_control_return(255);
685 }
686 #endif
687
688