1
- /*
2
- * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
3
- * SPDX-License-Identifier: Apache-2.0
1
+ /* mbed Microcontroller Library
2
+ * Copyright (c) 2017 ARM Limited
4
3
*
5
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
6
- * not use this file except in compliance with the License.
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
7
6
* You may obtain a copy of the License at
8
7
*
9
- * http://www.apache.org/licenses/LICENSE-2.0
8
+ * http://www.apache.org/licenses/LICENSE-2.0
10
9
*
11
10
* Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
13
* See the License for the specific language governing permissions and
15
14
* limitations under the License.
16
15
*/
16
+ #include " mbed.h"
17
+ #include " greentea-client/test_env.h"
18
+ #include " unity.h"
19
+ #include " utest.h"
20
+ #include " rtos.h"
17
21
22
+ using namespace utest ::v1;
18
23
19
- /*
20
- * Tests is to measure the accuracy of Timeout over a period of time
24
+ #define NUM_TIMEOUTS 64
25
+ const float TEST_DELAY_S = 0.01 ;
26
+ const uint32_t TEST_DELAY_MS = 1000 .0F * TEST_DELAY_S;
27
+ const us_timestamp_t TEST_DELAY_US = 1000000 .0F * TEST_DELAY_S;
28
+
29
+ void sem_callback (Semaphore *sem)
30
+ {
31
+ sem->release ();
32
+ }
33
+
34
+ void cnt_callback (volatile uint32_t *cnt)
35
+ {
36
+ (*cnt)++;
37
+ }
38
+
39
+ class TimeoutAttachUSTester : public Timeout {
40
+ public:
41
+ void attach_callback (Callback<void ()> func, us_timestamp_t delay_us)
42
+ {
43
+ attach_us (func, delay_us);
44
+ }
45
+ };
46
+
47
+ class TimeoutAttachTester : public Timeout {
48
+ public:
49
+ void attach_callback (Callback<void ()> func, us_timestamp_t delay_us)
50
+ {
51
+ attach (func, (float ) delay_us / 1000000 .0f );
52
+ }
53
+ };
54
+
55
+ /* * Template for tests: callback called once
21
56
*
57
+ * Test callback called once
58
+ * Given a Timeout object with a callback attached with @a attach()
59
+ * When given time elapses
60
+ * Then the callback is called exactly one time
22
61
*
23
- * 1) DUT would start to update callback_trigger_count every milli sec
24
- * 2) Host would query what is current count base_time, Device responds by the callback_trigger_count
25
- * 3) Host after waiting for measurement stretch. It will query for device time again final_time.
26
- * 4) Host computes the drift considering base_time, final_time, transport delay and measurement stretch
27
- * 5) Finally host send the results back to device pass/fail based on tolerance.
28
- * 6) More details on tests can be found in timing_drift_auto.py
62
+ * Test callback called once
63
+ * Given a Timeout object with a callback attached with @a attach_us()
64
+ * When given time elapses
65
+ * Then the callback is called exactly one time
66
+ */
67
+ template <typename T>
68
+ void test_callback_fires_once (void )
69
+ {
70
+ Semaphore sem (0 , 1 );
71
+ T timeout;
72
+
73
+ timeout.attach_callback (mbed::callback (sem_callback, &sem), TEST_DELAY_US);
74
+
75
+ int32_t sem_slots = sem.wait (0 );
76
+ TEST_ASSERT_EQUAL (0 , sem_slots);
77
+
78
+ sem_slots = sem.wait (TEST_DELAY_MS + 1 );
79
+ TEST_ASSERT_EQUAL (1 , sem_slots);
80
+
81
+ sem_slots = sem.wait (TEST_DELAY_MS + 1 );
82
+ TEST_ASSERT_EQUAL (0 , sem_slots);
83
+
84
+ timeout.detach ();
85
+ }
86
+
87
+ /* * Template for tests: callback not called when cancelled
29
88
*
89
+ * Test callback not called when cancelled
90
+ * Given a Timeout object with a callback attached with @a attach()
91
+ * When the callback is detached before being called
92
+ * Then the callback is never called
93
+ *
94
+ * Test callback not called when cancelled
95
+ * Given a Timeout object with a callback attached with @a attach_us()
96
+ * When the callback is detached before being called
97
+ * Then the callback is never called
30
98
*/
99
+ template <typename T>
100
+ void test_cancel (void )
101
+ {
102
+ Semaphore sem (0 , 1 );
103
+ T timeout;
31
104
32
- #include " mbed.h"
33
- #include " greentea-client/test_env.h"
34
- #include " utest/utest.h"
35
- #include " unity/unity.h"
105
+ timeout.attach_callback (mbed::callback (sem_callback, &sem), 2 .0f * TEST_DELAY_US);
36
106
37
- using namespace utest ::v1;
107
+ int32_t sem_slots = sem.wait (TEST_DELAY_MS);
108
+ TEST_ASSERT_EQUAL (0 , sem_slots);
109
+ timeout.detach ();
38
110
39
- #define PERIOD_US 10000
111
+ sem_slots = sem.wait (TEST_DELAY_MS + 1 );
112
+ TEST_ASSERT_EQUAL (0 , sem_slots);
113
+ }
40
114
41
- volatile int ticker_count = 0 ;
115
+ /* * Template for tests: callback override
116
+ *
117
+ * Test callback override
118
+ * Given a Timeout object with a callback attached with @a attach()
119
+ * When another callback is attached before first one is called
120
+ * and second callback's delay elapses
121
+ * Then the second callback is called
122
+ * and the first callback is never called
123
+ *
124
+ * Test callback override
125
+ * Given a Timeout object with a callback attached with @a attach_us()
126
+ * When another callback is attached before first one is called
127
+ * and second callback's delay elapses
128
+ * Then the second callback is called
129
+ * and the first callback is never called
130
+ */
131
+ template <typename T>
132
+ void test_override (void )
133
+ {
134
+ Semaphore sem1 (0 , 1 );
135
+ Semaphore sem2 (0 , 1 );
136
+ T timeout;
137
+
138
+ timeout.attach_callback (mbed::callback (sem_callback, &sem1), 2 .0f * TEST_DELAY_US);
139
+
140
+ int32_t sem_slots = sem1.wait (TEST_DELAY_MS);
141
+ TEST_ASSERT_EQUAL (0 , sem_slots);
142
+ timeout.attach_callback (mbed::callback (sem_callback, &sem2), 2 .0f * TEST_DELAY_US);
143
+
144
+ sem_slots = sem2.wait (2 * TEST_DELAY_MS + 1 );
145
+ TEST_ASSERT_EQUAL (1 , sem_slots);
146
+ sem_slots = sem1.wait (0 );
147
+ TEST_ASSERT_EQUAL (0 , sem_slots);
148
+
149
+ timeout.detach ();
150
+ }
151
+
152
+ /* * Template for tests: multiple Timeouts
153
+ *
154
+ * Test multiple Timeouts
155
+ * Given multiple separate Timeout objects
156
+ * When a callback is attached to all of these Timeout objects with @a attach()
157
+ * and delay for every Timeout elapses
158
+ * Then all callbacks are called
159
+ *
160
+ * Test multiple Timeouts
161
+ * Given multiple separate Timeout objects
162
+ * When a callback is attached to all of these Timeout objects with @a attach_us()
163
+ * and delay for every Timeout elapses
164
+ * Then all callbacks are called
165
+ */
166
+ template <typename T>
167
+ void test_multiple (void )
168
+ {
169
+ volatile uint32_t callback_count = 0 ;
170
+ T timeouts[NUM_TIMEOUTS];
171
+ for (size_t i = 0 ; i < NUM_TIMEOUTS; i++) {
172
+ timeouts[i].attach_callback (mbed::callback (cnt_callback, &callback_count), TEST_DELAY_US);
173
+ }
174
+ Thread::wait (TEST_DELAY_MS + 1 );
175
+ TEST_ASSERT_EQUAL (NUM_TIMEOUTS, callback_count);
176
+ }
177
+
178
+ /* * Template for tests: zero delay
179
+ *
180
+ * Test zero delay
181
+ * Given a Timeout object
182
+ * When a callback is attached with 0.0 s delay, with @a attach()
183
+ * Then the callback is called instantly
184
+ *
185
+ * Test zero delay
186
+ * Given a Timeout object
187
+ * When a callback is attached with 0.0 s delay, with @a attach_us()
188
+ * Then the callback is called instantly
189
+ */
190
+ template <typename T>
191
+ void test_no_wait (void )
192
+ {
193
+ Semaphore sem (0 , 1 );
194
+ T timeout;
195
+ timeout.attach_callback (mbed::callback (sem_callback, &sem), 0ULL );
196
+
197
+ int32_t sem_slots = sem.wait (0 );
198
+ TEST_ASSERT_EQUAL (1 , sem_slots);
199
+ timeout.detach ();
200
+ }
201
+
202
+ #define PERIOD_US 10000
42
203
volatile uint32_t callback_trigger_count = 0 ;
43
204
static const int test_timeout = 240 ;
44
205
Timeout timeout;
45
206
46
- void set_incremeant_count () {
47
- timeout.attach_us (set_incremeant_count, PERIOD_US);
207
+ void set_increment_count ()
208
+ {
209
+ timeout.attach_us (set_increment_count, PERIOD_US);
48
210
++callback_trigger_count;
49
211
}
50
212
51
- void test_case_timeout () {
213
+ /*
214
+ * Tests is to measure the accuracy of Timeout over a period of time
215
+ *
216
+ *
217
+ * 1) DUT would start to update callback_trigger_count every milli sec
218
+ * 2) Host would query what is current count base_time, Device responds by the callback_trigger_count
219
+ * 3) Host after waiting for measurement stretch. It will query for device time again final_time.
220
+ * 4) Host computes the drift considering base_time, final_time, transport delay and measurement stretch
221
+ * 5) Finally host send the results back to device pass/fail based on tolerance.
222
+ * 6) More details on tests can be found in timing_drift_auto.py
223
+ *
224
+ */
225
+ void test_case_timeout ()
226
+ {
52
227
53
228
char _key[11 ] = { };
54
229
char _value[128 ] = { };
55
230
int expected_key = 1 ;
56
- uint8_t results_size = 0 ;
57
231
58
232
greentea_send_kv (" timing_drift_check_start" , 0 );
59
- timeout.attach_us (set_incremeant_count , PERIOD_US);
233
+ timeout.attach_us (set_increment_count , PERIOD_US);
60
234
61
235
// wait for 1st signal from host
62
236
do {
@@ -73,19 +247,37 @@ void test_case_timeout() {
73
247
// get the results from host
74
248
greentea_parse_kv (_key, _value, sizeof (_key), sizeof (_value));
75
249
76
- TEST_ASSERT_EQUAL_STRING_MESSAGE (" pass" , _key," Host side script reported a fail..." );
250
+ TEST_ASSERT_EQUAL_STRING_MESSAGE (" pass" , _key, " Host side script reported a fail..." );
77
251
}
78
252
79
- // Test casess
80
- Case cases[] = { Case (" Timers: toggle on/off" , test_case_timeout), };
253
+ Case cases[] = {
254
+ Case (" Test callback called once (with attach)" , test_callback_fires_once<TimeoutAttachTester>),
255
+ Case (" Test callback called once (with attach_us)" , test_callback_fires_once<TimeoutAttachUSTester>),
256
+
257
+ Case (" Test callback not called when cancelled (with attach)" , test_cancel<TimeoutAttachTester>),
258
+ Case (" Test callback not called when cancelled (with attach_us)" , test_cancel<TimeoutAttachUSTester>),
259
+
260
+ Case (" Test callback override (with attach)" , test_override<TimeoutAttachTester>),
261
+ Case (" Test callback override (with attach_us)" , test_override<TimeoutAttachUSTester>),
262
+
263
+ Case (" Test multiple timeouts running in parallel (with attach)" , test_multiple<TimeoutAttachTester>),
264
+ Case (" Test multiple timeouts running in parallel (with attach_us)" , test_multiple<TimeoutAttachUSTester>),
265
+
266
+ Case (" Test zero delay (with attach)" , test_no_wait<TimeoutAttachTester>),
267
+ Case (" Test zero delay (with attach_us)" , test_no_wait<TimeoutAttachUSTester>),
268
+
269
+ Case (" Timers: toggle on/off" , test_case_timeout)
270
+ };
81
271
82
- utest::v1::status_t greentea_test_setup (const size_t number_of_cases) {
272
+ utest::v1::status_t greentea_test_setup (const size_t number_of_cases)
273
+ {
83
274
GREENTEA_SETUP (test_timeout, " timing_drift_auto" );
84
275
return greentea_test_setup_handler (number_of_cases);
85
276
}
86
277
87
278
Specification specification (greentea_test_setup, cases, greentea_test_teardown_handler);
88
279
89
- int main () {
280
+ int main ()
281
+ {
90
282
Harness::run (specification);
91
283
}
0 commit comments