1 /* This FileX test is determined to cover filex_fault_tolerant_file_delete  */
2 
3 
4 
5 #ifndef FX_STANDALONE_ENABLE
6 #include   "tx_api.h"
7 #else
8 #define    _GNU_SOURCE
9 #define    _DEFAULT_SOURCE
10 #include   <pthread.h>
11 #include   <unistd.h>
12 #endif
13 #include   "fx_api.h"
14 #include   "fx_system.h"
15 #include   "fx_fault_tolerant.h"
16 #include   <stdio.h>
17 #include   "fx_ram_driver_test.h"
18 extern void    test_control_return(UINT status);
19 void  filex_fault_tolerant_file_delete_test_application_define(void *first_unused_memory);
20 
21 #if defined (FX_ENABLE_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT_DATA)
22 
23 #define     DEMO_STACK_SIZE         4096
24 #define CACHE_SIZE                  2048
25 #define FAULT_TOLERANT_SIZE         FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
26 
27 
28 
29 
30 /* Define the ThreadX and FileX object control blocks...  */
31 
32 #ifndef FX_STANDALONE_ENABLE
33 static TX_THREAD               ftest_0;
34 static TX_THREAD               ftest_1;
35 #else
36 static pthread_t               ptid1;
37 #endif
38 static FX_MEDIA                ram_disk;
39 static FX_FILE                 my_file;
40 static UCHAR                   *pointer;
41 
42 /* Define the counters used in the test application...  */
43 
44 #ifndef FX_STANDALONE_ENABLE
45 static UCHAR                   *cache_buffer;
46 static UCHAR                   *fault_tolerant_buffer;
47 static UCHAR                   *thread_buffer;
48 #else
49 static UCHAR                   cache_buffer[CACHE_SIZE];
50 static UCHAR                   fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
51 #endif
52 static UINT                    fat_write_interrupt = FX_FALSE;
53 static CHAR                    read_buffer[1024];
54 static UINT                    read_buffer_size = 1024;
55 
56 #define TEST_COUNT              3
57 
58 /* Define thread prototypes.  */
59 
60 static void    ftest_0_entry(ULONG thread_input);
61 #ifndef FX_STANDALONE_ENABLE
62 static void    ftest_1_entry(ULONG thread_input);
63 #else
64 static void   * ftest_1_entry(void * thread_input);
65 #endif
66 extern void    _fx_ram_driver(FX_MEDIA *media_ptr);
67 extern void    test_control_return(UINT status);
68 extern UINT    _filex_fault_tolerant_log_check(FX_MEDIA *media_ptr);
69 extern UINT(*driver_write_callback)(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
70 static UINT    my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
71 
72 
73 
74 /* Create a terrible driver. */
75 static UINT driver_called_counter = 0;
_fx_terrible_driver(FX_MEDIA * media_ptr)76 static void _fx_terrible_driver(FX_MEDIA *media_ptr)
77 {
78     driver_called_counter++;
79     // printf("\n_fx_terrible_driver has been called %d times.", driver_called_counter);
80     if (driver_called_counter == 1)
81     {
82         media_ptr->fx_media_driver_status = FX_IO_ERROR;
83         return;
84     }
85     (*_fx_ram_driver)(media_ptr);
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_delete_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     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
104         pointer, DEMO_STACK_SIZE,
105         4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
106     pointer = pointer + DEMO_STACK_SIZE;
107 
108     /* Setup memory for the RAM disk and the sector cache.  */
109     cache_buffer = pointer;
110     pointer += CACHE_SIZE;
111     fault_tolerant_buffer = pointer;
112     pointer += FAULT_TOLERANT_SIZE;
113     thread_buffer = pointer;
114     pointer += DEMO_STACK_SIZE;
115 #endif
116 
117     /* Initialize the FileX system.  */
118     fx_system_initialize();
119 #ifdef FX_STANDALONE_ENABLE
120     ftest_0_entry(0);
121 #endif
122 }
123 
124 
125 
126 /* Define the test threads.  */
127 
ftest_0_entry(ULONG thread_input)128 static void    ftest_0_entry(ULONG thread_input)
129 {
130 
131     UINT        status;
132     ULONG       actual;
133     UINT        i;
134 
135     FX_PARAMETER_NOT_USED(thread_input);
136 
137     /* Print out some test information banners.  */
138     printf("FileX Test:   Fault Tolerant File Delete Test........................");
139 
140     /* Loop to test FAT 12, 16, 32.   */
141     for (i = 0; i < TEST_COUNT; i++)
142     {
143         if (i == 0)
144         {
145             /* Format the media with FAT12.  This needs to be done before opening it!  */
146             status = fx_media_format(&ram_disk,
147                 _fx_ram_driver,         // Driver entry
148                 ram_disk_memory_large,  // RAM disk memory pointer
149                 cache_buffer,           // Media buffer pointer
150                 CACHE_SIZE,             // Media buffer size
151                 "MY_RAM_DISK",          // Volume Name
152                 1,                      // Number of FATs
153                 32,                     // Directory Entries
154                 0,                      // Hidden sectors
155                 256,                    // Total sectors
156                 256,                    // Sector size
157                 8,                      // Sectors per cluster
158                 1,                      // Heads
159                 1);                     // Sectors per track
160         }
161         else if (i == 1)
162         {
163             /* Format the media with FAT16.  This needs to be done before opening it!  */
164             status = fx_media_format(&ram_disk,
165                 _fx_ram_driver,         // Driver entry
166                 ram_disk_memory_large,  // RAM disk memory pointer
167                 cache_buffer,           // Media buffer pointer
168                 CACHE_SIZE,             // Media buffer size
169                 "MY_RAM_DISK",          // Volume Name
170                 1,                      // Number of FATs
171                 32,                     // Directory Entries
172                 0,                      // Hidden sectors
173                 4200 * 8,               // Total sectors
174                 256,                    // Sector size
175                 8,                      // Sectors per cluster
176                 1,                      // Heads
177                 1);                     // Sectors per track
178         }
179         else if (i == 2)
180         {
181             /* Format the media with FAT32.  This needs to be done before opening it!  */
182             status = fx_media_format(&ram_disk,
183                 _fx_ram_driver,         // Driver entry
184                 ram_disk_memory_large,  // RAM disk memory pointer
185                 cache_buffer,           // Media buffer pointer
186                 CACHE_SIZE,             // Media buffer size
187                 "MY_RAM_DISK",          // Volume Name
188                 1,                      // Number of FATs
189                 32,                     // Directory Entries
190                 0,                      // Hidden sectors
191                 70000 * 8,              // Total sectors
192                 256,                    // Sector size
193                 8,                      // Sectors per cluster
194                 1,                      // Heads
195                 1);                     // Sectors per track
196         }
197 
198         /* Determine if the format had an error.  */
199         if (status)
200         {
201 
202             printf("ERROR!\n");
203             test_control_return(1);
204         }
205 
206         /* Open the ram_disk.  */
207         status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
208 
209         /* Check the status.  */
210         if (status != FX_SUCCESS)
211         {
212 
213             /* Output successful.  */
214             printf("SUCCESS!\n");
215             test_control_return(0);
216 
217         }
218 
219         /* Enable the Fault-tolerant feature.  */
220         status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
221 
222         /* Check status.   */
223         if (status)
224         {
225 
226             printf("ERROR!\n");
227             test_control_return(3);
228         }
229 
230         /* Create a file called TEST2.TXT in the root directory.  */
231         status = fx_file_create(&ram_disk, "TEST2.TXT");
232 
233         /* Check the create status.  */
234         if (status != FX_SUCCESS)
235         {
236 
237             printf("ERROR!\n");
238             test_control_return(16);
239         }
240 
241         /* Open the test file.  */
242         status = fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
243 
244         /* Check the file open status.  */
245         if (status != FX_SUCCESS)
246         {
247 
248             printf("ERROR!\n");
249             test_control_return(17);
250         }
251 
252         /* Write a string to the test file.  */
253         status = fx_file_write(&my_file, " EXPRESSLOGIC_TEST\n", 19);
254 
255         /* Check the file write status.  */
256         if (status != FX_SUCCESS)
257         {
258 
259             printf("ERROR!\n");
260             test_control_return(18);
261         }
262 
263         /* Seek to the beginning of the test file.  */
264         status = fx_file_seek(&my_file, 0);
265 
266         /* Check the file seek status.  */
267         if (status != FX_SUCCESS)
268         {
269 
270             printf("ERROR!\n");
271             test_control_return(19);
272         }
273 
274         /* Read the bytes of the test file.  */
275         status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
276 
277         /* Check the file read status.  */
278         if ((status != FX_SUCCESS) || (actual != 19))
279         {
280 
281             printf("ERROR!\n");
282             test_control_return(20);
283         }
284 
285         /* Close the test file.  */
286         status = fx_file_close(&my_file);
287 
288         /* Check the file close status.  */
289         if (status != FX_SUCCESS)
290         {
291 
292             printf("ERROR!\n");
293             test_control_return(21);
294         }
295 
296 #ifndef FX_STANDALONE_ENABLE
297         /* Create the main thread.  */
298         tx_thread_create(&ftest_1, "thread 1", ftest_1_entry, 0,
299             thread_buffer, DEMO_STACK_SIZE,
300             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
301 #endif
302         /* directory_write_interrupt */
303         fat_write_interrupt = FX_FALSE;
304 
305         /* Let the other thread run.  */
306 #ifndef FX_STANDALONE_ENABLE
307         tx_thread_relinquish();
308 #else
309         pthread_create(&ptid1, NULL, &ftest_1_entry, NULL);
310         usleep(10);
311         pthread_join(ptid1,NULL);
312 #endif
313         /* Delete the thread.  */
314 #ifndef FX_STANDALONE_ENABLE
315         tx_thread_delete(&ftest_1);
316 #else
317         pthread_cancel(ptid1);
318 #endif
319     }
320 
321     /* Output successful.  */
322     printf("SUCCESS!\n");
323     test_control_return(0);
324 
325 }
326 
327 
328 /* Define the test threads.  */
329 
330 #ifndef FX_STANDALONE_ENABLE
ftest_1_entry(ULONG thread_input)331 static void    ftest_1_entry(ULONG thread_input)
332 #else
333  void  *  ftest_1_entry(void * thread_input)
334 #endif
335 {
336 
337 #ifdef FX_STANDALONE_ENABLE
338     UINT oldtype;
339     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
340     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
341 #endif
342     UINT   status;
343 
344     FX_PARAMETER_NOT_USED(thread_input);
345 
346     /* Set the callback function to simulate poweoff operation when write FAT entry.  */
347     driver_write_callback = my_driver_write;
348 
349     /* Register our terrible dirver to make IO ERROR at a particular time. */
350     ram_disk.fx_media_driver_entry = _fx_terrible_driver;
351 
352     /* Create a file called TEST2.TXT in the root directory.  */
353     status=fx_file_delete(&ram_disk, "TEST2.TXT");
354     return_value_if_fail(status == FX_IO_ERROR, 6);
355 
356     /* Unregister our terrible driver. */
357     ram_disk.fx_media_driver_entry = _fx_ram_driver;
358 }
359 
360 
my_driver_write(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)361 static UINT my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
362 {
363 
364     FX_PARAMETER_NOT_USED(block_ptr);
365 
366     /* Interrupt the FAT write operation after record the redo log.  */
367     if ((sector_type == FX_FAT_SECTOR) && (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_DONE))
368     {
369 
370         /* Set the write interrupt operation.  */
371         *operation_ptr = FX_OP_WRITE_INTERRUPT;
372 
373         /* Update the flag.  */
374         fat_write_interrupt = FX_TRUE;
375 
376         /* Clean the callback function.  */
377         driver_write_callback = FX_NULL;
378 
379         /* Delete the media protection structure if FX_SINGLE_THREAD is not
380         defined.  */
381 #ifndef FX_SINGLE_THREAD
382 #ifndef FX_DONT_CREATE_MUTEX
383 
384         /* Note that the protection is never released. The mutex delete
385         service will handle all threads waiting access to this media
386         control block.  */
387         tx_mutex_delete(&(media_ptr->fx_media_protect));
388 #endif
389 #endif
390 
391         /* Clean the media data.  */
392         _fx_system_media_opened_ptr = FX_NULL;
393         _fx_system_media_opened_count = 0;
394 
395         /* Clean the media.  */
396         memset(media_ptr, 0, sizeof(FX_MEDIA));
397 
398         /* Simulate poweroff.  */
399         /* First terminate the thread to ensure it is ready for deletion.  */
400 #ifndef FX_STANDALONE_ENABLE
401         tx_thread_terminate(&ftest_1);
402 #else
403         pthread_cancel(ptid1);
404 #endif
405     }
406 
407     /* Return.  */
408     return FX_SUCCESS;
409 }
410 #else
411 
412 #ifdef CTEST
test_application_define(void * first_unused_memory)413 void test_application_define(void *first_unused_memory)
414 #else
415 void    filex_fault_tolerant_file_delete_test_application_define(void *first_unused_memory)
416 #endif
417 {
418 
419     FX_PARAMETER_NOT_USED(first_unused_memory);
420 
421     /* Print out some test information banners.  */
422     printf("FileX Test:   Fault Tolerant File Delete Test........................N/A\n");
423 
424     test_control_return(255);
425 }
426 #endif
427 
428 
429