1 /* This test is designed to test a simple application timer services, including create,
2    activate, deactivate, change, and delete.  */
3 
4 #include   <stdio.h>
5 #include   "tx_api.h"
6 #include   "tx_timer.h"
7 
8 typedef struct TIMER_MEMORY_TEST_STRUCT
9 {
10     ULONG       first;
11     ULONG       second;
12     TX_TIMER    timer;
13     ULONG       next_to_last;
14     ULONG       last;
15 
16 } TIMER_MEMORY_TEST;
17 
18 static  TIMER_MEMORY_TEST   timer_memory;
19 
20 
21 /* Define the ISR dispatch.  */
22 
23 extern VOID    (*test_isr_dispatch)(void);
24 
25 
26 /* Define external reference to status from timer create during initialization.  */
27 
28 extern UINT     test_timer_create_init;
29 
30 
31 static unsigned long   thread_0_counter =  0;
32 static TX_THREAD       thread_0;
33 static TX_THREAD       thread_1;
34 
35 static unsigned long   timer_0_counter =  0;
36 static TX_TIMER        timer_0;
37 
38 static unsigned long   timer_1_counter =  0;
39 static TX_TIMER        timer_1;
40 
41 static TX_TIMER        timer_2;
42 static TX_TIMER        timer_3;
43 
44 static unsigned long error =  0;
45 static unsigned long timer_executed =  0;
46 static unsigned long isr_executed =  0;
47 
48 /* Define thread prototypes.  */
49 
50 static void    thread_0_entry(ULONG thread_input);
51 static void    thread_1_entry(ULONG thread_input);
52 static void    timer_0_expiration(ULONG timer_input);
53 static void    timer_1_expiration(ULONG timer_input);
54 
55 UINT        _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr,
56                 VOID (*expiration_function)(ULONG), ULONG expiration_input,
57                 ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size);
58 
59 
60 /* Prototype for test control return.  */
61 
62 void  test_control_return(UINT status);
63 
64 
65 /* Define the timer for this test.  */
66 
timer_entry(ULONG i)67 static void    timer_entry(ULONG i)
68 {
69 
70 #ifndef TX_DISABLE_ERROR_CHECKING
71 
72 UINT    status;
73 
74 
75     /* Determine if the timer was able to be created durning initialization.   */
76     if (test_timer_create_init != TX_SUCCESS)
77     {
78 
79         /* Error!  */
80         error++;
81     }
82 
83     /* Attempt to delete a timer from a timer.  */
84     status =  tx_timer_delete(&timer_0);
85 
86     /* Check status.  */
87     if (status != TX_CALLER_ERROR)
88     {
89 
90         /* Error!  */
91         error++;
92     }
93 
94     /* Attempt to create a timer from a timer.  */
95     status =  tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
96                         1, 18, TX_AUTO_ACTIVATE);
97 
98     /* Check status.  */
99     if (status != TX_CALLER_ERROR)
100     {
101 
102         /* Error!  */
103         error++;
104     }
105 
106 #ifndef TX_TIMER_PROCESS_IN_ISR
107     /* Just to test another path, set this timer expired variable.  */
108     if (timer_executed == 0)
109         _tx_timer_expired =  1;
110 #endif
111 
112     timer_executed =  1;
113 #endif
114 }
115 
116 /* Define the ISR dispatch routine.  */
117 
test_isr(void)118 static void    test_isr(void)
119 {
120 
121 #ifndef TX_DISABLE_ERROR_CHECKING
122 
123 UINT    status;
124 
125     /* Attempt to delete a timer from an ISR.  */
126     status =  tx_timer_delete(&timer_0);
127 
128     /* Check status.  */
129     if (status != TX_CALLER_ERROR)
130     {
131 
132         /* Error!  */
133         error++;
134     }
135 
136     /* Attempt to create a timer from an ISR.  */
137     status =  tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
138                         1, 18, TX_AUTO_ACTIVATE);
139 
140     /* Check status.  */
141     if (status != TX_CALLER_ERROR)
142     {
143 
144         /* Error!  */
145         error++;
146     }
147 
148     isr_executed =  1;
149 #endif
150 }
151 
152 
153 /* Define what the initial system looks like.  */
154 
155 #ifdef CTEST
test_application_define(void * first_unused_memory)156 void test_application_define(void *first_unused_memory)
157 #else
158 void    threadx_timer_simple_application_define(void *first_unused_memory)
159 #endif
160 {
161 
162 UINT    status;
163 CHAR    *pointer;
164 
165     /* Put first available memory address into a character pointer.  */
166     pointer =  (CHAR *) first_unused_memory;
167 
168     /* Put system definition stuff in here, e.g. thread creates and other assorted
169        create information.  */
170 
171     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
172             pointer, TEST_STACK_SIZE_PRINTF,
173             16, 16, 3, TX_AUTO_START);
174     pointer = pointer + TEST_STACK_SIZE_PRINTF;
175 
176     status +=  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
177             pointer, TEST_STACK_SIZE_PRINTF,
178             18, 18, 3, TX_DONT_START);
179     pointer = pointer + TEST_STACK_SIZE_PRINTF;
180 
181     /* Check for status.  */
182     if (status != TX_SUCCESS)
183     {
184 
185         printf("Running Timer Simple Test........................................... ERROR #1\n");
186         test_control_return(1);
187     }
188 
189     status =  tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
190                         1, 18, TX_AUTO_ACTIVATE);
191 
192     /* Check for status.  */
193     if (status != TX_SUCCESS)
194     {
195 
196         printf("Running Timer Simple Test........................................... ERROR #2\n");
197         test_control_return(1);
198     }
199 
200     status =  tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
201                         1000, 1000, TX_AUTO_ACTIVATE);
202 
203     /* Check for status.  */
204     if (status != TX_SUCCESS)
205     {
206 
207         printf("Running Timer Simple Test........................................... ERROR #3\n");
208         test_control_return(1);
209     }
210 
211 #ifndef TX_TIMER_PROCESS_IN_ISR
212 
213     /* Call the timer thread entry function with a bad ID to test another path.  */
214     _tx_timer_thread_entry(0);
215 #endif
216 
217 }
218 
219 
220 
221 /* Define the test threads.  */
222 
thread_0_entry(ULONG thread_input)223 static void    thread_0_entry(ULONG thread_input)
224 {
225 
226 UINT    status;
227 
228 
229     /* Inform user.  */
230     printf("Running Timer Simple Test........................................... ");
231 
232     /* Perform timer memory test.  */
233     timer_memory.first =        0x11223344;
234     timer_memory.second =       0x55667788;
235     timer_memory.next_to_last = 0x99aabbcc;
236     timer_memory.last =         0xddeeff00;
237 
238     /* Create the timer.  */
239     status =  tx_timer_create(&timer_memory.timer, "timer memory", timer_0_expiration, 0x1234,
240                         1000000, 100000, TX_NO_ACTIVATE);
241     tx_timer_delete(&timer_memory.timer);
242 
243     /* Check for status.  */
244     if ((status != TX_SUCCESS) ||
245         (timer_memory.first != 0x11223344) ||
246         (timer_memory.second != 0x55667788) ||
247         (timer_memory.next_to_last != 0x99aabbcc) ||
248         (timer_memory.last != 0xddeeff00))
249     {
250 
251         /* Memory overwrite error.  */
252         printf("ERROR #4\n");
253         test_control_return(1);
254     }
255 
256 #ifndef TX_DISABLE_ERROR_CHECKING
257 
258     /* Attempt to activate a non-timer.  */
259     status =  tx_timer_activate(TX_NULL);
260 
261     /* Check status.  */
262     if (status != TX_TIMER_ERROR)
263     {
264 
265         /* Application timer error.  */
266         printf("ERROR #5\n");
267         test_control_return(1);
268     }
269 
270     /* Attempt to activate a non-created timer.  */
271     timer_2.tx_timer_id =  0;
272     status =  tx_timer_activate(&timer_2);
273 
274     /* Check status.  */
275     if (status != TX_TIMER_ERROR)
276     {
277 
278         /* Application timer error.  */
279         printf("ERROR #6\n");
280         test_control_return(1);
281     }
282 
283     /* Attempt to activate a timer with a 0 expiration.  */
284     timer_2.tx_timer_id =  ((ULONG) 0x4154494D);
285     timer_2.tx_timer_internal.tx_timer_internal_list_head =  TX_NULL;
286     timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks =  0;
287     status =  tx_timer_activate(&timer_2);
288 
289     /* Check status.  */
290     if (status != TX_ACTIVATE_ERROR)
291     {
292 
293         /* Application timer error.  */
294         printf("ERROR #7\n");
295         test_control_return(1);
296     }
297 
298 
299     /* Attempt to activate a timer with a wait forever expiration.  */
300     timer_2.tx_timer_id =  ((ULONG) 0x4154494D);
301     timer_2.tx_timer_internal.tx_timer_internal_list_head =  TX_NULL;
302     timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks =  TX_WAIT_FOREVER;
303     status =  tx_timer_activate(&timer_2);
304 
305     /* Check status.  */
306     if (status != TX_SUCCESS)
307     {
308 
309         /* Application timer error.  */
310         printf("ERROR #8\n");
311         test_control_return(1);
312     }
313 
314     timer_2.tx_timer_id =  0;
315 
316     /* Attempt to deactivate a non-timer.  */
317     status =  tx_timer_deactivate(TX_NULL);
318 
319     /* Check status.  */
320     if (status != TX_TIMER_ERROR)
321     {
322 
323         /* Application timer error.  */
324         printf("ERROR #9\n");
325         test_control_return(1);
326     }
327 
328     /* Attempt to deactivate a non-created timer.  */
329     timer_2.tx_timer_id =  0;
330     status =  tx_timer_deactivate(&timer_2);
331 
332     /* Check status.  */
333     if (status != TX_TIMER_ERROR)
334     {
335 
336         /* Application timer error.  */
337         printf("ERROR #10\n");
338         test_control_return(1);
339     }
340 
341     /* Attempt to change a non-timer.  */
342     status =  tx_timer_change(TX_NULL, 1, 1);
343 
344     /* Check status.  */
345     if (status != TX_TIMER_ERROR)
346     {
347 
348         /* Application timer error.  */
349         printf("ERROR #11\n");
350         test_control_return(1);
351     }
352 
353     /* Attempt to change a non-created timer.  */
354     timer_2.tx_timer_id =  0;
355     status =  tx_timer_change(&timer_2, 1, 1);
356 
357     /* Check status.  */
358     if (status != TX_TIMER_ERROR)
359     {
360 
361         /* Application timer error.  */
362         printf("ERROR #12\n");
363         test_control_return(1);
364     }
365 
366     /* Attempt to change a timer with a 0 initial ticks.  */
367     status =  tx_timer_change(&timer_0, 0, 1);
368 
369     /* Check status.  */
370     if (status != TX_TICK_ERROR)
371     {
372 
373         /* Application timer error.  */
374         printf("ERROR #13\n");
375         test_control_return(1);
376     }
377 
378     /* Attempt to delete a non-time.  */
379     status =  tx_timer_delete(TX_NULL);
380 
381     /* Check status.  */
382     if (status != TX_TIMER_ERROR)
383     {
384 
385         /* Application timer error.  */
386         printf("ERROR #14\n");
387         test_control_return(1);
388     }
389 
390     /* Attempt to delete a non-created time.  */
391     timer_2.tx_timer_id =  0;
392     status =  tx_timer_delete(&timer_2);
393 
394     /* Check status.  */
395     if (status != TX_TIMER_ERROR)
396     {
397 
398         /* Application timer error.  */
399         printf("ERROR #15\n");
400         test_control_return(1);
401     }
402 
403     /* Attempt to get info from a non-timer.  */
404     status =  tx_timer_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
405 
406     /* Check status.  */
407     if (status != TX_TIMER_ERROR)
408     {
409 
410         /* Application timer error.  */
411         printf("ERROR #16\n");
412         test_control_return(1);
413     }
414 
415     /* Attempt to get info from a non-created timer.  */
416     timer_2.tx_timer_id =  0;
417     status =  tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
418 
419     /* Check status.  */
420     if (status != TX_TIMER_ERROR)
421     {
422 
423         /* Application timer error.  */
424         printf("ERROR #17\n");
425         test_control_return(1);
426     }
427 
428     /* Attempt to create a timer with a NULL pointer.  */
429     status =  tx_timer_create(TX_NULL, "timer 0", timer_0_expiration, 0x1234,
430                         1, 18, TX_AUTO_ACTIVATE);
431 
432     /* Check status.  */
433     if (status != TX_TIMER_ERROR)
434     {
435 
436         /* Application timer error.  */
437         printf("ERROR #18\n");
438         test_control_return(1);
439     }
440 
441     /* Attempt to create a timer with a bad control block size.  */
442     status =  _txe_timer_create(&timer_3, "timer 3", timer_0_expiration, 0x1234,
443                         1, 18, TX_AUTO_ACTIVATE, (sizeof(TX_TIMER)+1));
444 
445     /* Check status.  */
446     if (status != TX_TIMER_ERROR)
447     {
448 
449         /* Application timer error.  */
450         printf("ERROR #19\n");
451         test_control_return(1);
452     }
453 
454     /* Attempt to create a timer that has already been created.  */
455     status =  tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
456                         1, 18, TX_AUTO_ACTIVATE);
457 
458     /* Check status.  */
459     if (status != TX_TIMER_ERROR)
460     {
461 
462         /* Application timer error.  */
463         printf("ERROR #20\n");
464         test_control_return(1);
465     }
466 
467     /* Attempt to create a timer with an invalid number of initial ticks.  */
468     status =  tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
469                         0, 18, TX_AUTO_ACTIVATE);
470 
471     /* Check status.  */
472     if (status != TX_TICK_ERROR)
473     {
474 
475         /* Application timer error.  */
476         printf("ERROR #21\n");
477         test_control_return(1);
478     }
479 
480     /* Attempt to create a timer with an invalid activation.  */
481     status =  tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
482                         1, 18, TX_AUTO_ACTIVATE+3999);
483 
484     /* Check status.  */
485     if (status != TX_ACTIVATE_ERROR)
486     {
487 
488         /* Application timer error.  */
489         printf("ERROR #22\n");
490         test_control_return(1);
491     }
492 
493 #endif
494 
495     /* Sleep for a couple ticks.  */
496     tx_thread_sleep(19);
497 
498     /* Check for an error.  */
499     if (timer_0_counter != 2)
500     {
501 
502         /* Application timer error.  */
503         printf("ERROR #23\n");
504         test_control_return(1);
505     }
506 
507     /* Deactivate the timer.  */
508     status =  tx_timer_deactivate(&timer_0);
509 
510     /* Check for status.  */
511     if (status != TX_SUCCESS)
512     {
513 
514         /* Application timer error.  */
515         printf("ERROR #24\n");
516         test_control_return(1);
517     }
518 
519     /* Sleep again.  */
520     tx_thread_sleep(19);
521 
522     /* Check for an error.  */
523     if (timer_0_counter != 2)
524     {
525 
526         /* Application timer error.  */
527         printf("ERROR #25\n");
528         test_control_return(1);
529     }
530 
531     /* Modify the timer.  */
532     status =  tx_timer_change(&timer_0, 100, 1);
533 
534     /* Check for status.  */
535     if (status != TX_SUCCESS)
536     {
537 
538         /* Application timer error.  */
539         printf("ERROR #26\n");
540         test_control_return(1);
541     }
542 
543     /* Clear the system time.  */
544     tx_time_set(0);
545 
546     /* Activate the timer.  */
547     status =  tx_timer_activate(&timer_0);
548 
549     /* Check for status.  */
550     if (status != TX_SUCCESS)
551     {
552 
553         /* Application timer error.  */
554         printf("ERROR #27\n");
555         test_control_return(1);
556     }
557 
558     /* Sleep for 120.  */
559     tx_thread_sleep(120);
560 
561     /* Check the counters to make sure everything is where it should be.  */
562     if ((timer_0_counter != 23) || (tx_time_get() != 120))
563     {
564 
565         /* Application timer error.  */
566         printf("ERROR #28\n");
567         test_control_return(1);
568     }
569 
570     /* Increment thread 0 counter.  */
571     thread_0_counter++;
572 
573     /* Delete the timer...  that are currently active and on the same expiration
574        list!  */
575     status =  tx_timer_deactivate(&timer_0);
576     status += tx_timer_deactivate(&timer_1);
577     status += tx_timer_change(&timer_0, 100, 100);
578     status += tx_timer_change(&timer_1, 100, 100);
579     status += tx_timer_activate(&timer_0);
580     status += tx_timer_activate(&timer_1);
581     status += tx_timer_delete(&timer_0);
582     status += tx_timer_delete(&timer_1);
583 
584     /* Check for status.  */
585     if (status != TX_SUCCESS)
586     {
587 
588         /* Application timer error.  */
589         printf("ERROR #29\n");
590         test_control_return(1);
591     }
592 
593 #ifndef TX_DISABLE_ERROR_CHECKING
594 
595     /* Create a timer for the test.  */
596     tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
597 
598     /* Setup the ISR.  */
599     test_isr_dispatch =  test_isr;
600 
601     /* Sleep for a bit...  */
602     tx_thread_sleep(3);
603 
604     /* Resume thread 1 to take an interrupt on top of it.  */
605     tx_thread_resume(&thread_1);
606 
607     /* Sleep for a bit...  */
608     tx_thread_sleep(3);
609 
610     /* Clear the ISR.  */
611     test_isr_dispatch =  TX_NULL;
612 
613     /* Test for error.  */
614     if ((error) || (timer_executed != 1) || (isr_executed != 1))
615     {
616 
617         /* Thread error.  */
618         printf("ERROR #30\n");
619         test_control_return(1);
620     }
621 
622 #endif
623 
624     if (error)
625     {
626 
627         /* Thread error.  */
628         printf("ERROR #31\n");
629         test_control_return(1);
630     }
631     else
632     {
633 
634         /* Successful Multiple Sleep test.  */
635         printf("SUCCESS!\n");
636         test_control_return(0);
637     }
638 }
639 
thread_1_entry(ULONG thread_input)640 static void    thread_1_entry(ULONG thread_input)
641 {
642 
643     while(1)
644     {
645 
646         tx_thread_relinquish();
647     }
648 }
649 
timer_0_expiration(ULONG timer_input)650 static void    timer_0_expiration(ULONG timer_input)
651 {
652 
653 
654     /* Process timer expiration.  */
655     timer_0_counter++;
656 }
657 
658 
timer_1_expiration(ULONG timer_input)659 static void    timer_1_expiration(ULONG timer_input)
660 {
661 
662     /* Process timer expiration.  */
663     timer_1_counter++;
664 }
665