Skip to content

Commit 89eba73

Browse files
committed
Timed sleep rework
1 parent a1e1ab6 commit 89eba73

File tree

6 files changed

+808
-227
lines changed

6 files changed

+808
-227
lines changed

TESTS/mbedmicro-rtos-mbed/systimer/main.cpp

Lines changed: 49 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
#ifndef MBED_TICKLESS
17-
#error [NOT_SUPPORTED] Tickless mode not supported for this target.
18-
#endif
1916

2017
#include "mbed.h"
2118
#include "greentea-client/test_env.h"
@@ -28,7 +25,8 @@ extern "C" {
2825
}
2926
#include "platform/SysTimer.h"
3027

31-
#define TEST_TICKS 42UL
28+
#define TEST_TICKS 42
29+
#define TEST_TICK_US (TEST_TICKS * 1000)
3230
#define DELAY_DELTA_US 2500ULL
3331

3432
/* Use a specific delta value for deep sleep, as entry/exit adds up extra latency.
@@ -40,29 +38,29 @@ extern "C" {
4038
#endif
4139

4240
using namespace utest::v1;
41+
using mbed::internal::SysTimer;
4342

44-
const us_timestamp_t DELAY_US = 1000000ULL * TEST_TICKS / OS_TICK_FREQ;
43+
const us_timestamp_t DELAY_US = TEST_TICK_US;
4544

46-
// Override the handler() -- the SysTick interrupt must not be set as pending by the test code.
47-
class SysTimerTest: public mbed::internal::SysTimer {
45+
// The SysTick interrupt must not be set as pending by the test code.
46+
template <uint32_t US_IN_TICK>
47+
class SysTimerTest: public SysTimer<US_IN_TICK, false> {
4848
private:
4949
Semaphore _sem;
5050
virtual void handler()
5151
{
52-
core_util_critical_section_enter();
53-
_increment_tick();
54-
core_util_critical_section_exit();
5552
_sem.release();
53+
SysTimer<US_IN_TICK, false>::handler();
5654
}
5755

5856
public:
5957
SysTimerTest() :
60-
SysTimer(), _sem(0, 1)
58+
SysTimer<US_IN_TICK, false>(), _sem(0, 1)
6159
{
6260
}
6361

6462
SysTimerTest(const ticker_data_t *data) :
65-
SysTimer(data), _sem(0, 1)
63+
SysTimer<US_IN_TICK, false>(data), _sem(0, 1)
6664
{
6765
}
6866

@@ -153,7 +151,7 @@ void mock_ticker_reset()
153151
*/
154152
void test_created_with_zero_tick_count(void)
155153
{
156-
SysTimerTest st;
154+
SysTimerTest<1000> st;
157155
TEST_ASSERT_EQUAL_UINT32(0, st.get_tick());
158156
}
159157

@@ -164,26 +162,27 @@ void test_created_with_zero_tick_count(void)
164162
* Then the tick count is not updated
165163
* When @a suspend and @a resume methods are called again after a delay
166164
* Then the tick count is updated
167-
* and the number of ticks incremented is equal TEST_TICKS - 1
165+
* and the number of ticks incremented is equal TEST_TICKS
168166
* When @a suspend and @a resume methods are called again without a delay
169167
* Then the tick count is not updated
170168
*/
171169
void test_update_tick(void)
172170
{
173171
mock_ticker_reset();
174-
SysTimerTest st(&mock_ticker_data);
175-
st.suspend(TEST_TICKS * 2);
176-
TEST_ASSERT_EQUAL_UINT32(0, st.resume());
172+
SysTimerTest<1000> st(&mock_ticker_data);
173+
st.set_wake_time(st.get_tick() + TEST_TICKS * 2);
174+
st.cancel_wake();
177175
TEST_ASSERT_EQUAL_UINT32(0, st.get_tick());
178176

179-
st.suspend(TEST_TICKS * 2);
177+
st.set_wake_time(st.get_tick() + TEST_TICKS * 2);
180178
mock_ticker_timestamp = DELAY_US;
181-
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.resume());
182-
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.get_tick());
179+
st.cancel_wake();
180+
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS, st.update_and_get_tick());
181+
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS, st.get_tick());
183182

184-
st.suspend(TEST_TICKS * 2);
185-
TEST_ASSERT_EQUAL_UINT32(0, st.resume());
186-
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.get_tick());
183+
st.set_wake_time(st.get_tick() + TEST_TICKS * 2);
184+
st.cancel_wake();
185+
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS, st.get_tick());
187186
}
188187

189188
/** Test get_time returns correct time
@@ -195,7 +194,7 @@ void test_update_tick(void)
195194
void test_get_time(void)
196195
{
197196
mock_ticker_reset();
198-
SysTimerTest st(&mock_ticker_data);
197+
SysTimerTest<1000> st(&mock_ticker_data);
199198
us_timestamp_t t1 = st.get_time();
200199

201200
mock_ticker_timestamp = DELAY_US;
@@ -212,60 +211,51 @@ void test_get_time(void)
212211
*/
213212
void test_cancel_tick(void)
214213
{
215-
SysTimerTest st;
214+
SysTimerTest<TEST_TICK_US> st;
216215
st.cancel_tick();
217-
st.schedule_tick(TEST_TICKS);
216+
st.start_tick();
218217

219218
st.cancel_tick();
220219
bool acquired = st.sem_try_acquire((DELAY_US + DELAY_DELTA_US) / 1000ULL);
221220
TEST_ASSERT_FALSE(acquired);
222221
TEST_ASSERT_EQUAL_UINT32(0, st.get_tick());
223222
}
224223

