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