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