1414 * See the License for the specific language governing permissions and
1515 * limitations under the License.
1616 */
17- #if defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)
18- #error [NOT_SUPPORTED] Signals test cases require RTOS with multithread to run
19- #else
20-
2117#include " mbed.h"
2218#include " greentea-client/test_env.h"
2319#include " utest/utest.h"
@@ -29,16 +25,166 @@ using utest::v1::Case;
2925#error [NOT_SUPPORTED] UsTicker need to be enabled for this test.
3026#else
3127
32- #define TEST_STACK_SIZE 512
33- #define MAX_FLAG_POS 30
34-
3528#define ALL_SIGNALS 0x7fffffff
3629#define NO_SIGNALS 0x0
37- # define PROHIBITED_SIGNAL 0x80000000
30+
3831#define SIGNAL1 0x1
3932#define SIGNAL2 0x2
4033#define SIGNAL3 0x4
4134
35+ template <int32_t signals, uint32_t timeout, uint32_t test_val>
36+ void run_signal_wait (void )
37+ {
38+ uint32_t ret = ThisThread::flags_wait_all_for (signals, timeout);
39+ TEST_ASSERT_EQUAL (test_val, ret);
40+ }
41+
42+ template <int32_t signals, int32_t test_val>
43+ void run_clear (void )
44+ {
45+ int32_t ret = ThisThread::flags_clear (signals);
46+ TEST_ASSERT_EQUAL (test_val, ret);
47+ }
48+
49+ void run_multiple_wait_clear (int32_t signals1, int32_t signals2, int32_t test_val1, int32_t test_val2)
50+ {
51+ int32_t ret;
52+ ret = ThisThread::flags_clear (signals1);
53+ TEST_ASSERT_EQUAL (test_val1, ret);
54+ ret = ThisThread::flags_clear (signals2);
55+ TEST_ASSERT_EQUAL (test_val2, ret);
56+ }
57+ /* * Validate that ticker callback to flags_clr(NO_SIGNALS) doesn't change main thread signals and return actual signals
58+
59+ Given main thread and ticker instance with callback registered
60+ When callback calls @a flags_clear(NO_SIGNALS)
61+ then callback @a flags_clear return status should be ALL_SIGNALS indicating that the signal is unchanged
62+ */
63+ void test_clear_no_signals_with_ticker (void )
64+ {
65+ Ticker t;
66+ osThreadFlagsSet (ThisThread::get_id (), ALL_SIGNALS);
67+ t.attach_us ([&] { run_multiple_wait_clear (NO_SIGNALS, NO_SIGNALS, ALL_SIGNALS, ALL_SIGNALS); }, 3000 );
68+ }
69+
70+ /* * Validate all flags_clr clears the signal in one shot
71+
72+ Given main thread and ticker instance with callback registered
73+ When callback calls @a flags_clear(ALL_SIGNALS) with all possible signals
74+ then callback @a flags_clear(NO_SIGNALS) return status should be NO_SIGNALS(0) indicating all signals cleared correctly
75+ */
76+ void test_clear_all_with_ticker (void )
77+ {
78+ Ticker t;
79+ osThreadFlagsSet (ThisThread::get_id (), ALL_SIGNALS);
80+ t.attach_us ([&] { run_multiple_wait_clear (ALL_SIGNALS, NO_SIGNALS, ALL_SIGNALS, NO_SIGNALS); }, 3000 );
81+ }
82+
83+ /* * Validate if any signals are set on ticker callback
84+
85+ Given main thread and ticker instance with callback registered
86+ When callback calls @a flags_clear(NO_SIGNALS)
87+ then callback @a flags_clear return status should be NO_SIGNALS(0) indicating no signals set
88+ */
89+ void test_init_state_with_ticker (void )
90+ {
91+ Ticker t;
92+ t.attach_us (callback (run_clear<NO_SIGNALS, NO_SIGNALS>), 3000 );
93+ }
94+
95+ /* * Validate signal_wait return status if timeout specified
96+
97+ Given main thread and ticker instance with callback registered
98+ When callback calls @a flags_wait_all_for(signals, timeout) with specified signals and timeout
99+ then callback @a flags_wait_all_for timeout and return 0 indicating no signals set
100+ */
101+ template <int32_t signals, uint32_t timeout, uint32_t status>
102+ void test_wait_timeout_with_ticker (void )
103+ {
104+ Ticker t;
105+ t.attach_us (callback (run_signal_wait<signals, timeout, status>), 3000 );
106+ }
107+
108+ void run_release_wait_signal_wait_callback ()
109+ {
110+ osThreadFlagsSet (ThisThread::get_id (), ALL_SIGNALS);
111+ }
112+
113+ /* * Validate that call of signal_wait return correctly when thread has all signals already set
114+
115+ Given main thread and ticker instance with callback registered
116+ When main thread @a flags_wait_all_for(ALL_SIGNALS, osWaitForever),
117+ then main thread is blocked
118+ when a callback calls @a osThreadFlagsSet set ALL_SIGNALS
119+ then the main thread is unblocked from @ flags_wait_all_for with the return of ALL_SIGNALS set
120+ */
121+ void test_wait_all_already_set_with_ticker (void )
122+ {
123+ Ticker t;
124+ t.attach_us ([&] { run_release_wait_signal_wait_callback (); }, 3000 );
125+ uint32_t ret = ThisThread::flags_wait_all_for (ALL_SIGNALS, osWaitForever);
126+ TEST_ASSERT_EQUAL (ALL_SIGNALS, ret);
127+ }
128+
129+ void run_release_wait_signal_set_callback (int32_t signal, osThreadId_t id)
130+ {
131+ int32_t ret;
132+ if (signal == 0 ) {
133+ for (int i = 0 ; i < 16 ; i++) {
134+ int32_t signal = 1 << i;
135+ ret = osThreadFlagsSet (id, signal);
136+ }
137+ } else {
138+ ret = osThreadFlagsSet (id, signal);
139+ }
140+ }
141+
142+ /* * Validate if wait_signal accumulate signals and return correctly when all signals set
143+
144+ Given the main thread and ticker instance with callback registered
145+ When main thread @a flags_wait_all_for,
146+ then main thread is blocked
147+ when a callback calls @a osThreadFlagsSet in a loop to set 16 different signal
148+ then the main thread is unblocked from @ flags_wait_all_for with the return of expected different signals set
149+ */
150+ void test_wait_all_loop_with_ticker (void )
151+ {
152+ int32_t ret;
153+ Semaphore sem (0 , 1 );
154+ Ticker t;
155+ osThreadId_t id = ThisThread::get_id ();
156+ t.attach_us ([&] { run_release_wait_signal_set_callback (0 , id); }, 4000 );
157+ ret = ThisThread::flags_wait_all_for ((ALL_SIGNALS & 0xFFFF ), osWaitForever, true );
158+ TEST_ASSERT_EQUAL ((ALL_SIGNALS & 0xFFFF ), ret);
159+ }
160+
161+ /* * Validate if setting same signal twice cause any unwanted behaviour
162+
163+ Given the main thread and two ticker instance with callback registered
164+ When main thread @a flags_wait_all_for,
165+ then main thread is blocked
166+ when a first callback calls @a osThreadFlagsSet set SIGNAL2 and
167+ second callback calls @a osThreadFlagsSet set SIGNAL1 | SIGNAL2 | SIGNAL3 with SIGNAL2 set again
168+ then the main thread is unblocked from @ flags_wait_all_for with return of expected signals set
169+ */
170+ void test_set_double_with_ticker (void )
171+ {
172+ int32_t ret;
173+ Ticker t1, t2;
174+ osThreadId_t id = ThisThread::get_id ();
175+ t1.attach_us ([&] { run_release_wait_signal_set_callback (SIGNAL2, id); }, 3000 );
176+ t2.attach_us ([&] { run_release_wait_signal_set_callback (SIGNAL1 | SIGNAL2 | SIGNAL3, id); }, 4000 );
177+
178+ ret = ThisThread::flags_wait_all_for ((SIGNAL1 | SIGNAL2 | SIGNAL3), osWaitForever, true );
179+ TEST_ASSERT_EQUAL (SIGNAL1 | SIGNAL2 | SIGNAL3, ret);
180+ }
181+
182+ #if defined(MBED_CONF_RTOS_PRESENT)
183+
184+ #define TEST_STACK_SIZE 512
185+ #define PROHIBITED_SIGNAL 0x80000000
186+ #define MAX_FLAG_POS 30
187+
42188struct Sync {
43189 Sync (Semaphore &parent, Semaphore &child): sem_parent(parent), sem_child(child)
44190 {}
@@ -47,13 +193,6 @@ struct Sync {
47193 Semaphore &sem_child;
48194};
49195
50- template <int32_t signals, uint32_t timeout, uint32_t test_val>
51- void run_signal_wait (void )
52- {
53- uint32_t ret = ThisThread::flags_wait_all_for (signals, timeout);
54- TEST_ASSERT_EQUAL (test_val, ret);
55- }
56-
57196template <int32_t signals, uint32_t timeout, uint32_t test_val>
58197void run_release_signal_wait (Semaphore *sem)
59198{
@@ -71,13 +210,6 @@ void run_release_wait_signal_wait(Sync *sync)
71210 TEST_ASSERT_EQUAL (test_val, ret);
72211}
73212
74- template <int32_t signals, int32_t test_val>
75- void run_clear (void )
76- {
77- int32_t ret = ThisThread::flags_clear (signals);
78- TEST_ASSERT_EQUAL (test_val, ret);
79- }
80-
81213template <int32_t signals, int32_t test_val>
82214void run_wait_clear (Sync *sync)
83215{
@@ -87,20 +219,6 @@ void run_wait_clear(Sync *sync)
87219 TEST_ASSERT_EQUAL (test_val, ret);
88220}
89221
90- template <int32_t signals1, int32_t signals2, int32_t test_val1, int32_t test_val2>
91- void run_double_wait_clear (Sync *sync)
92- {
93- int32_t ret;
94-
95- sync->sem_parent .release ();
96- sync->sem_child .acquire ();
97- ret = ThisThread::flags_clear (signals1);
98- TEST_ASSERT_EQUAL (test_val1, ret);
99-
100- ret = ThisThread::flags_clear (signals2);
101- TEST_ASSERT_EQUAL (test_val2, ret);
102- }
103-
104222void run_loop_wait_clear (Sync *sync)
105223{
106224 int32_t signals = NO_SIGNALS;
@@ -114,6 +232,19 @@ void run_loop_wait_clear(Sync *sync)
114232 }
115233}
116234
235+ template <int32_t signals1, int32_t signals2, int32_t test_val1, int32_t test_val2>
236+ void run_double_wait_clear (Sync *sync)
237+ {
238+ int32_t ret;
239+
240+ sync->sem_parent .release ();
241+ sync->sem_child .acquire ();
242+ ret = ThisThread::flags_clear (signals1);
243+ TEST_ASSERT_EQUAL (test_val1, ret);
244+
245+ ret = ThisThread::flags_clear (signals2);
246+ TEST_ASSERT_EQUAL (test_val2, ret);
247+ }
117248
118249/* * Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals
119250
@@ -365,15 +496,26 @@ void test_set_double(void)
365496 TEST_ASSERT_EQUAL (NO_SIGNALS, ret);
366497 t.join ();
367498}
368-
499+ # endif
369500
370501utest::v1::status_t test_setup (const size_t number_of_cases)
371502{
372- GREENTEA_SETUP (10 , " default_auto" );
503+ GREENTEA_SETUP (20 , " default_auto" );
373504 return utest::v1::verbose_test_setup_handler (number_of_cases);
374505}
375506
376507Case cases[] = {
508+ Case (" Validate that ticker callback flags_clear(NO_SIGNALS) doesn't change main thread flags and return actual flags" , test_clear_no_signals_with_ticker),
509+ Case (" Validate if any flags are set on ticker callback" , test_init_state_with_ticker),
510+ Case (" Validate all flags clear in one shot using ticker callback" , test_clear_all_with_ticker),
511+ Case (" Validate ticker callback flags_wait return status if timeout specified: 0[ms] no flags" , test_wait_timeout_with_ticker<0 , 0 , 0 >),
512+ Case (" Validate ticker callback flags_wait return status if timeout specified: 0[ms] all flags" , test_wait_timeout_with_ticker<ALL_SIGNALS, 0 , 0 >),
513+ Case (" Validate ticker callback flags_wait return status if timeout specified: 1[ms] no flags" , test_wait_timeout_with_ticker<0 , 1 , 0 >),
514+ Case (" Validate ticker callback flags_wait return status if timeout specified: 1[ms] all flags" , test_wait_timeout_with_ticker<ALL_SIGNALS, 1 , 0 >),
515+ Case (" Validate that main thread call of flags_wait_all_for return correctly when ticker callback set all flags" , test_wait_all_already_set_with_ticker),
516+ Case (" Validate if setting same flag twice cause any unwanted behaviour when ticker callbacks set" , test_set_double_with_ticker),
517+ Case (" Validate if main thread flags_wait_all_for accumulate flags and return correctly when all flags set by ticker callback" , test_wait_all_loop_with_ticker),
518+ #if defined(MBED_CONF_RTOS_PRESENT)
377519 Case (" Validate that call flags_clear(NO_SIGNALS) doesn't change thread flags and return actual flags" , test_clear_no_signals),
378520 Case (" Validate if any flags are set on just created thread" , test_init_state),
379521 Case (" Validate all flags set in one shot" , test_set_all),
@@ -387,7 +529,9 @@ Case cases[] = {
387529 Case (" Validate that call of flags_wait_all_for return correctly when thread has all flags already set" , test_wait_all_already_set),
388530 Case (" Validate if flags_wait_all_for return correctly when all flags set" , test_wait_all),
389531 Case (" Validate if flags_wait_all_for accumulate flags and return correctly when all flags set" , test_wait_all_loop),
390- Case (" Validate if setting same flag twice cause any unwanted behaviour" , test_set_double)
532+ Case (" Validate if setting same flag twice cause any unwanted behaviour" , test_set_double),
533+
534+ #endif
391535};
392536
393537utest::v1::Specification specification (test_setup, cases);
@@ -398,4 +542,3 @@ int main()
398542}
399543
400544#endif // !DEVICE_USTICKER
401- #endif // defined(MBED_RTOS_SINGLE_THREAD) || !defined(MBED_CONF_RTOS_PRESENT)
0 commit comments