1 #ifndef FX_STANDALONE_ENABLE
2 #include   "tx_api.h"
3 #else
4 #define    _GNU_SOURCE
5 #define    _DEFAULT_SOURCE
6 #include   <pthread.h>
7 #include   <unistd.h>
8 #endif
9 #include   "fx_api.h"
10 #include   "fx_system.h"
11 #include   "fx_utility.h"
12 #include   "fx_fault_tolerant.h"
13 #include   <stdio.h>
14 #include   "fx_ram_driver_test.h"
15 extern void    test_control_return(UINT status);
16 void    filex_fault_tolerant_enable_4_test_application_define(void *first_unused_memory);
17 
18 #if defined (FX_ENABLE_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT_DATA)
19 
20 #define DEMO_STACK_SIZE         4096
21 #define CACHE_SIZE              2048
22 #define FAULT_TOLERANT_SIZE     FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
23 
24 
25 /* Define the ThreadX and FileX object control blocks...  */
26 
27 #ifndef FX_STANDALONE_ENABLE
28 static TX_THREAD                ftest_0;
29 static TX_THREAD                ftest_1;
30 #else
31 static pthread_t                ptid1;
32 #endif
33 static FX_MEDIA                 ram_disk;
34 static FX_FILE                  my_file;
35 static UCHAR                    *pointer;
36 
37 /* Define the counters used in the test application...  */
38 
39 #ifndef FX_STANDALONE_ENABLE
40 static UCHAR                    *cache_buffer;
41 static UCHAR                    *fault_tolerant_buffer;
42 static UCHAR                    *thread_buffer;
43 #else
44 static UCHAR                    cache_buffer[CACHE_SIZE];
45 static UCHAR                    fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
46 #endif
47 static UINT                     directory_write_interrupt = FX_FALSE;
48 static CHAR                     write_buffer[2048];
49 static UCHAR                    read_buffer[4096];
50 
51 /* Define thread prototypes.  */
52 
53 static void    ftest_0_entry(ULONG thread_input);
54 #ifndef FX_STANDALONE_ENABLE
55 static void    ftest_1_entry(ULONG thread_input);
56 #else
57 static void    *ftest_1_entry(void * thread_input);
58 #endif
59 
60 extern void    _fx_ram_driver(FX_MEDIA *media_ptr);
61 extern void    test_control_return(UINT status);
62 extern UINT    _filex_fault_tolerant_log_check(FX_MEDIA *media_ptr);
63 extern UINT    (*driver_write_callback)(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
64 static UINT    my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
65 
66 
67 
68 /* Define what the initial system looks like.  */
69 
70 #ifdef CTEST
test_application_define(void * first_unused_memory)71 void test_application_define(void *first_unused_memory)
72 #else
73 void    filex_fault_tolerant_enable_4_test_application_define(void *first_unused_memory)
74 #endif
75 {
76 #ifndef FX_STANDALONE_ENABLE
77     /* Setup the working pointer.  */
78     pointer =  (UCHAR *) first_unused_memory;
79 
80     /* Create the main thread.  */
81 
82     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
83             pointer, DEMO_STACK_SIZE,
84             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
85 
86     pointer =  pointer + DEMO_STACK_SIZE;
87 
88     /* Setup memory for the RAM disk and the sector cache.  */
89     cache_buffer =  pointer;
90     pointer += CACHE_SIZE;
91     fault_tolerant_buffer = pointer;
92     pointer += FAULT_TOLERANT_SIZE;
93     thread_buffer = pointer;
94     pointer += DEMO_STACK_SIZE;
95 #endif
96 
97     /* Initialize the FileX system.  */
98     fx_system_initialize();
99 #ifdef FX_STANDALONE_ENABLE
100     ftest_0_entry(0);
101 #endif
102 }
103 
104 
105 
106 /* Define the test threads.  */
107 
ftest_0_entry(ULONG thread_input)108 static void    ftest_0_entry(ULONG thread_input)
109 {
110 
111 UINT        status;
112 
113     FX_PARAMETER_NOT_USED(thread_input);
114 
115     /* Print out some test information banners.  */
116     printf("FileX Test:   Fault Tolerant Enable 4 Test...........................");
117 
118     /* Format the media with FAT16.  This needs to be done before opening it!  */
119     status =  fx_media_format(&ram_disk,
120                                  _fx_ram_driver,         // Driver entry
121                                  ram_disk_memory_large,  // RAM disk memory pointer
122                                  cache_buffer,           // Media buffer pointer
123                                  CACHE_SIZE,             // Media buffer size
124                                  "MY_RAM_DISK",          // Volume Name
125                                  1,                      // Number of FATs
126                                  32,                     // Directory Entries
127                                  0,                      // Hidden sectors
128                                  4200 * 8,               // Total sectors
129                                  256,                    // Sector size
130                                  8,                      // Sectors per cluster
131                                  1,                      // Heads
132                                  1);                     // Sectors per track
133     status += fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
134     return_if_fail(status == FX_SUCCESS);
135 
136     /* Enable the Fault-tolerant feature.  */
137     status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
138     return_if_fail(status == FX_SUCCESS);
139 
140     /* Create a file called TEST1.TXT in the root directory.  */
141     status = fx_file_create(&ram_disk, "TEST1.TXT");
142     return_if_fail(status == FX_SUCCESS);
143 #ifndef FX_STANDALONE_ENABLE
144     /* Create the main thread.  */
145     tx_thread_create(&ftest_1, "thread 1", ftest_1_entry, 0,
146                     thread_buffer, DEMO_STACK_SIZE,
147                     4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
148 #endif
149 
150     /* directory_write_interrupt */
151     directory_write_interrupt = FX_FALSE;
152 
153     /* Let the other thread run.  */
154 #ifndef FX_STANDALONE_ENABLE
155     tx_thread_relinquish();
156 #else
157     pthread_create(&ptid1, NULL, &ftest_1_entry, NULL);
158     usleep(10);
159     pthread_join(ptid1,NULL);
160 #endif
161 
162     /* After write interrupt, reread the files.  */
163 
164     /* Open the ram_disk.  */
165     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
166     return_if_fail(status == FX_SUCCESS);
167 
168     /**** Modify the checksum of log content so that the log will not apply. ****/
169     _fx_utility_logical_sector_read( &ram_disk, 1 + ram_disk.fx_media_sectors_per_FAT + ram_disk.fx_media_root_sectors, read_buffer, 8, FX_DATA_SECTOR);
170     read_buffer[FX_FAULT_TOLERANT_LOG_CONTENT_OFFSET]++;
171     _fx_utility_logical_sector_write( &ram_disk, 1 + ram_disk.fx_media_sectors_per_FAT + ram_disk.fx_media_root_sectors, read_buffer, 8, FX_DATA_SECTOR);
172 
173     /* Enable the Fault-tolerant feature to recover the media.  */
174     status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
175     return_if_fail(status == FX_SUCCESS);
176 
177     /* Delete the thread.  */
178 #ifndef FX_STANDALONE_ENABLE
179     tx_thread_delete(&ftest_1);
180 #else
181     pthread_cancel(ptid1);
182 #endif
183     /* Output successful.  */
184     printf("SUCCESS!\n");
185     test_control_return(0);
186 }
187 
188 /* Define the test threads.  */
189 
190 #ifndef FX_STANDALONE_ENABLE
ftest_1_entry(ULONG thread_input)191 static void    ftest_1_entry(ULONG thread_input)
192 #else
193  void  *  ftest_1_entry(void * thread_input)
194 #endif
195 {
196 
197 #ifdef FX_STANDALONE_ENABLE
198     UINT oldtype;
199     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
200     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
201 #endif
202 
203     FX_PARAMETER_NOT_USED(thread_input);
204 
205     /* Set the callback function to simulate poweoff operation when write FAT entry.  */
206     driver_write_callback = my_driver_write;
207 
208     /* Open the test file.  */
209     fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
210     fx_file_seek(&my_file, 0);
211 
212     /* Write something to the file. */
213     fx_file_write(&my_file, (void *) write_buffer, 2048);
214 }
215 
my_driver_write(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)216 static UINT my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
217 {
218 
219     FX_PARAMETER_NOT_USED(block_ptr);
220 
221     /* Interrupt the Directory write operation after record the redo log.  */
222     if ((sector_type == FX_DIRECTORY_SECTOR) && (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_DONE))
223     {
224 
225         /* Set the write interrupt operation.  */
226         *operation_ptr = FX_OP_WRITE_INTERRUPT;
227 
228         /* Update the flag.  */
229         directory_write_interrupt = FX_TRUE;
230 
231         /* Clean the callback function.  */
232         driver_write_callback = FX_NULL;
233 
234         /* Delete the media protection structure if FX_SINGLE_THREAD is not
235         defined.  */
236 #ifndef FX_SINGLE_THREAD
237 #ifndef FX_DONT_CREATE_MUTEX
238 
239         /* Note that the protection is never released. The mutex delete
240         service will handle all threads waiting access to this media
241         control block.  */
242         tx_mutex_delete(&(media_ptr -> fx_media_protect));
243 #endif
244 #endif
245 
246         /* Clean the media data.  */
247         _fx_system_media_opened_ptr = FX_NULL;
248         _fx_system_media_opened_count = 0;
249 
250         /* Clean the media.  */
251         memset(media_ptr, 0, sizeof(FX_MEDIA));
252 
253         /* Simulate poweroff.  */
254         /* First terminate the thread to ensure it is ready for deletion.  */
255 #ifndef FX_STANDALONE_ENABLE
256         tx_thread_terminate(&ftest_1);
257 #else
258         pthread_cancel(ptid1);
259 #endif
260     }
261 
262     /* Return.  */
263     return FX_SUCCESS;
264 }
265 #else
266 
267 #ifdef CTEST
test_application_define(void * first_unused_memory)268 void test_application_define(void *first_unused_memory)
269 #else
270 void    filex_fault_tolerant_enable_4_test_application_define(void *first_unused_memory)
271 #endif
272 {
273 
274     FX_PARAMETER_NOT_USED(first_unused_memory);
275 
276     /* Print out some test information banners.  */
277     printf("FileX Test:   Fault Tolerant Enable 4................................N/A\n");
278 
279     test_control_return(255);
280 }
281 #endif
282 
283