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