1 /*
2  * Copyright (c) 2006-2019, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-08-15     liukang     the first version
9  * 2023-09-15     xqyjlj       change stack size in cpu64
10  */
11 
12 #include <rtthread.h>
13 #include "utest.h"
14 #include <stdlib.h>
15 
16 #define THREAD_STACKSIZE UTEST_THR_STACK_SIZE
17 #define EVENT_FLAG3 (1 << 3)
18 #define EVENT_FLAG5 (1 << 5)
19 
20 static struct rt_event static_event = {0};
21 #ifdef RT_USING_HEAP
22 static rt_event_t dynamic_event = RT_NULL;
23 static rt_uint32_t dynamic_event_recv_thread_finish = 0, dynamic_event_send_thread_finish = 0;
24 
25 rt_align(RT_ALIGN_SIZE)
26 static char thread3_stack[UTEST_THR_STACK_SIZE];
27 static struct rt_thread thread3;
28 
29 rt_align(RT_ALIGN_SIZE)
30 static char thread4_stack[UTEST_THR_STACK_SIZE];
31 static struct rt_thread thread4;
32 #endif /* RT_USING_HEAP */
33 
34 static rt_uint32_t recv_event_times1 = 0, recv_event_times2 = 0;
35 static rt_uint32_t static_event_recv_thread_finish = 0, static_event_send_thread_finish = 0;
36 
37 rt_align(RT_ALIGN_SIZE)
38 static char thread1_stack[UTEST_THR_STACK_SIZE];
39 static struct rt_thread thread1;
40 
41 rt_align(RT_ALIGN_SIZE)
42 static char thread2_stack[UTEST_THR_STACK_SIZE];
43 static struct rt_thread thread2;
44 
45 #define THREAD_PRIORITY      9
46 #define THREAD_TIMESLICE     5
47 
test_event_init(void)48 static void test_event_init(void)
49 {
50     rt_err_t result;
51 
52     result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO);
53     if (result != RT_EOK)
54     {
55         uassert_false(1);
56     }
57     result = rt_event_detach(&static_event);
58     if (result != RT_EOK)
59     {
60         uassert_false(1);
61     }
62 
63     result = rt_event_init(&static_event, "event", RT_IPC_FLAG_FIFO);
64     if (result != RT_EOK)
65     {
66         uassert_false(1);
67     }
68     result = rt_event_detach(&static_event);
69     if (result != RT_EOK)
70     {
71         uassert_false(1);
72     }
73 
74     uassert_true(1);
75 }
76 
test_event_detach(void)77 static void test_event_detach(void)
78 {
79     rt_err_t result = RT_EOK;
80 
81     result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO);
82     if (result != RT_EOK)
83     {
84         uassert_false(1);
85     }
86 
87     result = rt_event_detach(&static_event);
88     if (result != RT_EOK)
89     {
90         uassert_false(1);
91     }
92 
93     uassert_true(1);
94 }
95 
thread1_recv_static_event(void * param)96 static void thread1_recv_static_event(void *param)
97 {
98     rt_uint32_t e;
99 
100     if (rt_event_recv(&static_event, (EVENT_FLAG3 | EVENT_FLAG5),
101                       RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
102                       RT_WAITING_FOREVER, &e) != RT_EOK)
103     {
104         return;
105     }
106 
107     recv_event_times1 = e;
108 
109     rt_thread_mdelay(50);
110 
111     if (rt_event_recv(&static_event, (EVENT_FLAG3 | EVENT_FLAG5),
112                       RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
113                       RT_WAITING_FOREVER, &e) != RT_EOK)
114     {
115         return;
116     }
117     recv_event_times2 = e;
118 
119     static_event_recv_thread_finish = 1;
120 }
121 
thread2_send_static_event(void * param)122 static void thread2_send_static_event(void *param)
123 {
124     rt_event_send(&static_event, EVENT_FLAG3);
125     rt_thread_mdelay(10);
126 
127     rt_event_send(&static_event, EVENT_FLAG5);
128     rt_thread_mdelay(10);
129 
130     rt_event_send(&static_event, EVENT_FLAG3);
131 
132     static_event_send_thread_finish = 1;
133 }
134 
135 
test_static_event_send_recv(void)136 static void test_static_event_send_recv(void)
137 {
138     rt_err_t result = RT_EOK;
139 
140     result  = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO);
141     if (result  != RT_EOK)
142     {
143         uassert_false(1);
144     }
145 
146     rt_thread_init(&thread1,
147                    "thread1",
148                    thread1_recv_static_event,
149                    RT_NULL,
150                    &thread1_stack[0],
151                    sizeof(thread1_stack),
152                    THREAD_PRIORITY - 1, THREAD_TIMESLICE);
153     rt_thread_startup(&thread1);
154 
155     rt_thread_init(&thread2,
156                    "thread2",
157                    thread2_send_static_event,
158                    RT_NULL,
159                    &thread2_stack[0],
160                    sizeof(thread2_stack),
161                    THREAD_PRIORITY, THREAD_TIMESLICE);
162     rt_thread_startup(&thread2);
163 
164     while (static_event_recv_thread_finish != 1 || static_event_send_thread_finish != 1)
165     {
166         rt_thread_delay(1);
167     }
168 
169     if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5))
170     {
171         if (rt_event_detach(&static_event) != RT_EOK)
172         {
173             uassert_false(1);
174         }
175         uassert_true(1);
176     }
177     else
178     {
179         if (rt_event_detach(&static_event) != RT_EOK)
180         {
181             uassert_false(1);
182         }
183         uassert_false(1);
184     }
185 
186     return;
187 }
188 
189 #ifdef RT_USING_HEAP
test_event_create(void)190 static void test_event_create(void)
191 {
192     rt_err_t result = RT_EOK;
193 
194     dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_FIFO);
195     if (dynamic_event == RT_NULL)
196     {
197         uassert_false(1);
198     }
199 
200     result = rt_event_delete(dynamic_event);
201     if (result != RT_EOK)
202     {
203         uassert_false(1);
204     }
205 
206     uassert_true(1);
207 }
208 
test_event_delete(void)209 static void test_event_delete(void)
210 {
211     rt_err_t result;
212 
213     dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_FIFO);
214     if (dynamic_event == RT_NULL)
215     {
216         uassert_false(1);
217     }
218 
219     result = rt_event_delete(dynamic_event);
220     if (result != RT_EOK)
221     {
222         uassert_false(1);
223     }
224 
225     uassert_true(1);
226 }
227 
thread3_recv_dynamic_event(void * param)228 static void thread3_recv_dynamic_event(void *param)
229 {
230     rt_uint32_t e;
231 
232     if (rt_event_recv(dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5),
233                       RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
234                       RT_WAITING_FOREVER, &e) != RT_EOK)
235     {
236         return;
237     }
238 
239     recv_event_times1 = e;
240 
241     rt_thread_mdelay(50);
242 
243     if (rt_event_recv(dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5),
244                       RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
245                       RT_WAITING_FOREVER, &e) != RT_EOK)
246     {
247         return;
248     }
249     recv_event_times2 = e;
250 
251     dynamic_event_recv_thread_finish = 1;
252 }
253 
thread4_send_dynamic_event(void * param)254 static void thread4_send_dynamic_event(void *param)
255 {
256     rt_event_send(dynamic_event, EVENT_FLAG3);
257     rt_thread_mdelay(10);
258 
259     rt_event_send(dynamic_event, EVENT_FLAG5);
260     rt_thread_mdelay(10);
261 
262     rt_event_send(dynamic_event, EVENT_FLAG3);
263 
264     dynamic_event_send_thread_finish = 1;
265 }
266 
test_dynamic_event_send_recv(void)267 static void test_dynamic_event_send_recv(void)
268 {
269     dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_PRIO);
270     if (dynamic_event == RT_NULL)
271     {
272         uassert_false(1);
273     }
274 
275     rt_thread_init(&thread3,
276                    "thread3",
277                    thread3_recv_dynamic_event,
278                    RT_NULL,
279                    &thread3_stack[0],
280                    sizeof(thread3_stack),
281                    THREAD_PRIORITY - 1, THREAD_TIMESLICE);
282     rt_thread_startup(&thread3);
283 
284     rt_thread_init(&thread4,
285                    "thread4",
286                    thread4_send_dynamic_event,
287                    RT_NULL,
288                    &thread4_stack[0],
289                    sizeof(thread4_stack),
290                    THREAD_PRIORITY, THREAD_TIMESLICE);
291     rt_thread_startup(&thread4);
292 
293     while (dynamic_event_recv_thread_finish != 1 || dynamic_event_send_thread_finish != 1)
294     {
295         rt_thread_delay(1);
296     }
297 
298     if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5))
299     {
300         if (rt_event_delete(dynamic_event) != RT_EOK)
301         {
302             uassert_false(1);
303         }
304         uassert_true(1);
305     }
306     else
307     {
308         if (rt_event_delete(dynamic_event) != RT_EOK)
309         {
310             uassert_false(1);
311         }
312         uassert_false(1);
313     }
314 
315     return;
316 }
317 #endif
318 
utest_tc_init(void)319 static rt_err_t utest_tc_init(void)
320 {
321     static_event_recv_thread_finish = 0;
322     static_event_send_thread_finish = 0;
323 #ifdef RT_USING_HEAP
324     dynamic_event_recv_thread_finish = 0;
325     dynamic_event_send_thread_finish = 0;
326 #endif
327     return RT_EOK;
328 }
329 
utest_tc_cleanup(void)330 static rt_err_t utest_tc_cleanup(void)
331 {
332     return RT_EOK;
333 }
334 
testcase(void)335 static void testcase(void)
336 {
337     UTEST_UNIT_RUN(test_event_init);
338     UTEST_UNIT_RUN(test_event_detach);
339     UTEST_UNIT_RUN(test_static_event_send_recv);
340 #ifdef RT_USING_HEAP
341     UTEST_UNIT_RUN(test_event_create);
342     UTEST_UNIT_RUN(test_event_delete);
343     UTEST_UNIT_RUN(test_dynamic_event_send_recv);
344 #endif
345 }
346 UTEST_TC_EXPORT(testcase, "src.ipc.event_tc", utest_tc_init, utest_tc_cleanup, 60);
347