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