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_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 {
00043     touched = true;
00044     TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3 | a4, 0x1f);
00045 }
00046 
00047 void func4(int a0, int a1, int a2, int a3)
00048 {
00049     touched = true;
00050     TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3, 0xf);
00051 }
00052 
00053 void func3(int a0, int a1, int a2)
00054 {
00055     touched = true;
00056     TEST_ASSERT_EQUAL(a0 | a1 | a2, 0x7);
00057 }
00058 
00059 void func2(int a0, int a1)
00060 {
00061     touched = true;
00062     TEST_ASSERT_EQUAL(a0 | a1, 0x3);
00063 }
00064 
00065 void func1(int a0)
00066 {
00067     touched = true;
00068     TEST_ASSERT_EQUAL(a0, 0x1);
00069 }
00070 
00071 void func0()
00072 {
00073     touched = true;
00074 }
00075 
00076 #define SIMPLE_POSTS_TEST(i, ...)                           \
00077 void simple_posts_test##i() {                               \
00078     EventQueue queue(TEST_EQUEUE_SIZE);                     \
00079                                                             \
00080     touched = false;                                        \
00081     queue.call(func##i,##__VA_ARGS__);                      \
00082     queue.dispatch(0);                                      \
00083     TEST_ASSERT(touched);                                   \
00084                                                             \
00085     touched = false;                                        \
00086     queue.call_in(1, func##i,##__VA_ARGS__);                \
00087     queue.dispatch(2);                                      \
00088     TEST_ASSERT(touched);                                   \
00089                                                             \
00090     touched = false;                                        \
00091     queue.call_every(1, func##i,##__VA_ARGS__);             \
00092     queue.dispatch(2);                                      \
00093     TEST_ASSERT(touched);                                   \
00094 }
00095 
00096 SIMPLE_POSTS_TEST(5, 0x01, 0x02, 0x04, 0x08, 0x010)
00097 SIMPLE_POSTS_TEST(4, 0x01, 0x02, 0x04, 0x08)
00098 SIMPLE_POSTS_TEST(3, 0x01, 0x02, 0x04)
00099 SIMPLE_POSTS_TEST(2, 0x01, 0x02)
00100 SIMPLE_POSTS_TEST(1, 0x01)
00101 SIMPLE_POSTS_TEST(0)
00102 
00103 
00104 void time_func(Timer *t, int ms)
00105 {
00106     TEST_ASSERT_INT_WITHIN(DELTA(ms), ms, t->read_ms());
00107     t->reset();
00108 }
00109 
00110 template <int N>
00111 void call_in_test()
00112 {
00113     Timer tickers[N];
00114 
00115     EventQueue queue(TEST_EQUEUE_SIZE);
00116 
00117     for (int i = 0; i < N; i++) {
00118         tickers[i].start();
00119         queue.call_in((i + 1) * 100, time_func, &tickers[i], (i + 1) * 100);
00120     }
00121 
00122     queue.dispatch(N * 100);
00123 }
00124 
00125 template <int N>
00126 void call_every_test()
00127 {
00128     Timer tickers[N];
00129 
00130     EventQueue queue(TEST_EQUEUE_SIZE);
00131 
00132     for (int i = 0; i < N; i++) {
00133         tickers[i].start();
00134         queue.call_every((i + 1) * 100, time_func, &tickers[i], (i + 1) * 100);
00135     }
00136 
00137     queue.dispatch(N * 100);
00138 }
00139 
00140 void allocate_failure_test()
00141 {
00142     EventQueue queue(TEST_EQUEUE_SIZE);
00143     int id;
00144 
00145     for (int i = 0; i < 100; i++) {
00146         id = queue.call((void (*)())0);
00147     }
00148 
00149     TEST_ASSERT(!id);
00150 }
00151 
00152 void no()
00153 {
00154     TEST_ASSERT(false);
00155 }
00156 
00157 template <int N>
00158 void cancel_test1()
00159 {
00160     EventQueue queue(TEST_EQUEUE_SIZE);
00161 
00162     int ids[N];
00163 
00164     for (int i = 0; i < N; i++) {
00165         ids[i] = queue.call_in(1000, no);
00166     }
00167 
00168     for (int i = N - 1; i >= 0; i--) {
00169         queue.cancel(ids[i]);
00170     }
00171 
00172     queue.dispatch(0);
00173 }
00174 
00175 
00176 // Testing the dynamic arguments to the event class
00177 unsigned counter = 0;
00178 
00179 void count5(unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a5)
00180 {
00181     counter += a0 + a1 + a2 + a3 + a5;
00182 }
00183 
00184 void count4(unsigned a0, unsigned a1, unsigned a2, unsigned a3)
00185 {
00186     counter += a0 + a1 + a2 + a3;
00187 }
00188 
00189 void count3(unsigned a0, unsigned a1, unsigned a2)
00190 {
00191     counter += a0 + a1 + a2;
00192 }
00193 
00194 void count2(unsigned a0, unsigned a1)
00195 {
00196     counter += a0 + a1;
00197 }
00198 
00199 void count1(unsigned a0)
00200 {
00201     counter += a0;
00202 }
00203 
00204 void count0()
00205 {
00206     counter += 0;
00207 }
00208 
00209 void event_class_test()
00210 {
00211     counter = 0;
00212     EventQueue queue(TEST_EQUEUE_SIZE);
00213 
00214     Event<void(int, int, int, int, int)> e5(&queue, count5);
00215     Event<void(int, int, int, int)> e4(&queue, count5, 1);
00216     Event<void(int, int, int)> e3(&queue, count5, 1, 1);
00217     Event<void(int, int)> e2(&queue, count5, 1, 1, 1);
00218     Event<void(int)> e1(&queue, count5, 1, 1, 1, 1);
00219     Event<void()> e0(&queue, count5, 1, 1, 1, 1, 1);
00220 
00221     e5.post(1, 1, 1, 1, 1);
00222     e4.post(1, 1, 1, 1);
00223     e3.post(1, 1, 1);
00224     e2.post(1, 1);
00225     e1.post(1);
00226     e0.post();
00227 
00228     queue.dispatch(0);
00229 
00230     TEST_ASSERT_EQUAL(counter, 30);
00231 }
00232 
00233 void event_class_helper_test()
00234 {
00235     counter = 0;
00236     EventQueue queue(TEST_EQUEUE_SIZE);
00237 
00238     Event<void()> e5 = queue.event(count5, 1, 1, 1, 1, 1);
00239     Event<void()> e4 = queue.event(count4, 1, 1, 1, 1);
00240     Event<void()> e3 = queue.event(count3, 1, 1, 1);
00241     Event<void()> e2 = queue.event(count2, 1, 1);
00242     Event<void()> e1 = queue.event(count1, 1);
00243     Event<void()> e0 = queue.event(count0);
00244 
00245     e5.post();
00246     e4.post();
00247     e3.post();
00248     e2.post();
00249     e1.post();
00250     e0.post();
00251 
00252     queue.dispatch(0);
00253 
00254     TEST_ASSERT_EQUAL(counter, 15);
00255 }
00256 
00257 void event_inference_test()
00258 {
00259     counter = 0;
00260     EventQueue queue(TEST_EQUEUE_SIZE);
00261 
00262     queue.event(count5, 1, 1, 1, 1, 1).post();
00263     queue.event(count5, 1, 1, 1, 1).post(1);
00264     queue.event(count5, 1, 1, 1).post(1, 1);
00265     queue.event(count5, 1, 1).post(1, 1, 1);
00266     queue.event(count5, 1).post(1, 1, 1, 1);
00267     queue.event(count5).post(1, 1, 1, 1, 1);
00268 
00269     queue.event(callback(count5), 1, 1, 1, 1, 1).post();
00270     queue.event(callback(count5), 1, 1, 1, 1).post(1);
00271     queue.event(callback(count5), 1, 1, 1).post(1, 1);
00272     queue.event(callback(count5), 1, 1).post(1, 1, 1);
00273     queue.event(callback(count5), 1).post(1, 1, 1, 1);
00274     queue.event(callback(count5)).post(1, 1, 1, 1, 1);
00275 
00276     queue.dispatch(0);
00277 
00278     TEST_ASSERT_EQUAL(counter, 60);
00279 }
00280 
00281 int timeleft_events[2];
00282 
00283 void check_time_left(EventQueue *queue, int index, int expected)
00284 {
00285     const int event_id = timeleft_events[index];
00286     TEST_ASSERT_INT_WITHIN(2, expected, queue->time_left(event_id));
00287     touched = true;
00288 }
00289 
00290 void time_left(EventQueue *queue, int index)
00291 {
00292     const int event_id = timeleft_events[index];
00293     TEST_ASSERT_EQUAL(0, queue->time_left(event_id));
00294 }
00295 
00296 void time_left_test()
00297 {
00298     EventQueue queue(TEST_EQUEUE_SIZE);
00299 
00300     // Enque check events
00301     TEST_ASSERT(queue.call_in(50, check_time_left, &queue, 0, 100 - 50));
00302     TEST_ASSERT(queue.call_in(200, check_time_left, &queue, 1, 200 - 200));
00303 
00304     // Enque events to be checked
00305     timeleft_events[0] = queue.call_in(100, time_left, &queue, 0);
00306     timeleft_events[1] = queue.call_in(200, time_left, &queue, 1);
00307     TEST_ASSERT(timeleft_events[0]);
00308     TEST_ASSERT(timeleft_events[1]);
00309 
00310     queue.dispatch(300);
00311 
00312     // Ensure check was called
00313     TEST_ASSERT(touched);
00314     touched = false;
00315 
00316     int id = queue.call(func0);
00317     TEST_ASSERT(id);
00318     TEST_ASSERT_EQUAL(0, queue.time_left(id));
00319     queue.dispatch(10);
00320 
00321     // Test invalid event id
00322     TEST_ASSERT_EQUAL(-1, queue.time_left(0));
00323 }
00324 
00325 // Test setup
00326 utest::v1::status_t test_setup(const size_t number_of_cases)
00327 {
00328     GREENTEA_SETUP(20, "default_auto");
00329     return verbose_test_setup_handler(number_of_cases);
00330 }
00331 
00332 const Case cases[] = {
00333     Case("Testing calls with 5 args", simple_posts_test5),
00334     Case("Testing calls with 4 args", simple_posts_test4),
00335     Case("Testing calls with 3 args", simple_posts_test3),
00336     Case("Testing calls with 2 args", simple_posts_test2),
00337     Case("Testing calls with 1 args", simple_posts_test1),
00338     Case("Testing calls with 0 args", simple_posts_test0),
00339 
00340     Case("Testing call_in",    call_in_test<20>),
00341     Case("Testing call_every", call_every_test<20>),
00342 
00343     Case("Testing allocate failure", allocate_failure_test),
00344 
00345     Case("Testing event cancel 1", cancel_test1<20>),
00346     Case("Testing the event class", event_class_test),
00347     Case("Testing the event class helpers", event_class_helper_test),
00348     Case("Testing the event inference", event_inference_test),
00349 
00350     Case("Testing time_left", time_left_test),
00351 };
00352 
00353 Specification specification(test_setup, cases);
00354 
00355 int main()
00356 {
00357     return !Harness::run(specification);
00358 }
00359