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 #include <cstdlib>
00023 #include <cmath>
00024 
00025 using namespace utest::v1;
00026 
00027 
00028 // Test delay
00029 #ifndef TEST_EVENTS_TIMING_TIME
00030 #define TEST_EVENTS_TIMING_TIME 20000
00031 #endif
00032 
00033 #ifndef TEST_EVENTS_TIMING_MEAN
00034 #define TEST_EVENTS_TIMING_MEAN 25
00035 #endif
00036 
00037 #ifndef M_PI
00038 #define M_PI 3.14159265358979323846264338327950288
00039 #endif
00040 
00041 // Random number generation to skew timing values
00042 float gauss(float mu, float sigma) {
00043     float x = (float)rand() / ((float)RAND_MAX+1);
00044     float y = (float)rand() / ((float)RAND_MAX+1);
00045     float x2pi = x*2.0*M_PI;
00046     float g2rad = sqrt(-2.0 * log(1.0-y));
00047     float z = cos(x2pi) * g2rad;
00048     return mu + z*sigma;
00049 }
00050 
00051 float chisq(float sigma) {
00052     return pow(gauss(0, sqrt(sigma)), 2);
00053 }
00054 
00055 
00056 Timer timer;
00057 DigitalOut led(LED1);
00058 
00059 equeue_sema_t sema;
00060 
00061 // Timer timing test
00062 void timer_timing_test() {
00063     timer.reset();
00064     timer.start();
00065     int prev = timer.read_us();
00066 
00067     while (prev < TEST_EVENTS_TIMING_TIME*1000) {
00068         int next = timer.read_us();
00069         if (next < prev) {
00070             printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
00071                 prev, next, prev, next);
00072         }
00073         TEST_ASSERT(next >= prev);
00074         prev = next;
00075     }
00076 }
00077 
00078 // equeue tick timing test
00079 void tick_timing_test() {
00080     unsigned start = equeue_tick();
00081     int prev = 0;
00082 
00083     while (prev < TEST_EVENTS_TIMING_TIME) {
00084         int next = equeue_tick() - start;
00085         if (next < prev) {
00086             printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
00087                 prev, next, prev, next);
00088         }
00089         TEST_ASSERT(next >= prev);
00090         prev = next;
00091     }
00092 }
00093 
00094 // equeue semaphore timing test
00095 void semaphore_timing_test() {
00096     srand(0);
00097     timer.reset();
00098     timer.start();
00099 
00100     int err = equeue_sema_create(&sema);
00101     TEST_ASSERT_EQUAL(0, err);
00102 
00103     while (timer.read_ms() < TEST_EVENTS_TIMING_TIME) {
00104         int delay = chisq(TEST_EVENTS_TIMING_MEAN);
00105 
00106         int start = timer.read_us();
00107         equeue_sema_wait(&sema, delay);
00108         int taken = timer.read_us() - start;
00109 
00110         printf("delay %dms => error %dus\r\n", delay, abs(1000*delay - taken));
00111         TEST_ASSERT_INT_WITHIN(5000, taken, delay * 1000);
00112 
00113         led = !led;
00114     }
00115 
00116     equeue_sema_destroy(&sema);
00117 }
00118 
00119 
00120 // Test setup
00121 utest::v1::status_t test_setup(const size_t number_of_cases) {
00122     GREENTEA_SETUP((number_of_cases+1)*TEST_EVENTS_TIMING_TIME/1000, "default_auto");
00123     return verbose_test_setup_handler(number_of_cases);
00124 }
00125 
00126 const Case cases[] = {
00127     Case("Testing accuracy of timer", timer_timing_test),
00128     Case("Testing accuracy of equeue tick", tick_timing_test),
00129     Case("Testing accuracy of equeue semaphore", semaphore_timing_test),
00130 };
00131 
00132 Specification specification(test_setup, cases);
00133 
00134 int main() {
00135     return !Harness::run(specification);
00136 }
00137