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 #if defined(MBED_RTOS_SINGLE_THREAD) 00024 #error [NOT_SUPPORTED] test not supported 00025 #endif 00026 00027 #if !DEVICE_USTICKER 00028 #error [NOT_SUPPORTED] test not supported 00029 #endif 00030 00031 #define TEST_STACK_SIZE 512 00032 #define MAX_FLAG_POS 30 00033 00034 #define ALL_SIGNALS 0x7fffffff 00035 #define NO_SIGNALS 0x0 00036 #define PROHIBITED_SIGNAL 0x80000000 00037 #define SIGNAL1 0x1 00038 #define SIGNAL2 0x2 00039 #define SIGNAL3 0x4 00040 00041 struct Sync { 00042 Sync(Semaphore &parent, Semaphore &child): sem_parent(parent), sem_child(child) 00043 {} 00044 00045 Semaphore &sem_parent; 00046 Semaphore &sem_child; 00047 }; 00048 00049 00050 /* In order to successfully run this test suite when compiled with --profile=debug 00051 * error() has to be redefined as noop. 00052 * 00053 * ThreadFlags calls RTX API which uses Event Recorder functionality. When compiled 00054 * with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxEventFlagsError() calls error() 00055 * which aborts test program. 00056 */ 00057 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED 00058 void error(const char* format, ...) { 00059 (void) format; 00060 } 00061 00062 mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) 00063 { 00064 return MBED_SUCCESS; 00065 } 00066 #endif 00067 00068 00069 template <int32_t signals, uint32_t timeout, int32_t test_val> 00070 void run_signal_wait(void) 00071 { 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_signal_wait(Semaphore *sem) 00078 { 00079 sem->release(); 00080 osEvent ev = Thread::signal_wait(signals, timeout); 00081 TEST_ASSERT_EQUAL(test_val, ev.status); 00082 } 00083 00084 template <int32_t signals, uint32_t timeout, int32_t test_val> 00085 void run_release_wait_signal_wait(Sync *sync) 00086 { 00087 sync->sem_parent.release(); 00088 sync->sem_child.wait(); 00089 osEvent ev = Thread::signal_wait(signals, timeout); 00090 TEST_ASSERT_EQUAL(test_val, ev.status); 00091 } 00092 00093 template <int32_t signals, int32_t test_val> 00094 void run_clear(void) 00095 { 00096 int32_t ret = Thread::signal_clr(signals); 00097 TEST_ASSERT_EQUAL(test_val, ret); 00098 } 00099 00100 template <int32_t signals, int32_t test_val> 00101 void run_wait_clear(Sync *sync) 00102 { 00103 sync->sem_parent.release(); 00104 sync->sem_child.wait(); 00105 int32_t ret = Thread::signal_clr(signals); 00106 TEST_ASSERT_EQUAL(test_val, ret); 00107 } 00108 00109 template <int32_t signals1, int32_t signals2, int32_t test_val1, int32_t test_val2> 00110 void run_double_wait_clear(Sync *sync) 00111 { 00112 int32_t ret; 00113 00114 sync->sem_parent.release(); 00115 sync->sem_child.wait(); 00116 ret = Thread::signal_clr(signals1); 00117 TEST_ASSERT_EQUAL(test_val1, ret); 00118 00119 ret = Thread::signal_clr(signals2); 00120 TEST_ASSERT_EQUAL(test_val2, ret); 00121 } 00122 00123 void run_loop_wait_clear(Sync *sync) 00124 { 00125 int32_t signals = NO_SIGNALS; 00126 for (int i = 0; i <= MAX_FLAG_POS; i++) { 00127 int32_t signal = 1 << i; 00128 signals |= signal; 00129 sync->sem_child.wait(); 00130 int32_t ret = Thread::signal_clr(NO_SIGNALS); 00131 TEST_ASSERT_EQUAL(signals, ret); 00132 sync->sem_parent.release(); 00133 } 00134 } 00135 00136 00137 /** Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals 00138 00139 Given two threads A & B are started, B with all signals already set 00140 When thread B calls @a signal_clr(NO_SIGNALS) 00141 Then thread B @a signal_clr status should be ALL_SIGNALS indicating that thread B state is unchanged 00142 */ 00143 void test_clear_no_signals(void) 00144 { 00145 Semaphore sem_parent(0, 1); 00146 Semaphore sem_child(0, 1); 00147 Sync sync(sem_parent, sem_child); 00148 00149 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00150 t.start(callback(run_double_wait_clear<NO_SIGNALS, NO_SIGNALS, ALL_SIGNALS, ALL_SIGNALS>, &sync)); 00151 sem_parent.wait(); 00152 t.signal_set(ALL_SIGNALS); 00153 sem_child.release(); 00154 t.join(); 00155 } 00156 00157 /** Validate if any signals are set on just created thread 00158 00159 Given the thread is running 00160 When thread execute @a signal_clr(NO_SIGNALS) 00161 Then thread @a signal_clr return status should be NO_SIGNALS(0) indicating no signals set 00162 */ 00163 void test_init_state(void) 00164 { 00165 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00166 t.start(callback(run_clear<NO_SIGNALS, NO_SIGNALS>)); 00167 t.join(); 00168 } 00169 00170 /** Validate all signals set in one shot 00171 00172 Given two threads A & B are started 00173 When thread A call @a signal_set(ALL_SIGNALS) with all possible signals 00174 Then thread B @a signal_clr(NO_SIGNALS) status should be ALL_SIGNALS indicating all signals set correctly 00175 */ 00176 void test_set_all(void) 00177 { 00178 int32_t ret; 00179 Semaphore sem_parent(0, 1); 00180 Semaphore sem_child(0, 1); 00181 Sync sync(sem_parent, sem_child); 00182 00183 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00184 t.start(callback(run_wait_clear<NO_SIGNALS, ALL_SIGNALS>, &sync)); 00185 00186 sem_parent.wait(); 00187 ret = t.signal_set(ALL_SIGNALS); 00188 TEST_ASSERT_EQUAL(ALL_SIGNALS, ret); 00189 00190 sem_child.release(); 00191 t.join(); 00192 } 00193 00194 /** Validate that call signal_set with prohibited signal doesn't change thread signals 00195 00196 Given two threads A & B are started, B with all signals set 00197 When thread A executes @a signal_set(PROHIBITED_SIGNAL) with prohibited signal 00198 Then thread B @a signal_clr(NO_SIGNALS) status should be ALL_SIGNALS indicating that thread B signals are unchanged 00199 00200 @note Each signal has up to 31 event flags 0x1, 0x2, 0x4, 0x8, ..., 0x40000000 00201 Most significant bit is reserved and thereby flag 0x80000000 is prohibited 00202 */ 00203 void test_set_prohibited(void) 00204 { 00205 int32_t ret; 00206 Semaphore sem_parent(0, 1); 00207 Semaphore sem_child(0, 1); 00208 Sync sync(sem_parent, sem_child); 00209 00210 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00211 t.start(callback(run_wait_clear<NO_SIGNALS, ALL_SIGNALS>, &sync)); 00212 00213 sem_parent.wait(); 00214 t.signal_set(ALL_SIGNALS); 00215 00216 ret = t.signal_set(PROHIBITED_SIGNAL); 00217 TEST_ASSERT_EQUAL(osErrorParameter, ret); 00218 00219 sem_child.release(); 00220 t.join(); 00221 } 00222 00223 /** Validate all signals clear in one shot 00224 00225 Given two threads A & B are started, B with all signals set 00226 When thread B execute @a signal_clr(ALL_SIGNALS) with all possible signals 00227 Then thread B @a signal_clr(NO_SIGNALS) status should be NO_SIGNALS(0) indicating all signals cleared correctly 00228 */ 00229 void test_clear_all(void) 00230 { 00231 Semaphore sem_parent(0, 1); 00232 Semaphore sem_child(0, 1); 00233 Sync sync(sem_parent, sem_child); 00234 00235 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00236 t.start(callback(run_double_wait_clear<ALL_SIGNALS, NO_SIGNALS, ALL_SIGNALS, NO_SIGNALS>, &sync)); 00237 sem_parent.wait(); 00238 t.signal_set(ALL_SIGNALS); 00239 sem_child.release(); 00240 t.join(); 00241 } 00242 00243 /** Validate all signals set one by one in loop 00244 00245 Given two threads A & B are started 00246 When thread A executes @a signal_set(signal) in loop with all possible signals 00247 */ 00248 void test_set_all_loop(void) 00249 { 00250 int32_t ret; 00251 Semaphore sem_parent(0, 1); 00252 Semaphore sem_child(0, 1); 00253 Sync sync(sem_parent, sem_child); 00254 00255 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00256 t.start(callback(run_loop_wait_clear, &sync)); 00257 00258 int32_t signals = 0; 00259 for (int i = 0; i <= MAX_FLAG_POS; i++) { 00260 int32_t signal = 1 << i; 00261 00262 ret = t.signal_set(signal); 00263 signals |= signal; 00264 TEST_ASSERT_EQUAL(signals, ret); 00265 sem_child.release(); 00266 sem_parent.wait(); 00267 } 00268 t.join(); 00269 } 00270 00271 /** Validate signal_wait return status if timeout specified 00272 00273 Given the thread is running 00274 When thread executes @a signal_wait(signals, timeout) with specified signals and timeout 00275 Then thread @a signal_wait status should be osEventTimeout indicating a timeout 00276 thread @a signal_wait status should be osOK indicating 0[ms] timeout set 00277 */ 00278 template <int32_t signals, uint32_t timeout, int32_t status> 00279 void test_wait_timeout(void) 00280 { 00281 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00282 t.start(callback(run_signal_wait<signals, timeout, status>)); 00283 t.join(); 00284 } 00285 00286 /** Validate that call of signal_wait return correctly when thread has all signals already set 00287 00288 Given two threads A & B are started, B with all signals already set 00289 When thread B executes @a signal_wait(ALL_SIGNALS, osWaitForever), 00290 Then thread B @a signal_wait return immediately with status osEventSignal indicating all wait signals was already set 00291 */ 00292 void test_wait_all_already_set(void) 00293 { 00294 Semaphore sem_parent(0, 1); 00295 Semaphore sem_child(0, 1); 00296 Sync sync(sem_parent, sem_child); 00297 00298 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00299 t.start(callback(run_release_wait_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sync)); 00300 00301 sem_parent.wait(); 00302 TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state()); 00303 t.signal_set(ALL_SIGNALS); 00304 sem_child.release(); 00305 t.join(); 00306 } 00307 00308 /** Validate if signal_wait return correctly when all signals set 00309 00310 Given two threads A & B are started and B waiting for a thread flag to be set 00311 When thread A executes @a signal_set(ALL_SIGNALS) with all possible signals 00312 Then thread B @a signal_wait status is osEventSignal indicating all wait signals was set 00313 */ 00314 void test_wait_all(void) 00315 { 00316 Semaphore sem(0, 1); 00317 00318 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00319 t.start(callback(run_release_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sem)); 00320 00321 sem.wait(); 00322 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00323 00324 t.signal_set(ALL_SIGNALS); 00325 t.join(); 00326 } 00327 00328 /** Validate if signal_wait accumulate signals and return correctly when all signals set 00329 00330 Given two threads A & B are started and B waiting for a thread signals to be set 00331 When thread A executes @a signal_set setting all signals in loop 00332 Then thread B @a signal_wait status is osEventSignal indicating that all wait signals was set 00333 */ 00334 void test_wait_all_loop(void) 00335 { 00336 int32_t ret; 00337 Semaphore sem(0, 1); 00338 00339 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00340 t.start(callback(run_release_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sem)); 00341 00342 sem.wait(); 00343 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00344 00345 for (int i = 0; i < MAX_FLAG_POS; i++) { 00346 int32_t signal = 1 << i; 00347 ret = t.signal_set(signal); 00348 } 00349 ret = t.signal_set(1 << MAX_FLAG_POS); 00350 TEST_ASSERT_EQUAL(NO_SIGNALS, ret); 00351 t.join(); 00352 } 00353 00354 /** Validate if setting same signal twice cause any unwanted behaviour 00355 00356 Given two threads A & B are started and B waiting for a thread signals to be set 00357 When thread A executes @a signal_set twice for the same signal 00358 Then thread A @a signal_set status is current signal set 00359 thread B @a signal_wait status is osEventSignal indicating that all wait signals was set 00360 */ 00361 void test_set_double(void) 00362 { 00363 int32_t ret; 00364 Semaphore sem(0, 1); 00365 00366 Thread t(osPriorityNormal, TEST_STACK_SIZE); 00367 t.start(callback(run_release_signal_wait<SIGNAL1|SIGNAL2|SIGNAL3, osWaitForever, osEventSignal>, &sem)); 00368 00369 sem.wait(); 00370 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00371 00372 ret = t.signal_set(SIGNAL1); 00373 TEST_ASSERT_EQUAL(SIGNAL1, ret); 00374 00375 ret = t.signal_set(SIGNAL2); 00376 TEST_ASSERT_EQUAL(SIGNAL1 | SIGNAL2, ret); 00377 00378 ret = t.signal_set(SIGNAL2); 00379 TEST_ASSERT_EQUAL(SIGNAL1 | SIGNAL2, ret); 00380 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state()); 00381 00382 ret = t.signal_set(SIGNAL3); 00383 TEST_ASSERT_EQUAL(NO_SIGNALS, ret); 00384 t.join(); 00385 } 00386 00387 00388 utest::v1::status_t test_setup(const size_t number_of_cases) 00389 { 00390 GREENTEA_SETUP(10, "default_auto"); 00391 return utest::v1::verbose_test_setup_handler(number_of_cases); 00392 } 00393 00394 Case cases[] = { 00395 Case("Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals", test_clear_no_signals), 00396 Case("Validate if any signals are set on just created thread", test_init_state), 00397 Case("Validate all signals set in one shot", test_set_all), 00398 Case("Validate that call signal_set with prohibited signal doesn't change thread signals", test_set_prohibited), 00399 Case("Validate all signals clear in one shot", test_clear_all), 00400 Case("Validate all signals set one by one in loop", test_set_all_loop), 00401 Case("Validate signal_wait return status if timeout specified: 0[ms] no signals", test_wait_timeout<0, 0, osOK>), 00402 Case("Validate signal_wait return status if timeout specified: 0[ms] all signals", test_wait_timeout<ALL_SIGNALS, 0, osOK>), 00403 Case("Validate signal_wait return status if timeout specified: 1[ms] no signals", test_wait_timeout<0, 1, osEventTimeout>), 00404 Case("Validate signal_wait return status if timeout specified: 1[ms] all signals", test_wait_timeout<ALL_SIGNALS, 1, osEventTimeout>), 00405 Case("Validate that call of signal_wait return correctly when thread has all signals already set", test_wait_all_already_set), 00406 Case("Validate if signal_wait return correctly when all signals set", test_wait_all), 00407 Case("Validate if signal_wait accumulate signals and return correctly when all signals set", test_wait_all_loop), 00408 Case("Validate if setting same signal twice cause any unwanted behaviour", test_set_double) 00409 }; 00410 00411 utest::v1::Specification specification(test_setup, cases); 00412 00413 int main() 00414 { 00415 return !utest::v1::Harness::run(specification); 00416 }
Generated on Tue Jul 12 2022 12:45:24 by
