1 //===========================================================================
5 // uITRON "C++" test program eight
7 //===========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
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 version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //===========================================================================
41 //#####DESCRIPTIONBEGIN####
46 // Purpose: uITRON API testing
49 //####DESCRIPTIONEND####
51 //===========================================================================
53 #include <pkgconf/uitron.h> // uITRON setup CYGNUM_UITRON_SEMAS
54 // CYGPKG_UITRON et al
55 #include <cyg/infra/testcase.h> // testing infrastructure
57 #ifdef CYGPKG_UITRON // we DO want the uITRON package
59 #ifdef CYGSEM_KERNEL_SCHED_MLQUEUE // we DO want prioritized threads
61 #ifdef CYGFUN_KERNEL_THREADS_TIMER // we DO want timout-able calls
63 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK // we DO want the realtime clock
65 // we're OK if it's C++ or neither of those two is defined:
66 #if defined( __cplusplus ) || \
67 (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
68 !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
70 // =================== TEST CONFIGURATION ===================
72 /* test configuration for enough tasks */ \
73 (CYGNUM_UITRON_TASKS >= 4) && \
74 (CYGNUM_UITRON_TASKS < 90) && \
75 (CYGNUM_UITRON_START_TASKS == 1) && \
76 ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) || \
77 CYGNUM_UITRON_TASKS_INITIALLY >= 4 ) && \
79 /* test configuration for enough semaphores */ \
80 defined( CYGPKG_UITRON_SEMAS ) && \
81 (CYGNUM_UITRON_SEMAS >= 3) && \
82 (CYGNUM_UITRON_SEMAS < 90) && \
83 ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) || \
84 CYGNUM_UITRON_SEMAS_INITIALLY >= 3 ) && \
86 /* the end of the large #if statement */ \
89 // ============================ END ============================
93 #include <cyg/compat/uitron/uit_func.h> // uITRON
96 cyg_package_start( void )
99 CYG_TEST_INFO( "Calling cyg_uitron_start()" );
103 volatile int intercount = 0;
106 void newtask( unsigned int arg );
108 T_CTSK t_ctsk = { NULL, 0, (FP)&newtask, 1, CYGNUM_UITRON_STACK_SIZE };
112 void task1( unsigned int arg );
113 void task2( unsigned int arg );
114 void task3( unsigned int arg );
115 void task4( unsigned int arg );
118 void task1( unsigned int arg )
122 CYG_TEST_INFO( "Task 1 running" );
124 // change us to prio 3 for flexibility
125 ercd = chg_pri( 0, 3 );
126 CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
128 #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
129 // first, check that we can delete a task:
130 #ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
131 ercd = del_tsk( -6 );
132 CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
133 ercd = del_tsk( 99 );
134 CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
135 ercd = cre_tsk( -6, &t_ctsk );
136 CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
137 ercd = cre_tsk( 99, &t_ctsk );
138 CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
139 #endif // we can test bad param error returns
140 // try a pre-existing object
141 ercd = cre_tsk( 2, &t_ctsk );
142 CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
143 // try a pre-existing object - ourselves!
144 ercd = cre_tsk( 1, &t_ctsk );
145 CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
146 // try deleting an active task
148 CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
149 ercd = sta_tsk( 2, 22222 );
150 CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
151 ercd = chg_pri( 2, 5 );
152 CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
154 CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
155 // Task 2 is now ready-to-run, lower prio than us
157 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
158 ercd = dly_tsk( 10 );
159 CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
160 // Task 2 is now sleeping
161 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
163 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
164 // try deleting a running task - ourselves!
166 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
167 // terminate task 2; should then be OK to delete it
169 CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
170 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
172 CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
173 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
174 // and check it is deleted
175 ercd = sta_tsk( 2, 99 );
176 CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
178 CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
179 ercd = chg_pri( 2, 6 );
180 CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
182 CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
184 CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
186 CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
187 ercd = frsm_tsk( 2 );
188 CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
190 CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
191 ercd = can_wup( &scratch, 2 );
192 CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
193 ercd = ref_tsk( &t_rtsk, 2 );
194 CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
196 CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
197 // recreate task2, with the same function
198 t_ctsk.task = (FP)&task2;
200 ercd = cre_tsk( 2, &t_ctsk );
201 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
202 ercd = ref_tsk( &t_rtsk, 2 );
203 CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
204 CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
205 CYG_TEST_CHECK( TTS_DMT == t_rtsk.tskstat,
206 "Bad tskstat in new task2 !TTS_DMT" );
207 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
208 // now start the task and do the same lot again...
209 ercd = cre_tsk( 2, &t_ctsk );
210 CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
211 // try deleting an active task
212 ercd = sta_tsk( 2, 22222 );
213 CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
214 // Task 2 is now ready-to-run, lower prio than us
216 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
217 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
218 ercd = dly_tsk( 10 );
219 CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
220 CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
221 // Task 2 is now sleeping
222 ercd = ref_tsk( &t_rtsk, 2 );
223 CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
224 CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
225 CYG_TEST_CHECK( TTS_WAI == t_rtsk.tskstat,
226 "Bad tskstat in new task2 !TTS_WAI" );
228 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
230 ercd = chg_pri( 2, 1 );
231 CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
232 // awaken task 2; it will then exit-and-delete itself:
233 CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
235 CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
236 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
237 // and check it is deleted
238 ercd = sta_tsk( 2, 99 );
239 CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
240 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
242 CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
243 ercd = chg_pri( 2, 1 );
244 CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
246 CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
248 CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
250 CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
251 ercd = frsm_tsk( 2 );
252 CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
254 CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
255 ercd = can_wup( &scratch, 2 );
256 CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
257 ercd = ref_tsk( &t_rtsk, 2 );
258 CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
259 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
261 CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
262 #ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
263 // now try creating it (badly)
264 #ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
265 ercd = cre_tsk( 2, NULL );
266 CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
268 t_ctsk.stksz = 0x40000000;
269 ercd = cre_tsk( 2, &t_ctsk );
270 CYG_TEST_CHECK( E_NOMEM == ercd, "cre_tsk bad ercd !E_NOMEM" );
271 t_ctsk.stksz = CYGNUM_UITRON_STACK_SIZE;
272 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
273 #endif // we can test bad param error returns
276 CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
277 t_ctsk.task = (FP)&task4;
279 ercd = cre_tsk( 3, &t_ctsk );
280 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
281 // check we can delete it again immediately
283 CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
284 ercd = ref_tsk( &t_rtsk, 3 );
285 CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
286 t_ctsk.task = (FP)&newtask;
288 ercd = cre_tsk( 3, &t_ctsk );
289 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
290 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
291 ercd = sta_tsk( 3, 999 );
292 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
293 // it should have run now, and exited
294 CYG_TEST_CHECK( 5 == intercount, "bad intercount !5" );
296 CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
297 // and check that it will just run again...
298 ercd = sta_tsk( 3, 999 );
299 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
300 // it should have run now, and exited
301 CYG_TEST_CHECK( 7 == intercount, "bad intercount !7" );
303 CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
306 CYG_TEST_PASS("create/delete tasks");
309 CYG_TEST_EXIT( "All done" );
310 #else // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
311 CYG_TEST_NA( "Tasks do not have create/delete enabled" );
312 #endif // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
318 void newtask( unsigned int arg )
322 CYG_TEST_INFO( "Newtask running" );
323 CYG_TEST_CHECK( 999 == arg, "Bad arg to newtask() !999" );
324 ercd = get_tid( &i );
325 CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
326 CYG_TEST_CHECK( 3 == i, "tid not 3" );
329 CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
334 void task2( unsigned int arg )
338 CYG_TEST_INFO( "Task 2 running" );
339 ercd = get_tid( &i );
340 CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
341 CYG_TEST_CHECK( 2 == i, "tid not 2" );
343 CYG_TEST_FAIL( "Task 2 arg not 22222" );
348 CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
352 exd_tsk(); // if we are not killed first
354 intercount++; // shouldn't happen
357 void task3( unsigned int arg )
359 CYG_TEST_FAIL( "How come I'm being run?" );
362 void task4( unsigned int arg )
364 CYG_TEST_FAIL( "How come I'm being run?" );
367 #else // not enough (or too many) uITRON objects configured in
368 #define N_A_MSG "not enough uITRON objects to run test"
369 #endif // not enough (or too many) uITRON objects configured in
370 #else // not C++ and some C++ specific options enabled
371 #define N_A_MSG "C++ specific options selected but this is C"
372 #endif // not C++ and some C++ specific options enabled
373 #else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
374 #define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
375 #endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
376 #else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
377 #define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
378 #endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
379 #else // ! CYGIMP_THREAD_PRIORITY - can't test without it
380 #define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
381 #endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
382 #else // ! CYGPKG_UITRON
383 #define N_A_MSG "uITRON Compatibility layer disabled"
384 #endif // CYGPKG_UITRON
391 CYG_TEST_NA( N_A_MSG );
393 #endif // N_A_MSG defined ie. we are N/A.