Rtos API example

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