Skip to content

Commit 9fb4fd0

Browse files
Test set for LowPowerTicker class
1 parent 003dd7c commit 9fb4fd0

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed

TESTS/mbed_drivers/lp_ticker/main.cpp

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

0 commit comments

Comments
 (0)