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