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.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
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 "unity.h" 00019 #include "utest.h" 00020 #include "rtos.h" 00021 00022 #if defined(MBED_RTOS_SINGLE_THREAD) 00023 #error [NOT_SUPPORTED] test not supported 00024 #endif 00025 00026 using namespace utest::v1; 00027 00028 #define TEST_STACK_SIZE 512 00029 00030 #define TEST_LONG_DELAY 20 00031 #define TEST_DELAY 10 00032 #define SIGNALS_TO_EMIT 100 00033 00034 Mutex stdio_mutex; 00035 00036 volatile int change_counter = 0; 00037 volatile bool changing_counter = false; 00038 volatile bool mutex_defect = false; 00039 00040 bool manipulate_protected_zone(const int thread_delay) 00041 { 00042 bool result = true; 00043 00044 osStatus stat = stdio_mutex.lock(); 00045 TEST_ASSERT_EQUAL(osOK, stat); 00046 00047 core_util_critical_section_enter(); 00048 if (changing_counter == true) { 00049 result = false; 00050 mutex_defect = true; 00051 } 00052 changing_counter = true; 00053 00054 change_counter++; 00055 core_util_critical_section_exit(); 00056 00057 Thread::wait(thread_delay); 00058 00059 core_util_critical_section_enter(); 00060 changing_counter = false; 00061 core_util_critical_section_exit(); 00062 00063 stat = stdio_mutex.unlock(); 00064 TEST_ASSERT_EQUAL(osOK, stat); 00065 return result; 00066 } 00067 00068 void test_thread(int const *thread_delay) 00069 { 00070 while (true) { 00071 manipulate_protected_zone(*thread_delay); 00072 } 00073 } 00074 00075 /** Test multiple thread 00076 00077 Given 3 threads started with different delays and a section protected with a mutex 00078 when each thread runs it tries to lock the mutex 00079 then no more than one thread should be able to access protected region 00080 */ 00081 void test_multiple_threads(void) 00082 { 00083 const int t1_delay = TEST_DELAY * 1; 00084 const int t2_delay = TEST_DELAY * 2; 00085 const int t3_delay = TEST_DELAY * 3; 00086 00087 Thread t2(osPriorityNormal, TEST_STACK_SIZE); 00088 Thread t3(osPriorityNormal, TEST_STACK_SIZE); 00089 00090 t2.start(callback(test_thread, &t2_delay)); 00091 t3.start(callback(test_thread, &t3_delay)); 00092 00093 while (true) { 00094 // Thread 1 action 00095 Thread::wait(t1_delay); 00096 manipulate_protected_zone(t1_delay); 00097 00098 core_util_critical_section_enter(); 00099 if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true) { 00100 core_util_critical_section_exit(); 00101 t2.terminate(); 00102 t3.terminate(); 00103 break; 00104 } 00105 core_util_critical_section_exit(); 00106 } 00107 00108 TEST_ASSERT_EQUAL(false, mutex_defect); 00109 } 00110 00111 void test_dual_thread_nolock_lock_thread(Mutex *mutex) 00112 { 00113 osStatus stat = mutex->lock(osWaitForever); 00114 TEST_ASSERT_EQUAL(osOK, stat); 00115 00116 stat = mutex->unlock(); 00117 TEST_ASSERT_EQUAL(osOK, stat); 00118 } 00119 00120 void test_dual_thread_nolock_trylock_thread(Mutex *mutex) 00121 { 00122 bool stat_b = mutex->trylock(); 00123 TEST_ASSERT_EQUAL(true, stat_b); 00124 00125 osStatus stat = mutex->unlock(); 00126 TEST_ASSERT_EQUAL(osOK, stat); 00127 } 00128 00129 /** Test dual thread no-lock 00130 00131 Test dual thread second thread lock 00132 Given two threads A & B and a mutex 00133 When thread A creates a mutex and starts thread B 00134 and thread B calls @a lock and @a unlock 00135 Then returned statuses are osOK 00136 00137 Test dual thread second thread trylock 00138 Given two threads A & B and a mutex 00139 When thread A creates a mutex and starts thread B 00140 and thread B calls @a trylock and @a unlock 00141 Then returned statuses are true and osOK 00142 */ 00143 template <void (*F)(Mutex *)> 00144 void test_dual_thread_nolock(void) 00145 { 00146 Mutex mutex; 00147 Thread thread(osPriorityNormal, TEST_STACK_SIZE); 00148 00149 thread.start(callback(F, &mutex)); 00150 00151 wait_ms(TEST_DELAY); 00152 } 00153 00154 void test_dual_thread_lock_unlock_thread(Mutex *mutex) 00155 { 00156 osStatus stat = mutex->lock(osWaitForever); 00157 TEST_ASSERT_EQUAL(osOK, stat); 00158 } 00159 00160 /** Test dual thread lock unlock 00161 00162 Given two threads and a lock 00163 When thread A locks the lock and starts thread B 00164 and thread B calls @a lock on the mutex 00165 Then thread B waits for thread A to unlock the lock 00166 When thread A calls @a unlock on the mutex 00167 Then thread B acquires the lock 00168 */ 00169 void test_dual_thread_lock_unlock(void) 00170 { 00171 Mutex mutex; 00172 osStatus stat; 00173 Thread thread(osPriorityNormal, TEST_STACK_SIZE); 00174 00175 stat = mutex.lock(); 00176 TEST_ASSERT_EQUAL(osOK, stat); 00177 00178 thread.start(callback(test_dual_thread_lock_unlock_thread, &mutex)); 00179 00180 stat = mutex.unlock(); 00181 TEST_ASSERT_EQUAL(osOK, stat); 00182 00183 wait_ms(TEST_DELAY); 00184 } 00185 00186 void test_dual_thread_lock_trylock_thread(Mutex *mutex) 00187 { 00188 bool stat = mutex->trylock(); 00189 TEST_ASSERT_EQUAL(false, stat); 00190 } 00191 00192 void test_dual_thread_lock_lock_thread(Mutex *mutex) 00193 { 00194 Timer timer; 00195 timer.start(); 00196 00197 osStatus stat = mutex->lock(TEST_DELAY); 00198 TEST_ASSERT_EQUAL(osErrorTimeout, stat); 00199 TEST_ASSERT_UINT32_WITHIN(5000, TEST_DELAY*1000, timer.read_us()); 00200 } 00201 00202 /** Test dual thread lock 00203 00204 Test dual thread lock locked 00205 Given a mutex and two threads A & B 00206 When thread A calls @a lock and starts thread B 00207 and thread B calls @a lock with 500ms timeout 00208 Then thread B waits 500ms and timeouts 00209 00210 Test dual thread trylock locked 00211 Given a mutex and two threads A & B 00212 When thread A calls @a lock and starts thread B 00213 Then thread B calls @a trylock 00214 and thread B fails to acquire the lock 00215 */ 00216 template <void (*F)(Mutex *)> 00217 void test_dual_thread_lock(void) 00218 { 00219 Mutex mutex; 00220 osStatus stat; 00221 Thread thread(osPriorityNormal, TEST_STACK_SIZE); 00222 00223 stat = mutex.lock(); 00224 TEST_ASSERT_EQUAL(osOK, stat); 00225 00226 thread.start(callback(F, &mutex)); 00227 00228 wait_ms(TEST_LONG_DELAY); 00229 00230 stat = mutex.unlock(); 00231 TEST_ASSERT_EQUAL(osOK, stat); 00232 } 00233 00234 /** Test single thread lock recursive 00235 00236 Given a mutex and a single running thread 00237 When thread calls @a lock twice and @a unlock twice on the mutex 00238 Then the returned statuses are osOK 00239 */ 00240 void test_single_thread_lock_recursive(void) 00241 { 00242 Mutex mutex; 00243 osStatus stat; 00244 00245 stat = mutex.lock(); 00246 TEST_ASSERT_EQUAL(osOK, stat); 00247 00248 stat = mutex.lock(); 00249 TEST_ASSERT_EQUAL(osOK, stat); 00250 00251 stat = mutex.unlock(); 00252 TEST_ASSERT_EQUAL(osOK, stat); 00253 00254 stat = mutex.unlock(); 00255 TEST_ASSERT_EQUAL(osOK, stat); 00256 } 00257 00258 /** Test single thread trylock 00259 00260 Given a mutex and a single running thread 00261 When thread calls @a trylock and @a unlock on the mutex 00262 Then the returned statuses are osOK 00263 */ 00264 void test_single_thread_trylock(void) 00265 { 00266 Mutex mutex; 00267 00268 bool stat_b = mutex.trylock(); 00269 TEST_ASSERT_EQUAL(true, stat_b); 00270 00271 osStatus stat = mutex.unlock(); 00272 TEST_ASSERT_EQUAL(osOK, stat); 00273 } 00274 00275 /** Test single thread lock 00276 00277 Given a mutex and a single running thread 00278 When thread calls @a lock and @a unlock on the mutex 00279 Then the returned statuses are osOK 00280 */ 00281 void test_single_thread_lock(void) 00282 { 00283 Mutex mutex; 00284 osStatus stat; 00285 00286 stat = mutex.lock(); 00287 TEST_ASSERT_EQUAL(osOK, stat); 00288 00289 stat = mutex.unlock(); 00290 TEST_ASSERT_EQUAL(osOK, stat); 00291 } 00292 00293 utest::v1::status_t test_setup(const size_t number_of_cases) 00294 { 00295 GREENTEA_SETUP(10, "default_auto"); 00296 return verbose_test_setup_handler(number_of_cases); 00297 } 00298 00299 Case cases[] = { 00300 Case("Test single thread lock", test_single_thread_lock), 00301 Case("Test single thread trylock", test_single_thread_trylock), 00302 Case("Test single thread lock recursive", test_single_thread_lock_recursive), 00303 Case("Test dual thread lock locked", test_dual_thread_lock<test_dual_thread_lock_lock_thread>), 00304 Case("Test dual thread trylock locked", test_dual_thread_lock<test_dual_thread_lock_trylock_thread>), 00305 Case("Test dual thread lock unlock", test_dual_thread_lock_unlock), 00306 Case("Test dual thread second thread lock", test_dual_thread_nolock<test_dual_thread_nolock_lock_thread>), 00307 Case("Test dual thread second thread trylock", test_dual_thread_nolock<test_dual_thread_nolock_trylock_thread>), 00308 Case("Test multiple thread", test_multiple_threads), 00309 }; 00310 00311 Specification specification(test_setup, cases); 00312 00313 int main() 00314 { 00315 return !Harness::run(specification); 00316 }
Generated on Tue Jul 12 2022 13:03:02 by
