Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /* mbed Microcontroller Library
marcozecchini 0:9fca2b23d0ba 2 * Copyright (c) 2017 ARM Limited
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * Licensed under the Apache License, Version 2.0 (the "License");
marcozecchini 0:9fca2b23d0ba 5 * you may not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 6 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 7 *
marcozecchini 0:9fca2b23d0ba 8 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 9 *
marcozecchini 0:9fca2b23d0ba 10 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 11 * distributed under the License is distributed on an "AS IS" BASIS,
marcozecchini 0:9fca2b23d0ba 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 13 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 14 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 15 */
marcozecchini 0:9fca2b23d0ba 16 #include "mbed_events.h"
marcozecchini 0:9fca2b23d0ba 17 #include "mbed.h"
marcozecchini 0:9fca2b23d0ba 18 #include "rtos.h"
marcozecchini 0:9fca2b23d0ba 19 #include "greentea-client/test_env.h"
marcozecchini 0:9fca2b23d0ba 20 #include "unity.h"
marcozecchini 0:9fca2b23d0ba 21 #include "utest.h"
marcozecchini 0:9fca2b23d0ba 22 #include <cstdlib>
marcozecchini 0:9fca2b23d0ba 23 #include <cmath>
marcozecchini 0:9fca2b23d0ba 24
marcozecchini 0:9fca2b23d0ba 25 using namespace utest::v1;
marcozecchini 0:9fca2b23d0ba 26
marcozecchini 0:9fca2b23d0ba 27
marcozecchini 0:9fca2b23d0ba 28 // Test delay
marcozecchini 0:9fca2b23d0ba 29 #ifndef TEST_EVENTS_TIMING_TIME
marcozecchini 0:9fca2b23d0ba 30 #define TEST_EVENTS_TIMING_TIME 20000
marcozecchini 0:9fca2b23d0ba 31 #endif
marcozecchini 0:9fca2b23d0ba 32
marcozecchini 0:9fca2b23d0ba 33 #ifndef TEST_EVENTS_TIMING_MEAN
marcozecchini 0:9fca2b23d0ba 34 #define TEST_EVENTS_TIMING_MEAN 25
marcozecchini 0:9fca2b23d0ba 35 #endif
marcozecchini 0:9fca2b23d0ba 36
marcozecchini 0:9fca2b23d0ba 37 #ifndef M_PI
marcozecchini 0:9fca2b23d0ba 38 #define M_PI 3.14159265358979323846264338327950288
marcozecchini 0:9fca2b23d0ba 39 #endif
marcozecchini 0:9fca2b23d0ba 40
marcozecchini 0:9fca2b23d0ba 41 // Random number generation to skew timing values
marcozecchini 0:9fca2b23d0ba 42 float gauss(float mu, float sigma) {
marcozecchini 0:9fca2b23d0ba 43 float x = (float)rand() / ((float)RAND_MAX+1);
marcozecchini 0:9fca2b23d0ba 44 float y = (float)rand() / ((float)RAND_MAX+1);
marcozecchini 0:9fca2b23d0ba 45 float x2pi = x*2.0*M_PI;
marcozecchini 0:9fca2b23d0ba 46 float g2rad = sqrt(-2.0 * log(1.0-y));
marcozecchini 0:9fca2b23d0ba 47 float z = cos(x2pi) * g2rad;
marcozecchini 0:9fca2b23d0ba 48 return mu + z*sigma;
marcozecchini 0:9fca2b23d0ba 49 }
marcozecchini 0:9fca2b23d0ba 50
marcozecchini 0:9fca2b23d0ba 51 float chisq(float sigma) {
marcozecchini 0:9fca2b23d0ba 52 return pow(gauss(0, sqrt(sigma)), 2);
marcozecchini 0:9fca2b23d0ba 53 }
marcozecchini 0:9fca2b23d0ba 54
marcozecchini 0:9fca2b23d0ba 55
marcozecchini 0:9fca2b23d0ba 56 Timer timer;
marcozecchini 0:9fca2b23d0ba 57 DigitalOut led(LED1);
marcozecchini 0:9fca2b23d0ba 58
marcozecchini 0:9fca2b23d0ba 59 equeue_sema_t sema;
marcozecchini 0:9fca2b23d0ba 60
marcozecchini 0:9fca2b23d0ba 61 // Timer timing test
marcozecchini 0:9fca2b23d0ba 62 void timer_timing_test() {
marcozecchini 0:9fca2b23d0ba 63 timer.reset();
marcozecchini 0:9fca2b23d0ba 64 timer.start();
marcozecchini 0:9fca2b23d0ba 65 int prev = timer.read_us();
marcozecchini 0:9fca2b23d0ba 66
marcozecchini 0:9fca2b23d0ba 67 while (prev < TEST_EVENTS_TIMING_TIME*1000) {
marcozecchini 0:9fca2b23d0ba 68 int next = timer.read_us();
marcozecchini 0:9fca2b23d0ba 69 if (next < prev) {
marcozecchini 0:9fca2b23d0ba 70 printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
marcozecchini 0:9fca2b23d0ba 71 prev, next, prev, next);
marcozecchini 0:9fca2b23d0ba 72 }
marcozecchini 0:9fca2b23d0ba 73 TEST_ASSERT(next >= prev);
marcozecchini 0:9fca2b23d0ba 74 prev = next;
marcozecchini 0:9fca2b23d0ba 75 }
marcozecchini 0:9fca2b23d0ba 76 }
marcozecchini 0:9fca2b23d0ba 77
marcozecchini 0:9fca2b23d0ba 78 // equeue tick timing test
marcozecchini 0:9fca2b23d0ba 79 void tick_timing_test() {
marcozecchini 0:9fca2b23d0ba 80 unsigned start = equeue_tick();
marcozecchini 0:9fca2b23d0ba 81 int prev = 0;
marcozecchini 0:9fca2b23d0ba 82
marcozecchini 0:9fca2b23d0ba 83 while (prev < TEST_EVENTS_TIMING_TIME) {
marcozecchini 0:9fca2b23d0ba 84 int next = equeue_tick() - start;
marcozecchini 0:9fca2b23d0ba 85 if (next < prev) {
marcozecchini 0:9fca2b23d0ba 86 printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
marcozecchini 0:9fca2b23d0ba 87 prev, next, prev, next);
marcozecchini 0:9fca2b23d0ba 88 }
marcozecchini 0:9fca2b23d0ba 89 TEST_ASSERT(next >= prev);
marcozecchini 0:9fca2b23d0ba 90 prev = next;
marcozecchini 0:9fca2b23d0ba 91 }
marcozecchini 0:9fca2b23d0ba 92 }
marcozecchini 0:9fca2b23d0ba 93
marcozecchini 0:9fca2b23d0ba 94 // equeue semaphore timing test
marcozecchini 0:9fca2b23d0ba 95 void semaphore_timing_test() {
marcozecchini 0:9fca2b23d0ba 96 srand(0);
marcozecchini 0:9fca2b23d0ba 97 timer.reset();
marcozecchini 0:9fca2b23d0ba 98 timer.start();
marcozecchini 0:9fca2b23d0ba 99
marcozecchini 0:9fca2b23d0ba 100 int err = equeue_sema_create(&sema);
marcozecchini 0:9fca2b23d0ba 101 TEST_ASSERT_EQUAL(0, err);
marcozecchini 0:9fca2b23d0ba 102
marcozecchini 0:9fca2b23d0ba 103 while (timer.read_ms() < TEST_EVENTS_TIMING_TIME) {
marcozecchini 0:9fca2b23d0ba 104 int delay = chisq(TEST_EVENTS_TIMING_MEAN);
marcozecchini 0:9fca2b23d0ba 105
marcozecchini 0:9fca2b23d0ba 106 int start = timer.read_us();
marcozecchini 0:9fca2b23d0ba 107 equeue_sema_wait(&sema, delay);
marcozecchini 0:9fca2b23d0ba 108 int taken = timer.read_us() - start;
marcozecchini 0:9fca2b23d0ba 109
marcozecchini 0:9fca2b23d0ba 110 printf("delay %dms => error %dus\r\n", delay, abs(1000*delay - taken));
marcozecchini 0:9fca2b23d0ba 111 TEST_ASSERT_INT_WITHIN(5000, taken, delay * 1000);
marcozecchini 0:9fca2b23d0ba 112
marcozecchini 0:9fca2b23d0ba 113 led = !led;
marcozecchini 0:9fca2b23d0ba 114 }
marcozecchini 0:9fca2b23d0ba 115
marcozecchini 0:9fca2b23d0ba 116 equeue_sema_destroy(&sema);
marcozecchini 0:9fca2b23d0ba 117 }
marcozecchini 0:9fca2b23d0ba 118
marcozecchini 0:9fca2b23d0ba 119
marcozecchini 0:9fca2b23d0ba 120 // Test setup
marcozecchini 0:9fca2b23d0ba 121 utest::v1::status_t test_setup(const size_t number_of_cases) {
marcozecchini 0:9fca2b23d0ba 122 GREENTEA_SETUP((number_of_cases+1)*TEST_EVENTS_TIMING_TIME/1000, "default_auto");
marcozecchini 0:9fca2b23d0ba 123 return verbose_test_setup_handler(number_of_cases);
marcozecchini 0:9fca2b23d0ba 124 }
marcozecchini 0:9fca2b23d0ba 125
marcozecchini 0:9fca2b23d0ba 126 const Case cases[] = {
marcozecchini 0:9fca2b23d0ba 127 Case("Testing accuracy of timer", timer_timing_test),
marcozecchini 0:9fca2b23d0ba 128 Case("Testing accuracy of equeue tick", tick_timing_test),
marcozecchini 0:9fca2b23d0ba 129 Case("Testing accuracy of equeue semaphore", semaphore_timing_test),
marcozecchini 0:9fca2b23d0ba 130 };
marcozecchini 0:9fca2b23d0ba 131
marcozecchini 0:9fca2b23d0ba 132 Specification specification(test_setup, cases);
marcozecchini 0:9fca2b23d0ba 133
marcozecchini 0:9fca2b23d0ba 134 int main() {
marcozecchini 0:9fca2b23d0ba 135 return !Harness::run(specification);
marcozecchini 0:9fca2b23d0ba 136 }
marcozecchini 0:9fca2b23d0ba 137