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.
mbed-os/TESTS/mbed_drivers/lp_ticker/main.cpp@0:8fdf9a60065b, 2018-10-10 (annotated)
- Committer:
- kadonotakashi
- Date:
- Wed Oct 10 00:33:53 2018 +0000
- Revision:
- 0:8fdf9a60065b
how to make mbed librry
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kadonotakashi | 0:8fdf9a60065b | 1 | /* mbed Microcontroller Library |
kadonotakashi | 0:8fdf9a60065b | 2 | * Copyright (c) 2013-2017 ARM Limited |
kadonotakashi | 0:8fdf9a60065b | 3 | * |
kadonotakashi | 0:8fdf9a60065b | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
kadonotakashi | 0:8fdf9a60065b | 5 | * you may not use this file except in compliance with the License. |
kadonotakashi | 0:8fdf9a60065b | 6 | * You may obtain a copy of the License at |
kadonotakashi | 0:8fdf9a60065b | 7 | * |
kadonotakashi | 0:8fdf9a60065b | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
kadonotakashi | 0:8fdf9a60065b | 9 | * |
kadonotakashi | 0:8fdf9a60065b | 10 | * Unless required by applicable law or agreed to in writing, software |
kadonotakashi | 0:8fdf9a60065b | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
kadonotakashi | 0:8fdf9a60065b | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
kadonotakashi | 0:8fdf9a60065b | 13 | * See the License for the specific language governing permissions and |
kadonotakashi | 0:8fdf9a60065b | 14 | * limitations under the License. |
kadonotakashi | 0:8fdf9a60065b | 15 | */ |
kadonotakashi | 0:8fdf9a60065b | 16 | #include "mbed.h" |
kadonotakashi | 0:8fdf9a60065b | 17 | #include "greentea-client/test_env.h" |
kadonotakashi | 0:8fdf9a60065b | 18 | #include "utest/utest.h" |
kadonotakashi | 0:8fdf9a60065b | 19 | #include "unity/unity.h" |
kadonotakashi | 0:8fdf9a60065b | 20 | |
kadonotakashi | 0:8fdf9a60065b | 21 | |
kadonotakashi | 0:8fdf9a60065b | 22 | #if !DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 23 | #error [NOT_SUPPORTED] Low power ticker not supported for this target |
kadonotakashi | 0:8fdf9a60065b | 24 | #endif |
kadonotakashi | 0:8fdf9a60065b | 25 | |
kadonotakashi | 0:8fdf9a60065b | 26 | using utest::v1::Case; |
kadonotakashi | 0:8fdf9a60065b | 27 | |
kadonotakashi | 0:8fdf9a60065b | 28 | static const int test_timeout = 10; |
kadonotakashi | 0:8fdf9a60065b | 29 | |
kadonotakashi | 0:8fdf9a60065b | 30 | #define TICKER_COUNT 16 |
kadonotakashi | 0:8fdf9a60065b | 31 | #define MULTI_TICKER_TIME_MS 100 |
kadonotakashi | 0:8fdf9a60065b | 32 | |
kadonotakashi | 0:8fdf9a60065b | 33 | /* Due to poor accuracy of LowPowerTicker on many platforms |
kadonotakashi | 0:8fdf9a60065b | 34 | there is no sense to tune tolerance value as it was in Ticker tests. |
kadonotakashi | 0:8fdf9a60065b | 35 | |
kadonotakashi | 0:8fdf9a60065b | 36 | Tolerance value is set to 600us for measurement inaccuracy + 5% tolerance |
kadonotakashi | 0:8fdf9a60065b | 37 | for LowPowerTicker. */ |
kadonotakashi | 0:8fdf9a60065b | 38 | #define TOLERANCE_US(DELAY) (600 + DELAY / 20) |
kadonotakashi | 0:8fdf9a60065b | 39 | |
kadonotakashi | 0:8fdf9a60065b | 40 | |
kadonotakashi | 0:8fdf9a60065b | 41 | volatile uint32_t ticker_callback_flag; |
kadonotakashi | 0:8fdf9a60065b | 42 | volatile uint32_t multi_counter; |
kadonotakashi | 0:8fdf9a60065b | 43 | Timer gtimer; |
kadonotakashi | 0:8fdf9a60065b | 44 | |
kadonotakashi | 0:8fdf9a60065b | 45 | |
kadonotakashi | 0:8fdf9a60065b | 46 | |
kadonotakashi | 0:8fdf9a60065b | 47 | void sem_release(Semaphore *sem) |
kadonotakashi | 0:8fdf9a60065b | 48 | { |
kadonotakashi | 0:8fdf9a60065b | 49 | sem->release(); |
kadonotakashi | 0:8fdf9a60065b | 50 | } |
kadonotakashi | 0:8fdf9a60065b | 51 | |
kadonotakashi | 0:8fdf9a60065b | 52 | |
kadonotakashi | 0:8fdf9a60065b | 53 | void stop_gtimer_set_flag(void) |
kadonotakashi | 0:8fdf9a60065b | 54 | { |
kadonotakashi | 0:8fdf9a60065b | 55 | gtimer.stop(); |
kadonotakashi | 0:8fdf9a60065b | 56 | core_util_atomic_incr_u32((uint32_t *)&ticker_callback_flag, 1); |
kadonotakashi | 0:8fdf9a60065b | 57 | } |
kadonotakashi | 0:8fdf9a60065b | 58 | |
kadonotakashi | 0:8fdf9a60065b | 59 | void increment_multi_counter(void) |
kadonotakashi | 0:8fdf9a60065b | 60 | { |
kadonotakashi | 0:8fdf9a60065b | 61 | core_util_atomic_incr_u32((uint32_t *)&multi_counter, 1);; |
kadonotakashi | 0:8fdf9a60065b | 62 | } |
kadonotakashi | 0:8fdf9a60065b | 63 | |
kadonotakashi | 0:8fdf9a60065b | 64 | /** Test many tickers run one after the other |
kadonotakashi | 0:8fdf9a60065b | 65 | |
kadonotakashi | 0:8fdf9a60065b | 66 | Given many Tickers |
kadonotakashi | 0:8fdf9a60065b | 67 | When schedule them one after the other with the same time intervals |
kadonotakashi | 0:8fdf9a60065b | 68 | Then tickers properly execute callbacks |
kadonotakashi | 0:8fdf9a60065b | 69 | When schedule them one after the other with the different time intervals |
kadonotakashi | 0:8fdf9a60065b | 70 | Then tickers properly execute callbacks |
kadonotakashi | 0:8fdf9a60065b | 71 | */ |
kadonotakashi | 0:8fdf9a60065b | 72 | void test_multi_ticker(void) |
kadonotakashi | 0:8fdf9a60065b | 73 | { |
kadonotakashi | 0:8fdf9a60065b | 74 | LowPowerTicker ticker[TICKER_COUNT]; |
kadonotakashi | 0:8fdf9a60065b | 75 | const uint32_t extra_wait = 10; // extra 10ms wait time |
kadonotakashi | 0:8fdf9a60065b | 76 | |
kadonotakashi | 0:8fdf9a60065b | 77 | multi_counter = 0; |
kadonotakashi | 0:8fdf9a60065b | 78 | for (int i = 0; i < TICKER_COUNT; i++) { |
kadonotakashi | 0:8fdf9a60065b | 79 | ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000); |
kadonotakashi | 0:8fdf9a60065b | 80 | } |
kadonotakashi | 0:8fdf9a60065b | 81 | |
kadonotakashi | 0:8fdf9a60065b | 82 | Thread::wait(MULTI_TICKER_TIME_MS + extra_wait); |
kadonotakashi | 0:8fdf9a60065b | 83 | TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); |
kadonotakashi | 0:8fdf9a60065b | 84 | |
kadonotakashi | 0:8fdf9a60065b | 85 | for (int i = 0; i < TICKER_COUNT; i++) { |
kadonotakashi | 0:8fdf9a60065b | 86 | ticker[i].detach(); |
kadonotakashi | 0:8fdf9a60065b | 87 | } |
kadonotakashi | 0:8fdf9a60065b | 88 | // Because detach calls schedule_interrupt in some circumstances |
kadonotakashi | 0:8fdf9a60065b | 89 | // (e.g. when head event is removed), it's good to check if |
kadonotakashi | 0:8fdf9a60065b | 90 | // no more callbacks were triggered during detaching. |
kadonotakashi | 0:8fdf9a60065b | 91 | TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); |
kadonotakashi | 0:8fdf9a60065b | 92 | |
kadonotakashi | 0:8fdf9a60065b | 93 | multi_counter = 0; |
kadonotakashi | 0:8fdf9a60065b | 94 | for (int i = 0; i < TICKER_COUNT; i++) { |
kadonotakashi | 0:8fdf9a60065b | 95 | ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000); |
kadonotakashi | 0:8fdf9a60065b | 96 | } |
kadonotakashi | 0:8fdf9a60065b | 97 | |
kadonotakashi | 0:8fdf9a60065b | 98 | Thread::wait(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait); |
kadonotakashi | 0:8fdf9a60065b | 99 | TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); |
kadonotakashi | 0:8fdf9a60065b | 100 | |
kadonotakashi | 0:8fdf9a60065b | 101 | for (int i = 0; i < TICKER_COUNT; i++) { |
kadonotakashi | 0:8fdf9a60065b | 102 | ticker[i].detach(); |
kadonotakashi | 0:8fdf9a60065b | 103 | } |
kadonotakashi | 0:8fdf9a60065b | 104 | // Because detach calls schedule_interrupt in some circumstances |
kadonotakashi | 0:8fdf9a60065b | 105 | // (e.g. when head event is removed), it's good to check if |
kadonotakashi | 0:8fdf9a60065b | 106 | // no more callbacks were triggered during detaching. |
kadonotakashi | 0:8fdf9a60065b | 107 | TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); |
kadonotakashi | 0:8fdf9a60065b | 108 | } |
kadonotakashi | 0:8fdf9a60065b | 109 | |
kadonotakashi | 0:8fdf9a60065b | 110 | /** Test multi callback time |
kadonotakashi | 0:8fdf9a60065b | 111 | |
kadonotakashi | 0:8fdf9a60065b | 112 | Given a Ticker |
kadonotakashi | 0:8fdf9a60065b | 113 | When the callback is attached multiple times |
kadonotakashi | 0:8fdf9a60065b | 114 | Then ticker properly execute callback multiple times |
kadonotakashi | 0:8fdf9a60065b | 115 | */ |
kadonotakashi | 0:8fdf9a60065b | 116 | void test_multi_call_time(void) |
kadonotakashi | 0:8fdf9a60065b | 117 | { |
kadonotakashi | 0:8fdf9a60065b | 118 | LowPowerTicker ticker; |
kadonotakashi | 0:8fdf9a60065b | 119 | int time_diff; |
kadonotakashi | 0:8fdf9a60065b | 120 | const int attach_count = 10; |
kadonotakashi | 0:8fdf9a60065b | 121 | |
kadonotakashi | 0:8fdf9a60065b | 122 | for (int i = 0; i < attach_count; i++) { |
kadonotakashi | 0:8fdf9a60065b | 123 | ticker_callback_flag = 0; |
kadonotakashi | 0:8fdf9a60065b | 124 | gtimer.reset(); |
kadonotakashi | 0:8fdf9a60065b | 125 | |
kadonotakashi | 0:8fdf9a60065b | 126 | gtimer.start(); |
kadonotakashi | 0:8fdf9a60065b | 127 | ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000); |
kadonotakashi | 0:8fdf9a60065b | 128 | while (!ticker_callback_flag); |
kadonotakashi | 0:8fdf9a60065b | 129 | time_diff = gtimer.read_us(); |
kadonotakashi | 0:8fdf9a60065b | 130 | |
kadonotakashi | 0:8fdf9a60065b | 131 | TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US(MULTI_TICKER_TIME_MS * 1000), MULTI_TICKER_TIME_MS * 1000, time_diff); |
kadonotakashi | 0:8fdf9a60065b | 132 | } |
kadonotakashi | 0:8fdf9a60065b | 133 | } |
kadonotakashi | 0:8fdf9a60065b | 134 | |
kadonotakashi | 0:8fdf9a60065b | 135 | /** Test if detach cancel scheduled callback event |
kadonotakashi | 0:8fdf9a60065b | 136 | |
kadonotakashi | 0:8fdf9a60065b | 137 | Given a Ticker with callback attached |
kadonotakashi | 0:8fdf9a60065b | 138 | When the callback is detached |
kadonotakashi | 0:8fdf9a60065b | 139 | Then the callback is not being called |
kadonotakashi | 0:8fdf9a60065b | 140 | */ |
kadonotakashi | 0:8fdf9a60065b | 141 | void test_detach(void) |
kadonotakashi | 0:8fdf9a60065b | 142 | { |
kadonotakashi | 0:8fdf9a60065b | 143 | LowPowerTicker ticker; |
kadonotakashi | 0:8fdf9a60065b | 144 | int32_t ret; |
kadonotakashi | 0:8fdf9a60065b | 145 | const float ticker_time_s = 0.1f; |
kadonotakashi | 0:8fdf9a60065b | 146 | const uint32_t wait_time_ms = 500; |
kadonotakashi | 0:8fdf9a60065b | 147 | Semaphore sem(0, 1); |
kadonotakashi | 0:8fdf9a60065b | 148 | |
kadonotakashi | 0:8fdf9a60065b | 149 | ticker.attach(callback(sem_release, &sem), ticker_time_s); |
kadonotakashi | 0:8fdf9a60065b | 150 | |
kadonotakashi | 0:8fdf9a60065b | 151 | ret = sem.wait(); |
kadonotakashi | 0:8fdf9a60065b | 152 | TEST_ASSERT_TRUE(ret > 0); |
kadonotakashi | 0:8fdf9a60065b | 153 | |
kadonotakashi | 0:8fdf9a60065b | 154 | ret = sem.wait(); |
kadonotakashi | 0:8fdf9a60065b | 155 | ticker.detach(); /* cancel */ |
kadonotakashi | 0:8fdf9a60065b | 156 | TEST_ASSERT_TRUE(ret > 0); |
kadonotakashi | 0:8fdf9a60065b | 157 | |
kadonotakashi | 0:8fdf9a60065b | 158 | ret = sem.wait(wait_time_ms); |
kadonotakashi | 0:8fdf9a60065b | 159 | TEST_ASSERT_EQUAL(0, ret); |
kadonotakashi | 0:8fdf9a60065b | 160 | } |
kadonotakashi | 0:8fdf9a60065b | 161 | |
kadonotakashi | 0:8fdf9a60065b | 162 | /** Test single callback time via attach |
kadonotakashi | 0:8fdf9a60065b | 163 | |
kadonotakashi | 0:8fdf9a60065b | 164 | Given a Ticker |
kadonotakashi | 0:8fdf9a60065b | 165 | When callback attached with time interval specified |
kadonotakashi | 0:8fdf9a60065b | 166 | Then ticker properly executes callback within a specified time interval |
kadonotakashi | 0:8fdf9a60065b | 167 | */ |
kadonotakashi | 0:8fdf9a60065b | 168 | template<us_timestamp_t DELAY_US> |
kadonotakashi | 0:8fdf9a60065b | 169 | void test_attach_time(void) |
kadonotakashi | 0:8fdf9a60065b | 170 | { |
kadonotakashi | 0:8fdf9a60065b | 171 | LowPowerTicker ticker; |
kadonotakashi | 0:8fdf9a60065b | 172 | ticker_callback_flag = 0; |
kadonotakashi | 0:8fdf9a60065b | 173 | |
kadonotakashi | 0:8fdf9a60065b | 174 | gtimer.reset(); |
kadonotakashi | 0:8fdf9a60065b | 175 | gtimer.start(); |
kadonotakashi | 0:8fdf9a60065b | 176 | ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f); |
kadonotakashi | 0:8fdf9a60065b | 177 | while (!ticker_callback_flag); |
kadonotakashi | 0:8fdf9a60065b | 178 | ticker.detach(); |
kadonotakashi | 0:8fdf9a60065b | 179 | const int time_diff = gtimer.read_us(); |
kadonotakashi | 0:8fdf9a60065b | 180 | |
kadonotakashi | 0:8fdf9a60065b | 181 | TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US(DELAY_US), DELAY_US, time_diff); |
kadonotakashi | 0:8fdf9a60065b | 182 | } |
kadonotakashi | 0:8fdf9a60065b | 183 | |
kadonotakashi | 0:8fdf9a60065b | 184 | /** Test single callback time via attach_us |
kadonotakashi | 0:8fdf9a60065b | 185 | |
kadonotakashi | 0:8fdf9a60065b | 186 | Given a Ticker |
kadonotakashi | 0:8fdf9a60065b | 187 | When callback attached with time interval specified |
kadonotakashi | 0:8fdf9a60065b | 188 | Then ticker properly executes callback within a specified time interval |
kadonotakashi | 0:8fdf9a60065b | 189 | */ |
kadonotakashi | 0:8fdf9a60065b | 190 | template<us_timestamp_t DELAY_US> |
kadonotakashi | 0:8fdf9a60065b | 191 | void test_attach_us_time(void) |
kadonotakashi | 0:8fdf9a60065b | 192 | { |
kadonotakashi | 0:8fdf9a60065b | 193 | LowPowerTicker ticker; |
kadonotakashi | 0:8fdf9a60065b | 194 | ticker_callback_flag = 0; |
kadonotakashi | 0:8fdf9a60065b | 195 | |
kadonotakashi | 0:8fdf9a60065b | 196 | gtimer.reset(); |
kadonotakashi | 0:8fdf9a60065b | 197 | gtimer.start(); |
kadonotakashi | 0:8fdf9a60065b | 198 | ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US); |
kadonotakashi | 0:8fdf9a60065b | 199 | while (!ticker_callback_flag); |
kadonotakashi | 0:8fdf9a60065b | 200 | ticker.detach(); |
kadonotakashi | 0:8fdf9a60065b | 201 | const int time_diff = gtimer.read_us(); |
kadonotakashi | 0:8fdf9a60065b | 202 | |
kadonotakashi | 0:8fdf9a60065b | 203 | TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US(DELAY_US), DELAY_US, time_diff); |
kadonotakashi | 0:8fdf9a60065b | 204 | } |
kadonotakashi | 0:8fdf9a60065b | 205 | |
kadonotakashi | 0:8fdf9a60065b | 206 | // Test cases |
kadonotakashi | 0:8fdf9a60065b | 207 | Case cases[] = { |
kadonotakashi | 0:8fdf9a60065b | 208 | Case("Test attach for 0.001s and time measure", test_attach_time<1000>), |
kadonotakashi | 0:8fdf9a60065b | 209 | Case("Test attach_us for 1ms and time measure", test_attach_us_time<1000>), |
kadonotakashi | 0:8fdf9a60065b | 210 | Case("Test attach for 0.01s and time measure", test_attach_time<10000>), |
kadonotakashi | 0:8fdf9a60065b | 211 | Case("Test attach_us for 10ms and time measure", test_attach_us_time<10000>), |
kadonotakashi | 0:8fdf9a60065b | 212 | Case("Test attach for 0.1s and time measure", test_attach_time<100000>), |
kadonotakashi | 0:8fdf9a60065b | 213 | Case("Test attach_us for 100ms and time measure", test_attach_us_time<100000>), |
kadonotakashi | 0:8fdf9a60065b | 214 | Case("Test attach for 0.5s and time measure", test_attach_time<500000>), |
kadonotakashi | 0:8fdf9a60065b | 215 | Case("Test attach_us for 500ms and time measure", test_attach_us_time<500000>), |
kadonotakashi | 0:8fdf9a60065b | 216 | Case("Test detach", test_detach), |
kadonotakashi | 0:8fdf9a60065b | 217 | Case("Test multi call and time measure", test_multi_call_time), |
kadonotakashi | 0:8fdf9a60065b | 218 | Case("Test multi ticker", test_multi_ticker), |
kadonotakashi | 0:8fdf9a60065b | 219 | }; |
kadonotakashi | 0:8fdf9a60065b | 220 | |
kadonotakashi | 0:8fdf9a60065b | 221 | utest::v1::status_t greentea_test_setup(const size_t number_of_cases) |
kadonotakashi | 0:8fdf9a60065b | 222 | { |
kadonotakashi | 0:8fdf9a60065b | 223 | GREENTEA_SETUP(test_timeout, "timing_drift_auto"); |
kadonotakashi | 0:8fdf9a60065b | 224 | return utest::v1::greentea_test_setup_handler(number_of_cases); |
kadonotakashi | 0:8fdf9a60065b | 225 | } |
kadonotakashi | 0:8fdf9a60065b | 226 | |
kadonotakashi | 0:8fdf9a60065b | 227 | utest::v1::Specification specification(greentea_test_setup, cases, utest::v1::greentea_test_teardown_handler); |
kadonotakashi | 0:8fdf9a60065b | 228 | |
kadonotakashi | 0:8fdf9a60065b | 229 | int main() |
kadonotakashi | 0:8fdf9a60065b | 230 | { |
kadonotakashi | 0:8fdf9a60065b | 231 | utest::v1::Harness::run(specification); |
kadonotakashi | 0:8fdf9a60065b | 232 | } |