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