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 );
107 void task2( unsigned int arg );
108 void task3( unsigned int arg );
109 void task4( unsigned int arg );
111 T_CTSK t_ctsk = { NULL, 0, (FP)&newtask, 1, CYGNUM_UITRON_STACK_SIZE };
114 void task1( unsigned int arg )
118 CYG_TEST_INFO( "Task 1 running" );
120 // change us to prio 3 for flexibility
121 ercd = chg_pri( 0, 3 );
122 CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
124 #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
125 // first, check that we can delete a task:
126 #ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
127 ercd = del_tsk( -6 );
128 CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
129 ercd = del_tsk( 99 );
130 CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
131 ercd = cre_tsk( -6, &t_ctsk );
132 CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
133 ercd = cre_tsk( 99, &t_ctsk );
134 CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
135 #endif // we can test bad param error returns
136 // try a pre-existing object
137 ercd = cre_tsk( 2, &t_ctsk );
138 CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
139 // try a pre-existing object - ourselves!
140 ercd = cre_tsk( 1, &t_ctsk );
141 CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
142 // try deleting an active task
144 CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
145 ercd = sta_tsk( 2, 22222 );
146 CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
147 ercd = chg_pri( 2, 5 );
148 CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
150 CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
151 // Task 2 is now ready-to-run, lower prio than us
153 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
154 ercd = dly_tsk( 10 );
155 CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
156 // Task 2 is now sleeping
157 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
159 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
160 // try deleting a running task - ourselves!
162 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
163 // terminate task 2; should then be OK to delete it
165 CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
166 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
168 CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
169 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
170 // and check it is deleted
171 ercd = sta_tsk( 2, 99 );
172 CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
174 CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
175 ercd = chg_pri( 2, 6 );
176 CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
178 CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
180 CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
182 CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
183 ercd = frsm_tsk( 2 );
184 CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
186 CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
187 ercd = can_wup( &scratch, 2 );
188 CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
189 ercd = ref_tsk( &t_rtsk, 2 );
190 CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
192 CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
193 // recreate task2, with the same function
194 t_ctsk.task = (FP)&task2;
196 ercd = cre_tsk( 2, &t_ctsk );
197 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
198 ercd = ref_tsk( &t_rtsk, 2 );
199 CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
200 CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
201 CYG_TEST_CHECK( TTS_DMT == t_rtsk.tskstat,
202 "Bad tskstat in new task2 !TTS_DMT" );
203 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
204 // now start the task and do the same lot again...
205 ercd = cre_tsk( 2, &t_ctsk );
206 CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
207 // try deleting an active task
208 ercd = sta_tsk( 2, 22222 );
209 CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
210 // Task 2 is now ready-to-run, lower prio than us
212 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
213 CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
214 ercd = dly_tsk( 10 );
215 CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
216 CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
217 // Task 2 is now sleeping
218 ercd = ref_tsk( &t_rtsk, 2 );
219 CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
220 CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
221 CYG_TEST_CHECK( TTS_WAI == t_rtsk.tskstat,
222 "Bad tskstat in new task2 !TTS_WAI" );
224 CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
226 ercd = chg_pri( 2, 1 );
227 CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
228 // awaken task 2; it will then exit-and-delete itself:
229 CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
231 CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
232 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
233 // and check it is deleted
234 ercd = sta_tsk( 2, 99 );
235 CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
236 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
238 CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
239 ercd = chg_pri( 2, 1 );
240 CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
242 CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
244 CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
246 CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
247 ercd = frsm_tsk( 2 );
248 CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
250 CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
251 ercd = can_wup( &scratch, 2 );
252 CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
253 ercd = ref_tsk( &t_rtsk, 2 );
254 CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
255 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
257 CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
258 #ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
259 // now try creating it (badly)
260 #ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
261 ercd = cre_tsk( 2, NULL );
262 CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
264 ercd = cre_tsk( 2, NADR );
265 CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
266 t_ctsk.stksz = 0x40000000;
267 ercd = cre_tsk( 2, &t_ctsk );
268 CYG_TEST_CHECK( E_NOMEM == ercd, "cre_tsk bad ercd !E_NOMEM" );
269 t_ctsk.stksz = CYGNUM_UITRON_STACK_SIZE;
270 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
271 #endif // we can test bad param error returns
274 CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
275 t_ctsk.task = (FP)&task4;
277 ercd = cre_tsk( 3, &t_ctsk );
278 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
279 // check we can delete it again immediately
281 CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
282 ercd = ref_tsk( &t_rtsk, 3 );
283 CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
284 t_ctsk.task = (FP)&newtask;
286 ercd = cre_tsk( 3, &t_ctsk );
287 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
288 CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
289 ercd = sta_tsk( 3, 999 );
290 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
291 // it should have run now, and exited
292 CYG_TEST_CHECK( 5 == intercount, "bad intercount !5" );
294 CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
295 // and check that it will just run again...
296 ercd = sta_tsk( 3, 999 );
297 CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
298 // it should have run now, and exited
299 CYG_TEST_CHECK( 7 == intercount, "bad intercount !7" );
301 CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
304 CYG_TEST_PASS("create/delete tasks");
307 CYG_TEST_EXIT( "All done" );
308 #else // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
309 CYG_TEST_NA( "Tasks do not have create/delete enabled" );
310 #endif // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
316 void newtask( unsigned int arg )
320 CYG_TEST_INFO( "Newtask running" );
321 CYG_TEST_CHECK( 999 == arg, "Bad arg to newtask() !999" );
322 ercd = get_tid( &i );
323 CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
324 CYG_TEST_CHECK( 3 == i, "tid not 3" );
327 CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
332 void task2( unsigned int arg )
336 CYG_TEST_INFO( "Task 2 running" );
337 ercd = get_tid( &i );
338 CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
339 CYG_TEST_CHECK( 2 == i, "tid not 2" );
341 CYG_TEST_FAIL( "Task 2 arg not 22222" );
346 CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
350 exd_tsk(); // if we are not killed first
352 intercount++; // shouldn't happen
355 void task3( unsigned int arg )
357 CYG_TEST_FAIL( "How come I'm being run?" );
360 void task4( unsigned int arg )
362 CYG_TEST_FAIL( "How come I'm being run?" );
365 #else // not enough (or too many) uITRON objects configured in
366 #define N_A_MSG "not enough uITRON objects to run test"
367 #endif // not enough (or too many) uITRON objects configured in
368 #else // not C++ and some C++ specific options enabled
369 #define N_A_MSG "C++ specific options selected but this is C"
370 #endif // not C++ and some C++ specific options enabled
371 #else // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
372 #define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
373 #endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK - can't test without it
374 #else // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
375 #define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
376 #endif // ! CYGFUN_KERNEL_THREADS_TIMER - can't test without it
377 #else // ! CYGIMP_THREAD_PRIORITY - can't test without it
378 #define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
379 #endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE - can't test without it
380 #else // ! CYGPKG_UITRON
381 #define N_A_MSG "uITRON Compatibility layer disabled"
382 #endif // CYGPKG_UITRON
389 CYG_TEST_NA( N_A_MSG );
391 #endif // N_A_MSG defined ie. we are N/A.