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 "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 THREAD_STACK_SIZE 512 00029 #define TEST_UINT_MSG 0xDEADBEEF 00030 #define TEST_UINT_MSG2 0xE1EE7 00031 #define TEST_TIMEOUT 50 00032 00033 template <uint32_t ms> 00034 void thread_put_uint_msg(Queue<uint32_t, 1> *q) 00035 { 00036 Thread::wait(ms); 00037 osStatus stat = q->put((uint32_t*) TEST_UINT_MSG); 00038 TEST_ASSERT_EQUAL(osOK, stat); 00039 } 00040 00041 template <uint32_t ms, uint32_t val> 00042 void thread_get_uint_msg(Queue<uint32_t, 1> *q) 00043 { 00044 Thread::wait(ms); 00045 osEvent evt = q->get(); 00046 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00047 TEST_ASSERT_EQUAL(val, evt.value.v); 00048 } 00049 00050 /** Test pass uint msg 00051 00052 Given a queue for uint32_t messages with one slot 00053 When a uin32_t value is inserted into the queue 00054 and a message is extracted from the queue 00055 Then the extracted message is the same as previously inserted message 00056 */ 00057 void test_pass_uint() 00058 { 00059 Queue<uint32_t, 1> q; 00060 osStatus stat = q.put((uint32_t*)TEST_UINT_MSG); 00061 TEST_ASSERT_EQUAL(osOK, stat); 00062 00063 osEvent evt = q.get(); 00064 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00065 TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); 00066 } 00067 00068 /** Test pass uint msg twice 00069 00070 Given a queue for uint32_t messages with one slot 00071 When a uin32_t value is inserted into the queue 00072 and a message is extracted from the queue 00073 and the procedure is repeated with different message 00074 Then the extracted message is the same as previously inserted message for both iterations 00075 00076 */ 00077 void test_pass_uint_twice() 00078 { 00079 Queue<uint32_t, 1> q; 00080 osStatus stat = q.put((uint32_t*)TEST_UINT_MSG); 00081 TEST_ASSERT_EQUAL(osOK, stat); 00082 00083 osEvent evt = q.get(); 00084 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00085 TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); 00086 00087 stat = q.put((uint32_t*)TEST_UINT_MSG2); 00088 TEST_ASSERT_EQUAL(osOK, stat); 00089 00090 evt = q.get(); 00091 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00092 TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v); 00093 } 00094 00095 /** Test pass ptr msg 00096 00097 Given a queue for pointers to uint32_t messages with one slot 00098 When a pointer to an uint32_t is inserted into the queue 00099 and a message is extracted from the queue 00100 Then the extracted message is the same as previously inserted message 00101 */ 00102 void test_pass_ptr() 00103 { 00104 Queue<uint32_t, 1> q; 00105 uint32_t msg = TEST_UINT_MSG; 00106 00107 osStatus stat = q.put(&msg); 00108 TEST_ASSERT_EQUAL(osOK, stat); 00109 00110 osEvent evt = q.get(); 00111 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00112 TEST_ASSERT_EQUAL(&msg, evt.value.p); 00113 } 00114 00115 /** Test get from empty queue 00116 00117 Given an empty queue for uint32_t values 00118 When @a get is called on the queue with timeout of 0 00119 Then queue returns status of osOK, but no data 00120 */ 00121 void test_get_empty_no_timeout() 00122 { 00123 Queue<uint32_t, 1> q; 00124 00125 osEvent evt = q.get(0); 00126 TEST_ASSERT_EQUAL(osOK, evt.status); 00127 } 00128 00129 /** Test get from empty queue with timeout 00130 00131 Given an empty queue for uint32_t values 00132 When @a get is called on the queue with timeout of 50ms 00133 Then queue returns status of osEventTimeout after about 50ms wait 00134 */ 00135 void test_get_empty_timeout() 00136 { 00137 Queue<uint32_t, 1> q; 00138 Timer timer; 00139 timer.start(); 00140 00141 osEvent evt = q.get(50); 00142 TEST_ASSERT_EQUAL(osEventTimeout, evt.status); 00143 TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us()); 00144 } 00145 00146 /** Test get empty wait forever 00147 00148 Given a two threads A & B and a queue for uint32_t values 00149 When thread A calls @a get on an empty queue with osWaitForever 00150 Then the thread A waits for a message to appear in the queue 00151 When thread B puts a message in the queue 00152 Then thread A wakes up and receives it 00153 */ 00154 void test_get_empty_wait_forever() 00155 { 00156 Thread t(osPriorityNormal, THREAD_STACK_SIZE); 00157 Queue<uint32_t, 1> q; 00158 00159 t.start(callback(thread_put_uint_msg<TEST_TIMEOUT>, &q)); 00160 00161 Timer timer; 00162 timer.start(); 00163 00164 osEvent evt = q.get(); 00165 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00166 TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); 00167 TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us()); 00168 } 00169 00170 /** Test put full no timeout 00171 * 00172 * Given a queue with one slot for uint32_t data 00173 * When a thread tries to insert two messages 00174 * Then first operation succeeds and second fails with @a osErrorResource 00175 */ 00176 void test_put_full_no_timeout() 00177 { 00178 Queue<uint32_t, 1> q; 00179 00180 osStatus stat = q.put((uint32_t*) TEST_UINT_MSG); 00181 TEST_ASSERT_EQUAL(osOK, stat); 00182 00183 stat = q.put((uint32_t*) TEST_UINT_MSG); 00184 TEST_ASSERT_EQUAL(osErrorResource, stat); 00185 } 00186 00187 /** Test put full timeout 00188 * 00189 * Given a queue with one slot for uint32_t data 00190 * When a thread tries to insert two messages with @ TEST_TIMEOUT timeout 00191 * Then first operation succeeds and second fails with @a osErrorTimeout 00192 */ 00193 void test_put_full_timeout() 00194 { 00195 Queue<uint32_t, 1> q; 00196 00197 osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT); 00198 TEST_ASSERT_EQUAL(osOK, stat); 00199 00200 Timer timer; 00201 timer.start(); 00202 00203 stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT); 00204 TEST_ASSERT_EQUAL(osErrorTimeout, stat); 00205 TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us()); 00206 } 00207 00208 /** Test put full wait forever 00209 * 00210 * Given two threads A & B and a queue with one slot for uint32_t data 00211 * When thread A puts a message to the queue and tries to put second one with @a osWaitForever timeout 00212 * Then thread waits for a slot to become empty in the queue 00213 * When thread B takes one message out of the queue 00214 * Then thread A successfully inserts message into the queue 00215 */ 00216 void test_put_full_waitforever() 00217 { 00218 Thread t(osPriorityNormal, THREAD_STACK_SIZE); 00219 Queue<uint32_t, 1> q; 00220 00221 t.start(callback(thread_get_uint_msg<TEST_TIMEOUT, TEST_UINT_MSG>, &q)); 00222 00223 osStatus stat = q.put((uint32_t*) TEST_UINT_MSG); 00224 TEST_ASSERT_EQUAL(osOK, stat); 00225 00226 Timer timer; 00227 timer.start(); 00228 stat = q.put((uint32_t*) TEST_UINT_MSG, osWaitForever); 00229 TEST_ASSERT_EQUAL(osOK, stat); 00230 TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us()); 00231 00232 t.join(); 00233 } 00234 00235 /** Test message ordering 00236 00237 Given a queue of uint32_t data 00238 When two messages are inserted with equal priority 00239 Then messages should be returned in the exact order they were inserted 00240 */ 00241 void test_msg_order() 00242 { 00243 Queue<uint32_t, 2> q; 00244 00245 osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT); 00246 TEST_ASSERT_EQUAL(osOK, stat); 00247 00248 stat = q.put((uint32_t*) TEST_UINT_MSG2, TEST_TIMEOUT); 00249 TEST_ASSERT_EQUAL(osOK, stat); 00250 00251 osEvent evt = q.get(); 00252 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00253 TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); 00254 00255 evt = q.get(); 00256 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00257 TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v); 00258 } 00259 00260 /** Test message priority 00261 00262 Given a queue of uint32_t data 00263 When two messages are inserted with ascending priority 00264 Then messages should be returned in descending priority order 00265 */ 00266 void test_msg_prio() 00267 { 00268 Queue<uint32_t, 2> q; 00269 00270 osStatus stat = q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 0); 00271 TEST_ASSERT_EQUAL(osOK, stat); 00272 00273 stat = q.put((uint32_t*) TEST_UINT_MSG2, TEST_TIMEOUT, 1); 00274 TEST_ASSERT_EQUAL(osOK, stat); 00275 00276 osEvent evt = q.get(); 00277 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00278 TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v); 00279 00280 evt = q.get(); 00281 TEST_ASSERT_EQUAL(osEventMessage, evt.status); 00282 TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); 00283 } 00284 00285 /** Test queue empty 00286 00287 Given a queue of uint32_t data 00288 before data is inserted the queue should be empty 00289 after data is inserted the queue shouldn't be empty 00290 */ 00291 void test_queue_empty() 00292 { 00293 Queue<uint32_t, 1> q; 00294 00295 TEST_ASSERT_EQUAL(true, q.empty()); 00296 00297 q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 1); 00298 00299 TEST_ASSERT_EQUAL(false, q.empty()); 00300 } 00301 00302 /** Test queue empty 00303 00304 Given a queue of uint32_t data with size of 1 00305 before data is inserted the queue shouldn't be full 00306 after data is inserted the queue should be full 00307 */ 00308 void test_queue_full() 00309 { 00310 Queue<uint32_t, 1> q; 00311 00312 TEST_ASSERT_EQUAL(false, q.full()); 00313 00314 q.put((uint32_t*) TEST_UINT_MSG, TEST_TIMEOUT, 1); 00315 00316 TEST_ASSERT_EQUAL(true, q.full()); 00317 } 00318 00319 utest::v1::status_t test_setup(const size_t number_of_cases) 00320 { 00321 GREENTEA_SETUP(5, "default_auto"); 00322 return verbose_test_setup_handler(number_of_cases); 00323 } 00324 00325 Case cases[] = { 00326 Case("Test pass uint msg", test_pass_uint), 00327 Case("Test pass uint msg twice", test_pass_uint_twice), 00328 Case("Test pass ptr msg", test_pass_ptr), 00329 Case("Test get from empty queue no timeout", test_get_empty_no_timeout), 00330 Case("Test get from empty queue timeout", test_get_empty_timeout), 00331 Case("Test get empty wait forever", test_get_empty_wait_forever), 00332 Case("Test put full no timeout", test_put_full_no_timeout), 00333 Case("Test put full timeout", test_put_full_timeout), 00334 Case("Test put full wait forever", test_put_full_waitforever), 00335 Case("Test message ordering", test_msg_order), 00336 Case("Test message priority", test_msg_prio), 00337 Case("Test queue empty", test_queue_empty), 00338 Case("Test queue full", test_queue_full) 00339 }; 00340 00341 Specification specification(test_setup, cases); 00342 00343 int main() 00344 { 00345 return !Harness::run(specification); 00346 }
Generated on Sun Jul 17 2022 08:25:27 by 1.7.2