1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9 #include <cmsis_os.h>
10
11 #include <zephyr/irq_offload.h>
12 #include <zephyr/kernel_structs.h>
13
14 #define TIMEOUT (100)
15 #define SIGNAL1 (0x00000020)
16 #define SIGNAL2 (0x00000004)
17 #define SIGNAL (SIGNAL1 | SIGNAL2)
18
19 #define SIGNAL_FLAG 0x00000001
20 #define ISR_SIGNAL 0x50
21
22 #define SIGNAL_ALL_FLAGS ((1 << osFeature_Signals) - 1)
23 #define SIGNAL_OUTOFLIMIT_FLAG ((1 << (osFeature_Signals + 1))-1)
24
Thread_1(void const * arg)25 void Thread_1(void const *arg)
26 {
27 int signals = osSignalSet((osThreadId)arg, SIGNAL1);
28
29 zassert_not_equal(signals, 0x80000000, "");
30 }
31
Thread_2(void const * arg)32 void Thread_2(void const *arg)
33 {
34 int signals = osSignalSet((osThreadId)arg, SIGNAL2);
35
36 zassert_not_equal(signals, 0x80000000, "");
37 }
38
test_multiple_signal_flags(void const * thread_id)39 void test_multiple_signal_flags(void const *thread_id)
40 {
41 int max_signal_cnt = osFeature_Signals;
42 int signals, sig_cnt;
43
44 for (sig_cnt = 0; sig_cnt < max_signal_cnt; sig_cnt++) {
45 /* create unique signal flags to set one flag at a time */
46 int32_t signal_each_flag = SIGNAL_FLAG << sig_cnt;
47 /* check if each signal flag is set properly */
48 signals = osSignalSet((osThreadId)thread_id, signal_each_flag);
49 zassert_not_equal(signals, 0x80000000,
50 "Setting each signal flag failed");
51 }
52 /* clear all the bits to check next scenario */
53 signals = osSignalClear((osThreadId)thread_id, SIGNAL_ALL_FLAGS);
54 zassert_not_equal(signals, 0x80000000, "");
55
56 /* signal all the available flags at one shot */
57 signals = osSignalSet((osThreadId)thread_id, SIGNAL_ALL_FLAGS);
58 zassert_not_equal(signals, 0x80000000,
59 "Signal flags maximum limit failed");
60 /* clear all the bits to check next scenario */
61 signals = osSignalClear((osThreadId)thread_id, SIGNAL_ALL_FLAGS);
62 zassert_not_equal(signals, 0x80000000, "");
63
64 /* signal invalid flag to validate permissible flag limit */
65 signals = osSignalSet((osThreadId)thread_id, SIGNAL_OUTOFLIMIT_FLAG);
66 zassert_equal(signals, 0x80000000, "Signal flags set unexpectedly");
67 }
68
69 osThreadDef(Thread_1, osPriorityHigh, 3, 0);
70 osThreadDef(Thread_2, osPriorityHigh, 1, 0);
71
ZTEST(cmsis_signal,test_signal_events_no_wait)72 ZTEST(cmsis_signal, test_signal_events_no_wait)
73 {
74 osThreadId id1;
75 osEvent evt;
76
77 id1 = osThreadCreate(osThread(Thread_1), osThreadGetId());
78 zassert_true(id1 != NULL, "Thread creation failed");
79
80 /* Let id1 run to trigger SIGNAL1 */
81 osDelay(10);
82
83 /* wait for SIGNAL1. It should return immediately as it is
84 * already triggered.
85 */
86 evt = osSignalWait(SIGNAL1, 0);
87 zassert_equal(evt.status, osEventSignal, "");
88 zassert_equal((evt.value.signals & SIGNAL1), SIGNAL1, "");
89 osThreadTerminate(id1);
90 }
91
ZTEST(cmsis_signal,test_signal_events_timeout)92 ZTEST(cmsis_signal, test_signal_events_timeout)
93 {
94 osThreadId id1;
95 int signals;
96 osEvent evt;
97
98 id1 = osThreadCreate(osThread(Thread_1), osThreadGetId());
99 zassert_true(id1 != NULL, "Thread creation failed");
100
101 /* Let id1 run to trigger SIGNAL1 */
102 osDelay(10);
103
104 signals = osSignalClear(osThreadGetId(), SIGNAL1);
105 zassert_not_equal(signals, 0x80000000, "signal clear failed");
106
107 /* wait for SIGNAL1. It should timeout here as the signal
108 * though triggered, gets cleared in the previous step.
109 */
110 evt = osSignalWait(SIGNAL1, TIMEOUT);
111 zassert_equal(evt.status, osEventTimeout, "signal timeout failed");
112 osThreadTerminate(id1);
113 }
114
ZTEST(cmsis_signal,test_signal_events_signalled)115 ZTEST(cmsis_signal, test_signal_events_signalled)
116 {
117 osThreadId id1, id2;
118 osEvent evt;
119 int signals;
120
121 id1 = osThreadCreate(osThread(Thread_1), osThreadGetId());
122 zassert_true(id1 != NULL, "Thread creation failed");
123
124 id2 = osThreadCreate(osThread(Thread_2), osThreadGetId());
125 zassert_true(id2 != NULL, "Thread creation failed");
126
127 /* wait for multiple signals */
128 evt = osSignalWait(SIGNAL, TIMEOUT);
129 zassert_equal(evt.status, osEventSignal,
130 "wait signal returned unexpected error");
131 zassert_equal((evt.value.signals & SIGNAL), SIGNAL,
132 "wait signal failed unexpectedly");
133
134 signals = osSignalClear(osThreadGetId(), SIGNAL);
135 zassert_not_equal(signals, 0x80000000, "clear signal failed");
136
137 /* Set any single signal */
138 signals = osSignalSet(osThreadGetId(), SIGNAL1);
139 zassert_not_equal(signals, 0x80000000, "set any signal failed");
140
141 /* wait for any single signal flag */
142 evt = osSignalWait(0, TIMEOUT);
143 zassert_equal(evt.status, osEventSignal, "wait for single flag failed");
144 zassert_equal(evt.value.signals, SIGNAL1,
145 "wait single flag returned invalid value");
146
147 /* validate by passing invalid parameters */
148 zassert_equal(osSignalSet(NULL, 0), 0x80000000,
149 "NULL signal set unexpectedly");
150 zassert_equal(osSignalClear(NULL, 0), 0x80000000,
151 "NULL signal cleared unexpectedly");
152 /* cannot wait for Flag mask with MSB set */
153 zassert_equal(osSignalWait((int32_t)0x80010000, 0).status, osErrorValue,
154 "signal wait passed unexpectedly");
155 zassert_equal(osSignalSet(osThreadGetId(), (int32_t)0x80010000),
156 0x80000000, "signal set unexpectedly");
157 zassert_equal(osSignalClear(osThreadGetId(), (int32_t)0x80010000),
158 0x80000000, "signal cleared unexpectedly");
159
160 test_multiple_signal_flags(osThreadGetId());
161 }
162
163 /* IRQ offload function handler to set signal flag */
offload_function(const void * param)164 static void offload_function(const void *param)
165 {
166 osThreadId tid = (osThreadId)param;
167 int signals;
168
169 /* Make sure we're in IRQ context */
170 zassert_true(k_is_in_isr(), "Not in IRQ context!");
171
172 signals = osSignalSet(tid, ISR_SIGNAL);
173 zassert_not_equal(signals, 0x80000000, "signal set failed in ISR");
174 }
175
test_signal_from_isr(void const * thread_id)176 void test_signal_from_isr(void const *thread_id)
177 {
178 /**TESTPOINT: Offload to IRQ context*/
179 irq_offload(offload_function, (const void *)thread_id);
180 }
181
182 osThreadDef(test_signal_from_isr, osPriorityHigh, 1, 0);
183
ZTEST(cmsis_signal,test_signal_events_isr)184 ZTEST(cmsis_signal, test_signal_events_isr)
185 {
186 osThreadId id;
187 osEvent evt;
188
189 id = osThreadCreate(osThread(test_signal_from_isr), osThreadGetId());
190 zassert_true(id != NULL, "Thread creation failed");
191 evt = osSignalWait(ISR_SIGNAL, TIMEOUT);
192 zassert_equal(evt.status, osEventSignal,
193 "signal wait failed unexpectedly");
194 zassert_equal((evt.value.signals & ISR_SIGNAL),
195 ISR_SIGNAL, "unexpected signal wait value");
196 }
197 ZTEST_SUITE(cmsis_signal, NULL, NULL, NULL, NULL, NULL);
198