225-
/** Test schedule zero
226-
*
227-
* Given a SysTimer
228-
* When a tick is scheduled with delta = 0 ticks
229-
* Then the handler is called instantly
230-
*/
231-
void test_schedule_zero(void)
232-
{
233-
SysTimerTest st;
234-
235-
st.schedule_tick(0UL);
236-
bool acquired = st.sem_try_acquire(0);
237-
TEST_ASSERT_TRUE(acquired);
238-
}
239-
240-
/** Test handler called once
224+
/** Test handler called twice
241225
*
242226
* Given a SysTimer with a tick scheduled with delta = TEST_TICKS
243227
* When the handler is called
244228
* Then the tick count is incremented by 1
245229
* and elapsed time is equal 1000000ULL * TEST_TICKS / OS_TICK_FREQ;
246230
* When more time elapses
247-
* Then the handler is not called again
231+
* Repeat a second time.
248232
*/
249-
void test_handler_called_once(void)
233+
void test_handler_called_twice(void)
250234
{
251-
SysTimerTest st;
252-
st.schedule_tick(TEST_TICKS);
235+
SysTimerTest<TEST_TICK_US> st;
253236
us_timestamp_t t1 = st.get_time();
254237
bool acquired = st.sem_try_acquire(0);
255238
TEST_ASSERT_FALSE(acquired);
256239

240+
st.start_tick();
257241
// Wait in a busy loop to prevent entering sleep or deepsleep modes.
258-
while (!acquired) {
242+
do {
259243
acquired = st.sem_try_acquire(0);
260-
}
244+
} while (!acquired);
261245
us_timestamp_t t2 = st.get_time();
262246
TEST_ASSERT_TRUE(acquired);
263247
TEST_ASSERT_EQUAL_UINT32(1, st.get_tick());
264248
TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, t2 - t1);
265249

266-
acquired = st.sem_try_acquire((DELAY_US + DELAY_DELTA_US) / 1000ULL);
267-
TEST_ASSERT_FALSE(acquired);
268-
TEST_ASSERT_EQUAL_UINT32(1, st.get_tick());
250+
// Wait in a busy loop to prevent entering sleep or deepsleep modes.
251+
do {
252+
acquired = st.sem_try_acquire(0);
253+
} while (!acquired);
254+
t2 = st.get_time();
255+
TEST_ASSERT_TRUE(acquired);
256+
TEST_ASSERT_EQUAL_UINT32(2, st.get_tick());
257+
TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US * 2, t2 - t1);
258+
st.cancel_tick();
269259
}
270260

271261
#if DEVICE_SLEEP
@@ -281,16 +271,17 @@ void test_handler_called_once(void)
281271
void test_sleep(void)
282272
{
283273
Timer timer;
284-
SysTimerTest st;
274+
SysTimerTest<TEST_TICK_US> st;
285275

286276
sleep_manager_lock_deep_sleep();
287277
timer.start();
288-
st.schedule_tick(TEST_TICKS);
278+
st.start_tick();
289279

290280
TEST_ASSERT_FALSE_MESSAGE(sleep_manager_can_deep_sleep(), "Deep sleep should be disallowed");
291281
st.sem_acquire();
292282

293283
timer.stop();
284+
st.cancel_tick();
294285
sleep_manager_unlock_deep_sleep();
295286

296287
TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, timer.read_high_resolution_us());
@@ -319,13 +310,14 @@ void test_deepsleep(void)
319310
wait_ms(10);
320311
// Regular Timer might be disabled during deepsleep.
321312
LowPowerTimer lptimer;
322-
SysTimerTest st;
313+
SysTimerTest<TEST_TICK_US> st;
323314

324315
lptimer.start();
325-
st.schedule_tick(TEST_TICKS);
316+
st.start_tick();
326317
TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep_test_check(), "Deep sleep should be allowed");
327318
st.sem_acquire();
328319
lptimer.stop();
320+
st.cancel_tick();
329321

330322
TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_DELAY_DELTA_US, DELAY_US, lptimer.read_high_resolution_us());
331323
}
@@ -334,7 +326,7 @@ void test_deepsleep(void)
334326

335327
utest::v1::status_t test_setup(const size_t number_of_cases)
336328
{
337-
GREENTEA_SETUP(5, "default_auto");
329+
GREENTEA_SETUP(15, "default_auto");
338330
return verbose_test_setup_handler(number_of_cases);
339331
}
340332

@@ -343,8 +335,7 @@ Case cases[] = {
343335
Case("Tick count is updated correctly", test_update_tick),
344336
Case("Time is updated correctly", test_get_time),
345337
Case("Tick can be cancelled", test_cancel_tick),
346-
Case("Schedule zero ticks", test_schedule_zero),
347-
Case("Handler called once", test_handler_called_once),
338+
Case("Handler called twice", test_handler_called_twice),
348339
#if DEVICE_SLEEP
349340
Case("Wake up from sleep", test_sleep),
350341
#if DEVICE_LPTICKER && !MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER

0 commit comments

Comments
 (0)