xref: /nrf52832-nimble/rt-thread/examples/kernel/tc_comm.c (revision 104654410c56c573564690304ae786df310c91fc)
1 #include "tc_comm.h"
2 #ifdef RT_USING_FINSH
3 #include <finsh.h>
4 #endif
5 
6 #ifdef RT_USING_TC
7 #define TC_PRIORITY        25
8 #define TC_STACK_SIZE    0x400
9 
10 static rt_uint8_t _tc_stat;
11 static struct rt_semaphore _tc_sem;
12 static struct rt_thread _tc_thread;
13 static rt_uint8_t _tc_stack[TC_STACK_SIZE];
14 static char _tc_prefix[64];
15 static const char* _tc_current;
16 static void (*_tc_cleanup)(void) = RT_NULL;
17 
18 static rt_uint32_t _tc_scale = 1;
19 FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
20 
21 static rt_uint32_t _tc_loop;
22 
tc_thread_entry(void * parameter)23 void tc_thread_entry(void* parameter)
24 {
25     unsigned int fail_count = 0;
26     struct finsh_syscall* index;
27 
28     /* create tc semaphore */
29     rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO);
30 
31     do {
32         for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
33         {
34             /* search testcase */
35             if (rt_strstr(index->name, _tc_prefix) == index->name)
36             {
37                 long tick;
38 
39                 _tc_current = index->name + 4;
40                 rt_kprintf("Run TestCase: %s\n", _tc_current);
41                 _tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING;
42                 tick = index->func();
43                 if (tick > 0)
44                 {
45                     /* Make sure we are going to be blocked. */
46                     rt_sem_control(&_tc_sem, RT_IPC_CMD_RESET, 0);
47                     rt_sem_take(&_tc_sem, tick * _tc_scale);
48                 }
49 
50                 if (_tc_cleanup != RT_NULL)
51                 {
52                     /* perform testcase cleanup */
53                     _tc_cleanup();
54                     _tc_cleanup = RT_NULL;
55                 }
56 
57                 if (_tc_stat & TC_STAT_RUNNING)
58                 {
59                     rt_kprintf("TestCase[%s] exit with stat TC_STAT_RUNNING."
60                                " Please fix the TC.\n",
61                                _tc_current);
62                     /* If the TC forgot to clear the flag, we do it. */
63                     _tc_stat &= ~TC_STAT_RUNNING;
64                 }
65 
66                 if (_tc_stat & TC_STAT_FAILED)
67                 {
68                     rt_kprintf("TestCase[%s] failed\n", _tc_current);
69                     fail_count++;
70                 }
71                 else
72                 {
73                     rt_kprintf("TestCase[%s] passed\n", _tc_current);
74                 }
75             }
76         }
77     } while (_tc_loop);
78 
79     rt_kprintf("RT-Thread TestCase Running Done!\n");
80     if (fail_count)
81     {
82         rt_kprintf("%d tests failed\n", fail_count);
83     }
84     else
85     {
86         rt_kprintf("All tests passed\n");
87     }
88     /* detach tc semaphore */
89     rt_sem_detach(&_tc_sem);
90 }
91 
tc_stop()92 void tc_stop()
93 {
94     _tc_loop = 0;
95 
96     rt_thread_delay(10 * RT_TICK_PER_SECOND);
97     if (_tc_thread.stat != RT_THREAD_INIT)
98     {
99         /* lock scheduler */
100         rt_enter_critical();
101 
102         /* detach old tc thread */
103         rt_thread_detach(&_tc_thread);
104         rt_sem_detach(&_tc_sem);
105 
106         /* unlock scheduler */
107         rt_exit_critical();
108     }
109     rt_thread_delay(RT_TICK_PER_SECOND/2);
110 }
111 FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread);
112 
tc_done(rt_uint8_t stat)113 void tc_done(rt_uint8_t stat)
114 {
115     _tc_stat |= stat;
116     _tc_stat &= ~TC_STAT_RUNNING;
117 
118     /* release semaphore */
119     rt_sem_release(&_tc_sem);
120 }
121 
tc_stat(rt_uint8_t stat)122 void tc_stat(rt_uint8_t stat)
123 {
124     if (stat & TC_STAT_FAILED)
125     {
126         rt_kprintf("TestCases[%s] failed\n", _tc_current);
127     }
128     _tc_stat |= stat;
129 }
130 
tc_cleanup(void (* cleanup)())131 void tc_cleanup(void (*cleanup)())
132 {
133     _tc_cleanup = cleanup;
134 }
135 
tc_start(const char * tc_prefix)136 void tc_start(const char* tc_prefix)
137 {
138     rt_err_t result;
139 
140     /* tesecase prefix is null */
141     if (tc_prefix == RT_NULL)
142     {
143         rt_kprintf("TestCase Usage: tc_start(prefix)\n\n");
144         rt_kprintf("list_tc() can list all testcases.\n");
145         return ;
146     }
147 
148     /* init tc thread */
149     if (_tc_stat & TC_STAT_RUNNING)
150     {
151         /* stop old tc thread */
152         tc_stop();
153     }
154 
155     rt_memset(_tc_prefix, 0, sizeof(_tc_prefix));
156     rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix);
157 
158     result = rt_thread_init(&_tc_thread, "tc",
159                             tc_thread_entry, RT_NULL,
160                             &_tc_stack[0], sizeof(_tc_stack),
161                             TC_PRIORITY - 3, 5);
162 
163     /* set tc stat */
164     _tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED;
165 
166     if (result == RT_EOK)
167         rt_thread_startup(&_tc_thread);
168 }
169 FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name);
170 
tc_loop(const char * tc_prefix)171 void tc_loop(const char *tc_prefix)
172 {
173     _tc_loop = 1;
174     tc_start(tc_prefix);
175 }
176 FINSH_FUNCTION_EXPORT(tc_loop, start testcase with testcase prefix or name in loop mode);
177 
list_tc()178 void list_tc()
179 {
180     struct finsh_syscall* index;
181 
182     rt_kprintf("TestCases List:\n");
183     for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
184     {
185         /* search testcase */
186         if (rt_strstr(index->name, "_tc_") == index->name)
187         {
188 #ifdef FINSH_USING_DESCRIPTION
189             rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc);
190 #else
191             rt_kprintf("%s\n", index->name + 4);
192 #endif
193         }
194     }
195 }
196 FINSH_FUNCTION_EXPORT(list_tc, list all testcases);
197 #endif
198 
199