|
3216
|
1 //========================================================================== |
|
|
2 // |
|
|
3 // fpinttestf.c |
|
|
4 // |
|
|
5 // Basic FPU integrity test |
|
|
6 // |
|
|
7 //========================================================================== |
|
|
8 // ####ECOSGPLCOPYRIGHTBEGIN#### |
|
|
9 // ------------------------------------------- |
|
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
|
11 // Copyright (C) 2012 Free Software Foundation, Inc. |
|
|
12 // |
|
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
|
14 // the terms of the GNU General Public License as published by the Free |
|
|
15 // Software Foundation; either version 2 or (at your option) any later |
|
|
16 // version. |
|
|
17 // |
|
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT |
|
|
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
|
21 // for more details. |
|
|
22 // |
|
|
23 // You should have received a copy of the GNU General Public License |
|
|
24 // along with eCos; if not, write to the Free Software Foundation, Inc., |
|
|
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
|
26 // |
|
|
27 // As a special exception, if other files instantiate templates or use |
|
|
28 // macros or inline functions from this file, or you compile this file |
|
|
29 // and link it with other works to produce a work based on this file, |
|
|
30 // this file does not by itself cause the resulting work to be covered by |
|
|
31 // the GNU General Public License. However the source code for this file |
|
|
32 // must still be made available in accordance with section (3) of the GNU |
|
|
33 // General Public License v2. |
|
|
34 // |
|
|
35 // This exception does not invalidate any other reasons why a work based |
|
|
36 // on this file might be covered by the GNU General Public License. |
|
|
37 // ------------------------------------------- |
|
|
38 // ####ECOSGPLCOPYRIGHTEND#### |
|
|
39 //========================================================================== |
|
|
40 //#####DESCRIPTIONBEGIN#### |
|
|
41 // |
|
|
42 // Author(s): ilijak |
|
|
43 // Original code: nickg@calivar.com |
|
|
44 // Contributors: |
|
|
45 // Date: 2012-12-18 |
|
|
46 // Description: Simple FPU test with a mix of threads that do and do not use |
|
|
47 // floating point. |
|
|
48 // This is a modification of the original FPU test, and presents |
|
|
49 // both "integer" and "float" threads in order to enforce LAZY |
|
|
50 // context switching. Single precision floating point is used. |
|
|
51 // This is not very sophisticated as far |
|
|
52 // as checking FPU performance or accuracy. It is more |
|
|
53 // concerned with checking that several threads doing FP |
|
|
54 // operations do not interfere with eachother's use of the |
|
|
55 // FPU. |
|
|
56 // Note: NONE context switching scheme should NOT pass this test with |
|
|
57 // multiple FP threads. Look for fpinttestf1.c instead. |
|
|
58 // |
|
|
59 //####DESCRIPTIONEND#### |
|
|
60 //========================================================================== |
|
|
61 |
|
|
62 #include <pkgconf/kernel.h> |
|
|
63 #include <pkgconf/hal.h> |
|
|
64 |
|
|
65 #include <cyg/hal/hal_arch.h> |
|
|
66 |
|
|
67 #include <cyg/kernel/kapi.h> |
|
|
68 |
|
|
69 #include <cyg/infra/testcase.h> |
|
|
70 #include <cyg/infra/diag.h> |
|
|
71 |
|
|
72 #include <cyg/kernel/test/stackmon.h> |
|
|
73 #include CYGHWR_MEMORY_LAYOUT_H |
|
|
74 |
|
|
75 //========================================================================== |
|
|
76 |
|
|
77 #ifndef FP_THREADS_N |
|
|
78 #define FP_THREADS_N 3 |
|
|
79 #define FP_TEST_NAME "FP test" |
|
|
80 #endif |
|
|
81 |
|
|
82 #if defined(CYGFUN_KERNEL_API_C) && \ |
|
|
83 defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \ |
|
|
84 (CYGNUM_KERNEL_SCHED_PRIORITIES > 12) && \ |
|
|
85 (CYGMEM_REGION_ram_SIZE >= (49152-4096)) && \ |
|
|
86 (!defined(CYGTST_KERNEL_SKIP_MULTI_THREAD_FP_TEST) || (FP_THREADS_N == 1)) |
|
|
87 |
|
|
88 //========================================================================== |
|
|
89 // Base priority for all threads. |
|
|
90 |
|
|
91 #define BASE_PRI 5 |
|
|
92 |
|
|
93 //========================================================================== |
|
|
94 // Runtime |
|
|
95 // |
|
|
96 // This is the number of ticks that the program will run for. 3000 |
|
|
97 // ticks is equal to 30 seconds in the default configuration. For |
|
|
98 // simulators we reduce the run time to 3 simulated seconds. |
|
|
99 |
|
|
100 #define RUN_TICKS 3000 |
|
|
101 #define RUN_TICKS_SIM 300 |
|
|
102 |
|
|
103 //========================================================================== |
|
|
104 // Thread parameters |
|
|
105 |
|
|
106 #define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM |
|
|
107 #define THREADS_N 8 |
|
|
108 static cyg_uint8 stacks[THREADS_N][STACK_SIZE] CYGBLD_ATTRIB_ALIGN_MAX; |
|
|
109 static cyg_handle_t thread[THREADS_N]; |
|
|
110 static cyg_thread thread_struct[THREADS_N]; |
|
|
111 static unsigned long iter_n[THREADS_N]; |
|
|
112 |
|
|
113 //========================================================================== |
|
|
114 // Alarm parameters. |
|
|
115 |
|
|
116 static cyg_alarm alarm_struct; |
|
|
117 static cyg_handle_t alarm; |
|
|
118 |
|
|
119 static cyg_count8 cur_thread = 0; |
|
|
120 static cyg_count32 alarm_ticks = 0; |
|
|
121 static cyg_count32 run_ticks = RUN_TICKS; |
|
|
122 |
|
|
123 //========================================================================== |
|
|
124 |
|
|
125 static int errors = 0; |
|
|
126 |
|
|
127 //========================================================================== |
|
|
128 // Random number generator. Ripped out of the C library. |
|
|
129 |
|
|
130 static int CYGBLD_ATTRIB_NO_INLINE rand( unsigned int *seed ) |
|
|
131 { |
|
|
132 // This is the code supplied in Knuth Vol 2 section 3.6 p.185 bottom |
|
|
133 |
|
|
134 #define RAND_MAX 0x7fffffff |
|
|
135 #define MM 2147483647 // a Mersenne prime |
|
|
136 #define AA 48271 // this does well in the spectral test |
|
|
137 #define QQ 44488 // (long)(MM/AA) |
|
|
138 #define RR 3399 // MM % AA; it is important that RR<QQ |
|
|
139 |
|
|
140 *seed = AA*(*seed % QQ) - RR*(unsigned int)(*seed/QQ); |
|
|
141 if (*seed < 0) |
|
|
142 *seed += MM; |
|
|
143 |
|
|
144 return (int)( *seed & RAND_MAX ); |
|
|
145 } |
|
|
146 |
|
|
147 |
|
|
148 //========================================================================== |
|
|
149 // Test calculation. |
|
|
150 // |
|
|
151 // Generates an array of random FP values and then repeatedly applies |
|
|
152 // a calculation to them and checks that the same result is reached |
|
|
153 // each time. The calculation, in the macro CALC, is intended to make |
|
|
154 // maximum use of the FPU registers. However, the i386 compiler |
|
|
155 // doesn't let this expression get very complex before it starts |
|
|
156 // spilling values out to memory. |
|
|
157 |
|
|
158 static void do_test( float *values, |
|
|
159 int count, |
|
|
160 int loops, |
|
|
161 int test, |
|
|
162 const char *name) |
|
|
163 { |
|
|
164 unsigned int i, j; |
|
|
165 // volatiles necessary to force |
|
|
166 // values to 32 bits for comparison |
|
|
167 volatile float sum = 1.0; |
|
|
168 volatile float last_sum; |
|
|
169 unsigned int seed; |
|
|
170 |
|
|
171 cyg_uint32 iter = 0; |
|
|
172 int thread_i = name[__builtin_strlen(name)-1]-'1'; |
|
|
173 |
|
|
174 #define V(__i) (values[(__i)%count]) |
|
|
175 #define CALC ((V(i-1)*V(i+1))*(V(i-2)*V(i+2))*(V(i-3)*sum)) |
|
|
176 |
|
|
177 seed = ((unsigned int)&i)*count; |
|
|
178 |
|
|
179 // Set up an array of values... |
|
|
180 for( i = 0; i < count; i++ ) |
|
|
181 values[i] = (float)rand( &seed )/(float)0x7fffffff; |
|
|
182 |
|
|
183 // Now calculate something from them... |
|
|
184 for( i = 0; i < count; i++ ) |
|
|
185 sum += CALC; |
|
|
186 |
|
|
187 last_sum = sum; |
|
|
188 |
|
|
189 // Now recalculate the sum in a loop and look for errors |
|
|
190 for( j = 0; j < loops ; j++ ) |
|
|
191 { |
|
|
192 iter++; |
|
|
193 if(thread_i < 3) |
|
|
194 iter_n[thread_i]++; |
|
|
195 sum = 1.0; |
|
|
196 for( i = 0; i < count; i++ ) |
|
|
197 sum += CALC; |
|
|
198 |
|
|
199 if( sum != last_sum ) |
|
|
200 { |
|
|
201 union float_int_union { |
|
|
202 float d; |
|
|
203 cyg_uint32 i; |
|
|
204 } diu_sum, diu_lastsum; |
|
|
205 |
|
|
206 diu_sum.d = sum; |
|
|
207 diu_lastsum.d = last_sum; |
|
|
208 |
|
|
209 errors++; |
|
|
210 if (sizeof(float) != sizeof(cyg_uint32)) { |
|
|
211 diag_printf("Warning: sizeof(float) != sizeof(cyg_uint32), therefore next line may\n" |
|
|
212 "have invalid sum/last_sum values\n"); |
|
|
213 } |
|
|
214 diag_printf("%s: Sum mismatch! %d sum=[%08x] last_sum=[%08x]\n", |
|
|
215 name,j, diu_sum.i, diu_lastsum.i ); |
|
|
216 |
|
|
217 } |
|
|
218 #if 0 |
|
|
219 if( ((j*count)%1000000) == 0 ) |
|
|
220 diag_printf("INFO:<%s: %2d calculations done>\n",name,j*count); |
|
|
221 #endif |
|
|
222 } |
|
|
223 #if 0 |
|
|
224 if(thread_i < 3) |
|
|
225 diag_printf("INFO:<%s [%d]: %2d calculations done>\n",name,thread_i,j*count); |
|
|
226 #endif |
|
|
227 if(thread_i < 3) |
|
|
228 iter_n[thread_i] = iter; |
|
|
229 } |
|
|
230 |
|
|
231 |
|
|
232 //========================================================================== |
|
|
233 // Test calculation. |
|
|
234 // |
|
|
235 // Generates an array of random integer values and then repeatedly applies |
|
|
236 // a calculation to them and checks that the same result is reached |
|
|
237 // each time. |
|
|
238 |
|
|
239 static void do_int_test( int *values, |
|
|
240 int count, |
|
|
241 int loops, |
|
|
242 int test, |
|
|
243 const char *name) |
|
|
244 { |
|
|
245 unsigned int i, j; |
|
|
246 // volatiles necessary to force |
|
|
247 // values to 32 bits for comparison |
|
|
248 volatile int sum = 1; |
|
|
249 volatile int last_sum; |
|
|
250 unsigned int seed; |
|
|
251 #if 0 |
|
|
252 cyg_uint32 ctrlreg; |
|
|
253 #endif |
|
|
254 cyg_uint32 iter = 0; |
|
|
255 int thread_i = name[__builtin_strlen(name)-1]-'1'; |
|
|
256 |
|
|
257 #define VI(__i) (values[(__i)%count]) |
|
|
258 #define CALCI ((VI(i-1)*VI(i+1))*(VI(i-2)*VI(i+2))*(VI(i-3)*sum)) |
|
|
259 |
|
|
260 seed = ((unsigned int)&i)*count; |
|
|
261 |
|
|
262 // Set up an array of values... |
|
|
263 for( i = 0; i < count; i++ ) |
|
|
264 values[i] = rand( &seed ); |
|
|
265 |
|
|
266 // Now calculate something from them... |
|
|
267 for( i = 0; i < count; i++ ) |
|
|
268 sum += CALC; |
|
|
269 |
|
|
270 last_sum = sum; |
|
|
271 |
|
|
272 // Now recalculate the sum in a loop and look for errors |
|
|
273 for( j = 0; j < loops ; j++ ) |
|
|
274 { |
|
|
275 iter++; |
|
|
276 if(thread_i < 8) |
|
|
277 iter_n[thread_i]++; |
|
|
278 sum = 1; |
|
|
279 for( i = 0; i < count; i++ ) |
|
|
280 sum += CALC; |
|
|
281 |
|
|
282 if( sum != last_sum ) |
|
|
283 { |
|
|
284 errors++; |
|
|
285 diag_printf("%s: Sum mismatch! %d sum=[%08x] last_sum=[%08x]\n", |
|
|
286 name,j, sum, last_sum ); |
|
|
287 } |
|
|
288 #if 0 |
|
|
289 CYGARC_MRS(ctrlreg, control); |
|
|
290 if(ctrlreg & 0x04){ |
|
|
291 diag_printf("%s: control = 0x%08x\n", name, ctrlreg); |
|
|
292 } |
|
|
293 #endif |
|
|
294 #if 0 |
|
|
295 if( ((j*count)%1000000) == 0 ) |
|
|
296 diag_printf("INFO:<%s: %2d calculations done>\n",name,j*count); |
|
|
297 #endif |
|
|
298 } |
|
|
299 } |
|
|
300 |
|
|
301 //========================================================================== |
|
|
302 // Alarm handler |
|
|
303 // |
|
|
304 // This is called every tick. It lowers the priority of the currently |
|
|
305 // running thread and raises the priority of the next. Thus we |
|
|
306 // implement a form of timelslicing between the threads at one tick |
|
|
307 // granularity. |
|
|
308 |
|
|
309 static void alarm_fn(cyg_handle_t alarm, cyg_addrword_t data) |
|
|
310 { |
|
|
311 alarm_ticks++; |
|
|
312 unsigned long iter_sum; |
|
|
313 |
|
|
314 if( alarm_ticks >= run_ticks ) |
|
|
315 { |
|
|
316 if( errors ) |
|
|
317 CYG_TEST_FAIL("Errors detected"); |
|
|
318 else |
|
|
319 CYG_TEST_PASS("OK"); |
|
|
320 |
|
|
321 iter_sum = + iter_n[0] + iter_n[1] + iter_n[2] + iter_n[3]+ iter_n[4] + iter_n[5]+ iter_n[6] + iter_n[7]; |
|
|
322 diag_printf("Iterations = %lu+%lu+%lu+%lu+%lu+%lu+%lu+%lu", |
|
|
323 iter_n[0], iter_n[1], iter_n[2], iter_n[3], iter_n[4], iter_n[5], iter_n[6], iter_n[7]); |
|
|
324 diag_printf("=%lu\n", iter_sum); |
|
|
325 CYG_TEST_FINISH("FP Test done"); |
|
|
326 } |
|
|
327 else |
|
|
328 { |
|
|
329 cyg_thread_set_priority( thread[cur_thread], BASE_PRI ); |
|
|
330 |
|
|
331 cur_thread = (cur_thread+1)%8; |
|
|
332 |
|
|
333 cyg_thread_set_priority( thread[cur_thread], BASE_PRI-1 ); |
|
|
334 } |
|
|
335 } |
|
|
336 |
|
|
337 |
|
|
338 //========================================================================== |
|
|
339 // Floating point threads |
|
|
340 // |
|
|
341 #define FP1_COUNT 1000 |
|
|
342 |
|
|
343 static float fpt1_values[FP1_COUNT]; |
|
|
344 |
|
|
345 void fptest1( CYG_ADDRWORD id ) |
|
|
346 { |
|
|
347 while(1) |
|
|
348 do_test( fpt1_values, FP1_COUNT, 2000000000, id, "fptest1" ); |
|
|
349 } |
|
|
350 |
|
|
351 //========================================================================== |
|
|
352 #if (CYGMEM_REGION_ram_SIZE / 8 / 2) < 10000 |
|
|
353 #define FP2_COUNT (CYGMEM_REGION_ram_SIZE / 8 / 2) |
|
|
354 #else |
|
|
355 #define FP2_COUNT 10000 |
|
|
356 #endif |
|
|
357 |
|
|
358 static float fpt2_values[FP2_COUNT]; |
|
|
359 |
|
|
360 void fptest2( CYG_ADDRWORD id ) |
|
|
361 { |
|
|
362 while(1) |
|
|
363 do_test( fpt2_values, FP2_COUNT, 2000000000, id, "fptest2" ); |
|
|
364 } |
|
|
365 |
|
|
366 //========================================================================== |
|
|
367 |
|
|
368 #define FP3_COUNT 100 |
|
|
369 |
|
|
370 static float fpt3_values[FP3_COUNT]; |
|
|
371 |
|
|
372 void fptest3( CYG_ADDRWORD id ) |
|
|
373 { |
|
|
374 while(1) |
|
|
375 do_test( fpt3_values, FP3_COUNT, 2000000000, id, "fptest3" ); |
|
|
376 } |
|
|
377 |
|
|
378 //========================================================================== |
|
|
379 // Integral threads |
|
|
380 // |
|
|
381 |
|
|
382 #define INT1_COUNT 1000 |
|
|
383 |
|
|
384 static int int1_values[INT1_COUNT]; |
|
|
385 |
|
|
386 void inttest4( CYG_ADDRWORD id ) |
|
|
387 { |
|
|
388 while(1) |
|
|
389 do_int_test( int1_values, INT1_COUNT, 2000000000, id, "inttest4" ); |
|
|
390 } |
|
|
391 |
|
|
392 #define INT2_COUNT 1000 |
|
|
393 |
|
|
394 static int int2_values[INT2_COUNT]; |
|
|
395 |
|
|
396 void inttest5( CYG_ADDRWORD id ) |
|
|
397 { |
|
|
398 while(1) |
|
|
399 do_int_test( int2_values, INT2_COUNT, 2000000000, id, "inttest5" ); |
|
|
400 } |
|
|
401 |
|
|
402 #define INT3_COUNT 1000 |
|
|
403 |
|
|
404 static int int3_values[INT3_COUNT]; |
|
|
405 |
|
|
406 void inttest6( CYG_ADDRWORD id ) |
|
|
407 { |
|
|
408 while(1) |
|
|
409 do_int_test( int3_values, INT3_COUNT, 2000000000, id, "inttest6" ); |
|
|
410 } |
|
|
411 |
|
|
412 |
|
|
413 #define INT4_COUNT 1000 |
|
|
414 |
|
|
415 static int int4_values[INT4_COUNT]; |
|
|
416 |
|
|
417 void inttest7( CYG_ADDRWORD id ) |
|
|
418 { |
|
|
419 while(1) |
|
|
420 do_int_test( int4_values, INT4_COUNT, 2000000000, id, "inttest7" ); |
|
|
421 } |
|
|
422 |
|
|
423 #define INT5_COUNT 1000 |
|
|
424 |
|
|
425 static int int5_values[INT5_COUNT]; |
|
|
426 |
|
|
427 void inttest8( CYG_ADDRWORD id ) |
|
|
428 { |
|
|
429 while(1) |
|
|
430 do_int_test( int5_values, INT5_COUNT, 2000000000, id, "inttest8" ); |
|
|
431 } |
|
|
432 |
|
|
433 //====================================================================================== |
|
|
434 // Main |
|
|
435 |
|
|
436 void fptest_main( void ) |
|
|
437 { |
|
|
438 CYG_TEST_INIT(); |
|
|
439 |
|
|
440 if( cyg_test_is_simulator ) |
|
|
441 { |
|
|
442 run_ticks = RUN_TICKS_SIM; |
|
|
443 } |
|
|
444 CYG_TEST_INFO("Run fptest in cyg_start"); |
|
|
445 do_test( fpt3_values, FP3_COUNT, 1000, 0, "start" ); |
|
|
446 CYG_TEST_INFO( "cyg_start run done"); |
|
|
447 |
|
|
448 cyg_thread_create( BASE_PRI-1, |
|
|
449 fptest1, |
|
|
450 0, |
|
|
451 "fptest1", |
|
|
452 &stacks[0][0], |
|
|
453 STACK_SIZE, |
|
|
454 &thread[0], |
|
|
455 &thread_struct[0]); |
|
|
456 #if FP_THREADS_N > 0 |
|
|
457 cyg_thread_resume( thread[0] ); |
|
|
458 #endif |
|
|
459 cyg_thread_create( BASE_PRI, |
|
|
460 fptest2, |
|
|
461 1, |
|
|
462 "fptest2", |
|
|
463 &stacks[1][0], |
|
|
464 STACK_SIZE, |
|
|
465 &thread[1], |
|
|
466 &thread_struct[1]); |
|
|
467 |
|
|
468 #if FP_THREADS_N > 1 |
|
|
469 cyg_thread_resume( thread[1] ); |
|
|
470 #endif |
|
|
471 cyg_thread_create( BASE_PRI, |
|
|
472 fptest3, |
|
|
473 2, |
|
|
474 "fptest3", |
|
|
475 &stacks[2][0], |
|
|
476 STACK_SIZE, |
|
|
477 &thread[2], |
|
|
478 &thread_struct[2]); |
|
|
479 |
|
|
480 #if FP_THREADS_N > 2 |
|
|
481 cyg_thread_resume( thread[2] ); |
|
|
482 #endif |
|
|
483 |
|
|
484 cyg_thread_create( BASE_PRI, |
|
|
485 inttest4, |
|
|
486 3, |
|
|
487 "inttest4", |
|
|
488 &stacks[3][0], |
|
|
489 STACK_SIZE, |
|
|
490 &thread[3], |
|
|
491 &thread_struct[3]); |
|
|
492 |
|
|
493 cyg_thread_resume( thread[3] ); |
|
|
494 |
|
|
495 cyg_thread_create( BASE_PRI, |
|
|
496 inttest5, |
|
|
497 4, |
|
|
498 "inttest5", |
|
|
499 &stacks[4][0], |
|
|
500 STACK_SIZE, |
|
|
501 &thread[4], |
|
|
502 &thread_struct[4]); |
|
|
503 |
|
|
504 cyg_thread_resume( thread[4] ); |
|
|
505 |
|
|
506 cyg_thread_create( BASE_PRI, |
|
|
507 inttest6, |
|
|
508 5, |
|
|
509 "inttest6", |
|
|
510 &stacks[5][0], |
|
|
511 STACK_SIZE, |
|
|
512 &thread[5], |
|
|
513 &thread_struct[5]); |
|
|
514 |
|
|
515 cyg_thread_resume( thread[5] ); |
|
|
516 |
|
|
517 cyg_thread_create( BASE_PRI, |
|
|
518 inttest7, |
|
|
519 6, |
|
|
520 "inttest7", |
|
|
521 &stacks[6][0], |
|
|
522 STACK_SIZE, |
|
|
523 &thread[6], |
|
|
524 &thread_struct[6]); |
|
|
525 |
|
|
526 cyg_thread_resume( thread[6] ); |
|
|
527 |
|
|
528 cyg_thread_create( BASE_PRI, |
|
|
529 inttest8, |
|
|
530 7, |
|
|
531 "inttest8", |
|
|
532 &stacks[7][0], |
|
|
533 STACK_SIZE, |
|
|
534 &thread[7], |
|
|
535 &thread_struct[7]); |
|
|
536 |
|
|
537 cyg_thread_resume( thread[7] ); |
|
|
538 |
|
|
539 cyg_alarm_create( cyg_real_time_clock(), |
|
|
540 alarm_fn, |
|
|
541 0, |
|
|
542 &alarm, |
|
|
543 &alarm_struct ); |
|
|
544 |
|
|
545 cyg_alarm_initialize( alarm, cyg_current_time()+1, 1 ); |
|
|
546 |
|
|
547 cyg_scheduler_start(); |
|
|
548 |
|
|
549 } |
|
|
550 |
|
|
551 //========================================================================== |
|
|
552 |
|
|
553 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG |
|
|
554 externC void |
|
|
555 cyg_hal_invoke_constructors(); |
|
|
556 #endif |
|
|
557 |
|
|
558 externC void |
|
|
559 cyg_start( void ) |
|
|
560 { |
|
|
561 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG |
|
|
562 cyg_hal_invoke_constructors(); |
|
|
563 #endif |
|
|
564 fptest_main(); |
|
|
565 } |
|
|
566 |
|
|
567 //========================================================================== |
|
|
568 |
|
|
569 #else // CYGFUN_KERNEL_API_C... |
|
|
570 |
|
|
571 externC void |
|
|
572 cyg_start( void ) |
|
|
573 { |
|
|
574 CYG_TEST_INIT(); |
|
|
575 CYG_TEST_INFO(FP_TEST_NAME " requires:\n" |
|
|
576 "CYGFUN_KERNEL_API_C && \n" |
|
|
577 "CYGSEM_KERNEL_SCHED_MLQUEUE && \n" |
|
|
578 "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12) &&\n" |
|
|
579 "(CYGMEM_REGION_ram_SIZE >= (49152-4096)) &&\n" |
|
|
580 "(!defined(CYGHWR_HAL_CORTEXM_FPU_SWITCH_NONE) || (FP_THREADS_N == 1))" |
|
|
581 ); |
|
|
582 CYG_TEST_NA("FP test requirements"); |
|
|
583 } |
|
|
584 |
|
|
585 #endif // CYGFUN_KERNEL_API_C, etc. |
|
|
586 |
|
|
587 //========================================================================== |
|
|
588 // EOF fpinttestf.c |