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