takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }