Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed.h" 00017 #include "greentea-client/test_env.h" 00018 #include "utest/utest.h" 00019 #include "unity/unity.h" 00020 00021 using utest::v1::Case; 00022 00023 00024 #if defined(MBED_RTOS_SINGLE_THREAD) 00025 #error [NOT_SUPPORTED] test not supported 00026 #endif 00027 00028 #define TEST_STACK_SIZE 512 00029 #define MAX_FLAG_POS 30 00030 00031 #define ALL_SIGNALS 0x7fffffff 00032 #define NO_SIGNALS 0x0 00033 #define PROHIBITED_SIGNAL 0x80000000 00034 #define SIGNAL1 0x1 00035 #define SIGNAL2 0x2 00036 #define SIGNAL3 0x4 00037 00038 struct Sync { 00039 Sync(Semaphore &parent, Semaphore &child): sem_parent(parent), sem_child(child) 00040 {} 00041 00042 Semaphore &sem_parent; 00043 Semaphore &sem_child; 00044 }; 00045 00046 00047 /* In order to successfully run this test suite when compiled with --profile=debug 00048 * error() has to be redefined as noop. 00049 * 00050 * ThreadFlags calls RTX API which uses Event Recorder functionality. When compiled 00051 * with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxEventFlagsError() calls error() 00052 * which aborts test program. 00053 */ 00054 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED 00055 void error(const char* format, ...) { 00056 (void) format; 00057 } 00058 #endif 00059 00060 00061 template <int32_t signals, uint32_t timeout, int32_t test_val> 00062 void run_signal_wait(void) 00063 { 00064 osEvent ev = Thread::signal_wait(signals, timeout); 00065 TEST_ASSERT_EQUAL(test_val, ev.status); 00066 } 00067 00068 template <int32_t signals, uint32_t timeout, int32_t test_val> 00069 void run_release_signal_wait(Semaphore *sem) 00070 { 00071 sem->release(); 00072 osEvent ev = Thread::signal_wait(signals, timeout); 00073 TEST_ASSERT_EQUAL(test_val, ev.status); 00074 } 00075 00076 template <int32_t signals, uint32_t timeout, int32_t test_val> 00077 void run_release_wait_signal_wait(Sync *sync) 00078 { 00079 sync->sem_parent.release(); 00080 sync->sem_child.wait(); 00081 osEvent ev = Thread::signal_wait(signals, timeout); 00082 TEST_ASSERT_EQUAL(test_val, ev.status); 00083 } 00084 00085 template <int32_t signals, int32_t test_val> 00086 void run_clear(void) 00087 { 00088 int32_t ret = Thread::signal_clr(signals); 00089 TEST_ASSERT_EQUAL(test_val, ret); 00090 } 00091 00092 template <int32_t signals, int32_t test_val> 00093 void run_wait_clear(Sync *sync) 00094 { 00095 sync->sem_parent.release(); 00096 sync->sem_child.wait(); 00097 int32_t ret = Thread::signal_clr(signals); 00098 TEST_ASSERT_EQUAL(test_val, ret); 00099 } 00100 00101 template <int32_t signals1, int32_t signals2, int32_t test_val1, int32_t test_val2> 00102 void run_double_wait_clear(Sync *sync) 00103 { 00104 int32_t ret; 00105 00106 sync->sem_parent.release(); 00107 sync->sem_child.wait(); 00108 ret = Thread::signal_clr(signals1); 00109 TEST_ASSERT_EQUAL(test_val1, ret); 00110 00111 ret = Thread::signal_clr(signals2); 00112 TEST_ASSERT_EQUAL(test_val2, ret); 00113 } 00114 00115 void run_loop_wait_clear(Sync *sync) 00116 { 00117 int32_t signals = NO_SIGNALS; 00118 for (int i = 0; i <= MAX_FLAG_POS; i++) { 00119 int32_t signal = 1 << i; 00120 signals |= signal; 00121 sync->sem_child.wait(); 00122 int32_t ret = Thread::signal_clr(NO_SIGNALS); 00123 TEST_ASSERT_EQUAL(signals, ret); 00124 sync->sem_parent.release(); 00125 } 00126 } 00127 00128 00129 /** Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals 00130 00131 Given two threads A & B are started, B with all signals already set 00132 When thread B calls @a signal_clr(NO_SIGNALS) 00133 Then thread B @a signal_clr status should be ALL_SIGNALS indicating that thread B state is unchanged 00134 */ 00135 void test_clear_no_signals(void) 00136 { 00137 Semaphore sem_parent(0, 1); 00138 Semaphore sem_child(0, 1); 00139 Sync sync(sem_parent, sem_child); 00140 00141 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00142 t.start(callback(run_double_wait_clear<NO_SIGNALS, NO_SIGNALS, ALL_SIGNALS, ALL_SIGNALS>, &sync)); 00143 sem_parent.wait(); 00144 t.signal_set(ALL_SIGNALS); 00145 sem_child.release(); 00146 t.join(); 00147 } 00148 00149 /** Validate if any signals are set on just created thread 00150 00151 Given the thread is running 00152 When thread execute @a signal_clr(NO_SIGNALS) 00153 Then thread @a signal_clr return status should be NO_SIGNALS(0) indicating no signals set 00154 */ 00155 void test_init_state(void) 00156 { 00157 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00158 t.start(callback(run_clear<NO_SIGNALS, NO_SIGNALS>)); 00159 t.join(); 00160 } 00161 00162 /** Validate all signals set in one shot 00163 00164 Given two threads A & B are started 00165 When thread A call @a signal_set(ALL_SIGNALS) with all possible signals 00166 Then thread B @a signal_clr(NO_SIGNALS) status should be ALL_SIGNALS indicating all signals set correctly 00167 */ 00168 void test_set_all(void) 00169 { 00170 int32_t ret; 00171 Semaphore sem_parent(0, 1); 00172 Semaphore sem_child(0, 1); 00173 Sync sync(sem_parent, sem_child); 00174 00175 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00176 t.start(callback(run_wait_clear<NO_SIGNALS, ALL_SIGNALS>, &sync)); 00177 00178 sem_parent.wait(); 00179 ret = t.signal_set(ALL_SIGNALS); 00180 TEST_ASSERT_EQUAL(ALL_SIGNALS, ret); 00181 00182 sem_child.release(); 00183 t.join(); 00184 } 00185 00186 /** Validate that call signal_set with prohibited signal doesn't change thread signals 00187 00188 Given two threads A & B are started, B with all signals set 00189 When thread A executes @a signal_set(PROHIBITED_SIGNAL) with prohibited signal 00190 Then thread B @a signal_clr(NO_SIGNALS) status should be ALL_SIGNALS indicating that thread B signals are unchanged 00191 00192 @note Each signal has up to 31 event flags 0x1, 0x2, 0x4, 0x8, ..., 0x40000000 00193 Most significant bit is reserved and thereby flag 0x80000000 is prohibited 00194 */ 00195 void test_set_prohibited(void) 00196 { 00197 int32_t ret; 00198 Semaphore sem_parent(0, 1); 00199 Semaphore sem_child(0, 1); 00200 Sync sync(sem_parent, sem_child); 00201 00202 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00203 t.start(callback(run_wait_clear<NO_SIGNALS, ALL_SIGNALS>, &sync)); 00204 00205 sem_parent.wait(); 00206 t.signal_set(ALL_SIGNALS); 00207 00208 ret = t.signal_set(PROHIBITED_SIGNAL); 00209 TEST_ASSERT_EQUAL(osErrorParameter, ret); 00210 00211 sem_child.release(); 00212 t.join(); 00213 } 00214 00215 /** Validate all signals clear in one shot 00216 00217 Given two threads A & B are started, B with all signals set 00218 When thread B execute @a signal_clr(ALL_SIGNALS) with all possible signals 00219 Then thread B @a signal_clr(NO_SIGNALS) status should be NO_SIGNALS(0) indicating all signals cleared correctly 00220 */ 00221 void test_clear_all(void) 00222 { 00223 Semaphore sem_parent(0, 1); 00224 Semaphore sem_child(0, 1); 00225 Sync sync(sem_parent, sem_child); 00226 00227 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00228 t.start(callback(run_double_wait_clear<ALL_SIGNALS, NO_SIGNALS, ALL_SIGNALS, NO_SIGNALS>, &sync)); 00229 sem_parent.wait(); 00230 t.signal_set(ALL_SIGNALS); 00231 sem_child.release(); 00232 t.join(); 00233 } 00234 00235 /** Validate all signals set one by one in loop 00236 00237 Given two threads A & B are started 00238 When thread A executes @a signal_set(signal) in loop with all possible signals 00239 */ 00240 void test_set_all_loop(void) 00241 { 00242 int32_t ret; 00243 Semaphore sem_parent(0, 1); 00244 Semaphore sem_child(0, 1); 00245 Sync sync(sem_parent, sem_child); 00246 00247 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00248 t.start(callback(run_loop_wait_clear, &sync)); 00249 00250 int32_t signals = 0; 00251 for (int i = 0; i <= MAX_FLAG_POS; i++) { 00252 int32_t signal = 1 << i; 00253 00254 ret = t.signal_set(signal); 00255 signals |= signal; 00256 TEST_ASSERT_EQUAL(signals, ret); 00257 sem_child.release(); 00258 sem_parent.wait(); 00259 } 00260 t.join(); 00261 } 00262 00263 /** Validate signal_wait return status if timeout specified 00264 00265 Given the thread is running 00266 When thread executes @a signal_wait(signals, timeout) with specified signals and timeout 00267 Then thread @a signal_wait status should be osEventTimeout indicating a timeout 00268 thread @a signal_wait status should be osOK indicating 0[ms] timeout set 00269 */ 00270 template <int32_t signals, uint32_t timeout, int32_t status> 00271 void test_wait_timeout(void) 00272 { 00273 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00274 t.start(callback(run_signal_wait<signals, timeout, status>)); 00275 t.join(); 00276 } 00277 00278 /** Validate that call of signal_wait return correctly when thread has all signals already set 00279 00280 Given two threads A & B are started, B with all signals already set 00281 When thread B executes @a signal_wait(ALL_SIGNALS, osWaitForever), 00282 Then thread B @a signal_wait return immediately with status osEventSignal indicating all wait signals was already set 00283 */ 00284 void test_wait_all_already_set(void) 00285 { 00286 Semaphore sem_parent(0, 1); 00287 Semaphore sem_child(0, 1); 00288 Sync sync(sem_parent, sem_child); 00289 00290 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00291 t.start(callback(run_release_wait_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sync)); 00292 00293 sem_parent.wait(); 00294 TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state()); 00295 t.signal_set(ALL_SIGNALS); 00296 sem_child.release(); 00297 t.join(); 00298 } 00299 00300 /** Validate if signal_wait return correctly when all signals set 00301 00302 Given two threads A & B are started and B waiting for a thread flag to be set 00303 When thread A executes @a signal_set(ALL_SIGNALS) with all possible signals 00304 Then thread B @a signal_wait status is osEventSignal indicating all wait signals was set 00305 */ 00306 void test_wait_all(void) 00307 { 00308 Semaphore sem(0, 1); 00309 00310 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00311 t.start(callback(run_release_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sem)); 00312 00313 sem.wait(); 00314 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00315 00316 t.signal_set(ALL_SIGNALS); 00317 t.join(); 00318 } 00319 00320 /** Validate if signal_wait accumulate signals and return correctly when all signals set 00321 00322 Given two threads A & B are started and B waiting for a thread signals to be set 00323 When thread A executes @a signal_set setting all signals in loop 00324 Then thread B @a signal_wait status is osEventSignal indicating that all wait signals was set 00325 */ 00326 void test_wait_all_loop(void) 00327 { 00328 int32_t ret; 00329 Semaphore sem(0, 1); 00330 00331 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00332 t.start(callback(run_release_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sem)); 00333 00334 sem.wait(); 00335 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00336 00337 for (int i = 0; i < MAX_FLAG_POS; i++) { 00338 int32_t signal = 1 << i; 00339 ret = t.signal_set(signal); 00340 } 00341 ret = t.signal_set(1 << MAX_FLAG_POS); 00342 TEST_ASSERT_EQUAL(NO_SIGNALS, ret); 00343 t.join(); 00344 } 00345 00346 /** Validate if setting same signal twice cause any unwanted behaviour 00347 00348 Given two threads A & B are started and B waiting for a thread signals to be set 00349 When thread A executes @a signal_set twice for the same signal 00350 Then thread A @a signal_set status is current signal set 00351 thread B @a signal_wait status is osEventSignal indicating that all wait signals was set 00352 */ 00353 void test_set_double(void) 00354 { 00355 int32_t ret; 00356 Semaphore sem(0, 1); 00357 00358 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00359 t.start(callback(run_release_signal_wait<SIGNAL1|SIGNAL2|SIGNAL3, osWaitForever, osEventSignal>, &sem)); 00360 00361 sem.wait(); 00362 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00363 00364 ret = t.signal_set(SIGNAL1); 00365 TEST_ASSERT_EQUAL(SIGNAL1, ret); 00366 00367 ret = t.signal_set(SIGNAL2); 00368 TEST_ASSERT_EQUAL(SIGNAL1 | SIGNAL2, ret); 00369 00370 ret = t.signal_set(SIGNAL2); 00371 TEST_ASSERT_EQUAL(SIGNAL1 | SIGNAL2, ret); 00372 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00373 00374 ret = t.signal_set(SIGNAL3); 00375 TEST_ASSERT_EQUAL(NO_SIGNALS, ret); 00376 t.join(); 00377 } 00378 00379 00380 utest::v1::status_t test_setup(const size_t number_of_cases) 00381 { 00382 GREENTEA_SETUP(10, "default_auto"); 00383 return utest::v1::verbose_test_setup_handler(number_of_cases); 00384 } 00385 00386 Case cases[] = { 00387 Case("Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals", test_clear_no_signals), 00388 Case("Validate if any signals are set on just created thread", test_init_state), 00389 Case("Validate all signals set in one shot", test_set_all), 00390 Case("Validate that call signal_set with prohibited signal doesn't change thread signals", test_set_prohibited), 00391 Case("Validate all signals clear in one shot", test_clear_all), 00392 Case("Validate all signals set one by one in loop", test_set_all_loop), 00393 Case("Validate signal_wait return status if timeout specified: 0[ms] no signals", test_wait_timeout<0, 0, osOK>), 00394 Case("Validate signal_wait return status if timeout specified: 0[ms] all signals", test_wait_timeout<ALL_SIGNALS, 0, osOK>), 00395 Case("Validate signal_wait return status if timeout specified: 1[ms] no signals", test_wait_timeout<0, 1, osEventTimeout>), 00396 Case("Validate signal_wait return status if timeout specified: 1[ms] all signals", test_wait_timeout<ALL_SIGNALS, 1, osEventTimeout>), 00397 Case("Validate that call of signal_wait return correctly when thread has all signals already set", test_wait_all_already_set), 00398 Case("Validate if signal_wait return correctly when all signals set", test_wait_all), 00399 Case("Validate if signal_wait accumulate signals and return correctly when all signals set", test_wait_all_loop), 00400 Case("Validate if setting same signal twice cause any unwanted behaviour", test_set_double) 00401 }; 00402 00403 utest::v1::Specification specification(test_setup, cases); 00404 00405 int main() 00406 { 00407 return !utest::v1::Harness::run(specification); 00408 }
Generated on Thu Jul 14 2022 14:36:19 by
