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