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_events.h" 00017 #include "mbed.h" 00018 #include "rtos.h" 00019 #include "greentea-client/test_env.h" 00020 #include "unity.h" 00021 #include "utest.h" 00022 00023 #if !DEVICE_USTICKER 00024 #error [NOT_SUPPORTED] test not supported 00025 #endif 00026 00027 using namespace utest::v1; 00028 00029 // Assume that tolerance is 5% of measured time. 00030 #define DELTA(ms) (ms / 20) 00031 00032 // TEST_EQUEUE_SIZE was reduced below 1024B to fit this test to devices with small RAM (RAM <= 16kB) 00033 // additionally TEST_EQUEUE_SIZE was expressed in EVENTS_EVENT_SIZE to increase readability 00034 // (for more details about EVENTS_EVENT_SIZE see EventQueue constructor) 00035 #define TEST_EQUEUE_SIZE (18*EVENTS_EVENT_SIZE) 00036 00037 // flag for called 00038 volatile bool touched = false; 00039 00040 // static functions 00041 void func5(int a0, int a1, int a2, int a3, int a4) { 00042 touched = true; 00043 TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3 | a4, 0x1f); 00044 } 00045 00046 void func4(int a0, int a1, int a2, int a3) { 00047 touched = true; 00048 TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3, 0xf); 00049 } 00050 00051 void func3(int a0, int a1, int a2) { 00052 touched = true; 00053 TEST_ASSERT_EQUAL(a0 | a1 | a2, 0x7); 00054 } 00055 00056 void func2(int a0, int a1) { 00057 touched = true; 00058 TEST_ASSERT_EQUAL(a0 | a1, 0x3); 00059 } 00060 00061 void func1(int a0) { 00062 touched = true; 00063 TEST_ASSERT_EQUAL(a0, 0x1); 00064 } 00065 00066 void func0() { 00067 touched = true; 00068 } 00069 00070 #define SIMPLE_POSTS_TEST(i, ...) \ 00071 void simple_posts_test##i() { \ 00072 EventQueue queue(TEST_EQUEUE_SIZE); \ 00073 \ 00074 touched = false; \ 00075 queue.call(func##i,##__VA_ARGS__); \ 00076 queue.dispatch(0); \ 00077 TEST_ASSERT(touched); \ 00078 \ 00079 touched = false; \ 00080 queue.call_in(1, func##i,##__VA_ARGS__); \ 00081 queue.dispatch(2); \ 00082 TEST_ASSERT(touched); \ 00083 \ 00084 touched = false; \ 00085 queue.call_every(1, func##i,##__VA_ARGS__); \ 00086 queue.dispatch(2); \ 00087 TEST_ASSERT(touched); \ 00088 } 00089 00090 SIMPLE_POSTS_TEST(5, 0x01, 0x02, 0x04, 0x08, 0x010) 00091 SIMPLE_POSTS_TEST(4, 0x01, 0x02, 0x04, 0x08) 00092 SIMPLE_POSTS_TEST(3, 0x01, 0x02, 0x04) 00093 SIMPLE_POSTS_TEST(2, 0x01, 0x02) 00094 SIMPLE_POSTS_TEST(1, 0x01) 00095 SIMPLE_POSTS_TEST(0) 00096 00097 00098 void time_func(Timer *t, int ms) { 00099 TEST_ASSERT_INT_WITHIN(DELTA(ms), ms, t->read_ms()); 00100 t->reset(); 00101 } 00102 00103 template <int N> 00104 void call_in_test() { 00105 Timer tickers[N]; 00106 00107 EventQueue queue(TEST_EQUEUE_SIZE); 00108 00109 for (int i = 0; i < N; i++) { 00110 tickers[i].start(); 00111 queue.call_in((i+1)*100, time_func, &tickers[i], (i+1)*100); 00112 } 00113 00114 queue.dispatch(N*100); 00115 } 00116 00117 template <int N> 00118 void call_every_test() { 00119 Timer tickers[N]; 00120 00121 EventQueue queue(TEST_EQUEUE_SIZE); 00122 00123 for (int i = 0; i < N; i++) { 00124 tickers[i].start(); 00125 queue.call_every((i+1)*100, time_func, &tickers[i], (i+1)*100); 00126 } 00127 00128 queue.dispatch(N*100); 00129 } 00130 00131 void allocate_failure_test() { 00132 EventQueue queue(TEST_EQUEUE_SIZE); 00133 int id; 00134 00135 for (int i = 0; i < 100; i++) { 00136 id = queue.call((void (*)())0); 00137 } 00138 00139 TEST_ASSERT(!id); 00140 } 00141 00142 void no() { 00143 TEST_ASSERT(false); 00144 } 00145 00146 template <int N> 00147 void cancel_test1() { 00148 EventQueue queue(TEST_EQUEUE_SIZE); 00149 00150 int ids[N]; 00151 00152 for (int i = 0; i < N; i++) { 00153 ids[i] = queue.call_in(1000, no); 00154 } 00155 00156 for (int i = N-1; i >= 0; i--) { 00157 queue.cancel(ids[i]); 00158 } 00159 00160 queue.dispatch(0); 00161 } 00162 00163 00164 // Testing the dynamic arguments to the event class 00165 unsigned counter = 0; 00166 00167 void count5(unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a5) { 00168 counter += a0 + a1 + a2 + a3 + a5; 00169 } 00170 00171 void count4(unsigned a0, unsigned a1, unsigned a2, unsigned a3) { 00172 counter += a0 + a1 + a2 + a3; 00173 } 00174 00175 void count3(unsigned a0, unsigned a1, unsigned a2) { 00176 counter += a0 + a1 + a2; 00177 } 00178 00179 void count2(unsigned a0, unsigned a1) { 00180 counter += a0 + a1; 00181 } 00182 00183 void count1(unsigned a0) { 00184 counter += a0; 00185 } 00186 00187 void count0() { 00188 counter += 0; 00189 } 00190 00191 void event_class_test() { 00192 counter = 0; 00193 EventQueue queue(TEST_EQUEUE_SIZE); 00194 00195 Event<void(int, int, int, int, int)> e5(&queue, count5); 00196 Event<void(int, int, int, int)> e4(&queue, count5, 1); 00197 Event<void(int, int, int)> e3(&queue, count5, 1, 1); 00198 Event<void(int, int)> e2(&queue, count5, 1, 1, 1); 00199 Event<void(int)> e1(&queue, count5, 1, 1, 1, 1); 00200 Event<void()> e0(&queue, count5, 1, 1, 1, 1, 1); 00201 00202 e5.post(1, 1, 1, 1, 1); 00203 e4.post(1, 1, 1, 1); 00204 e3.post(1, 1, 1); 00205 e2.post(1, 1); 00206 e1.post(1); 00207 e0.post(); 00208 00209 queue.dispatch(0); 00210 00211 TEST_ASSERT_EQUAL(counter, 30); 00212 } 00213 00214 void event_class_helper_test() { 00215 counter = 0; 00216 EventQueue queue(TEST_EQUEUE_SIZE); 00217 00218 Event<void()> e5 = queue.event(count5, 1, 1, 1, 1, 1); 00219 Event<void()> e4 = queue.event(count4, 1, 1, 1, 1); 00220 Event<void()> e3 = queue.event(count3, 1, 1, 1); 00221 Event<void()> e2 = queue.event(count2, 1, 1); 00222 Event<void()> e1 = queue.event(count1, 1); 00223 Event<void()> e0 = queue.event(count0); 00224 00225 e5.post(); 00226 e4.post(); 00227 e3.post(); 00228 e2.post(); 00229 e1.post(); 00230 e0.post(); 00231 00232 queue.dispatch(0); 00233 00234 TEST_ASSERT_EQUAL(counter, 15); 00235 } 00236 00237 void event_inference_test() { 00238 counter = 0; 00239 EventQueue queue(TEST_EQUEUE_SIZE); 00240 00241 queue.event(count5, 1, 1, 1, 1, 1).post(); 00242 queue.event(count5, 1, 1, 1, 1).post(1); 00243 queue.event(count5, 1, 1, 1).post(1, 1); 00244 queue.event(count5, 1, 1).post(1, 1, 1); 00245 queue.event(count5, 1).post(1, 1, 1, 1); 00246 queue.event(count5).post(1, 1, 1, 1, 1); 00247 00248 queue.event(callback(count5), 1, 1, 1, 1, 1).post(); 00249 queue.event(callback(count5), 1, 1, 1, 1).post(1); 00250 queue.event(callback(count5), 1, 1, 1).post(1, 1); 00251 queue.event(callback(count5), 1, 1).post(1, 1, 1); 00252 queue.event(callback(count5), 1).post(1, 1, 1, 1); 00253 queue.event(callback(count5)).post(1, 1, 1, 1, 1); 00254 00255 queue.dispatch(0); 00256 00257 TEST_ASSERT_EQUAL(counter, 60); 00258 } 00259 00260 int timeleft_events[2]; 00261 00262 void check_time_left(EventQueue* queue, int index, int expected) { 00263 const int event_id = timeleft_events[index]; 00264 TEST_ASSERT_INT_WITHIN(2, expected, queue->time_left(event_id)); 00265 touched = true; 00266 } 00267 00268 void time_left(EventQueue* queue, int index) { 00269 const int event_id = timeleft_events[index]; 00270 TEST_ASSERT_EQUAL(0, queue->time_left(event_id)); 00271 } 00272 00273 void time_left_test() { 00274 EventQueue queue(TEST_EQUEUE_SIZE); 00275 00276 // Enque check events 00277 TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100-50)); 00278 TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200-200)); 00279 00280 // Enque events to be checked 00281 timeleft_events[0] = queue.call_in(100, time_left, &queue, 0); 00282 timeleft_events[1] = queue.call_in(200, time_left, &queue, 1); 00283 TEST_ASSERT(timeleft_events[0]); 00284 TEST_ASSERT(timeleft_events[1]); 00285 00286 queue.dispatch(300); 00287 00288 // Ensure check was called 00289 TEST_ASSERT(touched); 00290 touched = false; 00291 00292 int id = queue.call(func0); 00293 TEST_ASSERT(id); 00294 TEST_ASSERT_EQUAL(0, queue.time_left(id)); 00295 queue.dispatch(10); 00296 00297 // Test invalid event id 00298 TEST_ASSERT_EQUAL(-1, queue.time_left(0)); 00299 } 00300 00301 // Test setup 00302 utest::v1::status_t test_setup(const size_t number_of_cases) { 00303 GREENTEA_SETUP(20, "default_auto"); 00304 return verbose_test_setup_handler(number_of_cases); 00305 } 00306 00307 const Case cases[] = { 00308 Case("Testing calls with 5 args", simple_posts_test5), 00309 Case("Testing calls with 4 args", simple_posts_test4), 00310 Case("Testing calls with 3 args", simple_posts_test3), 00311 Case("Testing calls with 2 args", simple_posts_test2), 00312 Case("Testing calls with 1 args", simple_posts_test1), 00313 Case("Testing calls with 0 args", simple_posts_test0), 00314 00315 Case("Testing call_in", call_in_test<20>), 00316 Case("Testing call_every", call_every_test<20>), 00317 00318 Case("Testing allocate failure", allocate_failure_test), 00319 00320 Case("Testing event cancel 1", cancel_test1<20>), 00321 Case("Testing the event class", event_class_test), 00322 Case("Testing the event class helpers", event_class_helper_test), 00323 Case("Testing the event inference", event_inference_test), 00324 00325 Case("Testing time_left", time_left_test), 00326 }; 00327 00328 Specification specification(test_setup, cases); 00329 00330 int main() { 00331 return !Harness::run(specification); 00332 } 00333
Generated on Tue Jul 12 2022 12:45:14 by
1.7.2