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