Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 17 2022 08:25:27 by 1.7.2