Skip to content

Commit e02466a

Browse files
author
Cruz Monrreal
authored
Merge pull request #7524 from c1728p9/tickless_fix
Fixes for tickless and LPTICKER_DELAY_TICKS
2 parents 7c22dca + dc2e2c0 commit e02466a

File tree

20 files changed

+1068
-196
lines changed

20 files changed

+1068
-196
lines changed

TESTS/mbed_drivers/sleep_lock/main.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,90 +29,90 @@ using namespace utest::v1;
2929

3030
void deep_sleep_lock_lock_test()
3131
{
32-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
32+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
3333
{
3434
// Check basic usage works
3535
DeepSleepLock lock;
36-
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
36+
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
3737
}
3838

39-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
39+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
4040
{
4141
// Check that unlock and lock change can deep sleep as expected
4242
DeepSleepLock lock;
43-
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
43+
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
4444
lock.unlock();
45-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
45+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
4646
lock.lock();
47-
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
47+
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
4848
}
4949

50-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
50+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
5151
{
5252
// Check that unlock releases sleep based on count
5353
DeepSleepLock lock;
5454
lock.lock();
5555
lock.lock();
5656
lock.unlock();
57-
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
57+
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
5858
}
5959

60-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
60+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
6161
{
6262
// Check that unbalanced locks do not leave deep sleep locked
6363
DeepSleepLock lock;
6464
lock.lock();
65-
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
65+
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
6666
}
67-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
67+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
6868

6969
}
7070

7171
void timer_lock_test()
7272
{
73-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
73+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
7474
{
7575
// Just creating a timer object does not lock sleep
7676
Timer timer;
77-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
77+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
7878
}
7979

80-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
80+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
8181
{
8282
// Starting a timer does lock sleep
8383
Timer timer;
8484
timer.start();
85-
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
85+
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
8686
}
8787

88-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
88+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
8989
{
9090
// Stopping a timer after starting it allows sleep
9191
Timer timer;
9292
timer.start();
9393
timer.stop();
94-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
94+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
9595
}
9696

97-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
97+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
9898
{
9999
// Starting a timer multiple times still lets you sleep
100100
Timer timer;
101101
timer.start();
102102
timer.start();
103103
}
104-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
104+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
105105

106-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
106+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
107107
{
108108
// Stopping a timer multiple times still lets you sleep
109109
Timer timer;
110110
timer.start();
111111
timer.stop();
112112
timer.stop();
113-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
113+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
114114
}
115-
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
115+
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
116116
}
117117

118118
Case cases[] = {

TESTS/mbed_drivers/timeout/timeout_tests.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ void test_sleep(void)
263263
timer.start();
264264
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us);
265265

266-
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
266+
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
267267
TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed");
268268
while (sem.wait(0) != 1) {
269269
sleep();
@@ -322,7 +322,7 @@ void test_deepsleep(void)
322322
timer.start();
323323
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us);
324324

325-
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
325+
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
326326
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
327327
while (sem.wait(0) != 1) {
328328
sleep();

TESTS/mbed_hal/common_tickers/main.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "ticker_api_tests.h"
2121
#include "hal/us_ticker_api.h"
2222
#include "hal/lp_ticker_api.h"
23+
#include "hal/mbed_lp_ticker_wrapper.h"
2324

2425
#ifdef __cplusplus
2526
extern "C" {
@@ -496,7 +497,15 @@ utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index
496497
{
497498
intf = get_us_ticker_data()->interface;
498499

499-
OS_Tick_Disable();
500+
/* OS, common ticker and low power ticker wrapper
501+
* may make use of us ticker so suspend them for this test */
502+
osKernelSuspend();
503+
#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0)
504+
/* Suspend the lp ticker wrapper since it makes use of the us ticker */
505+
ticker_suspend(get_lp_ticker_data());
506+
lp_ticker_wrapper_suspend();
507+
#endif
508+
ticker_suspend(get_us_ticker_data());
500509

501510
intf->init();
502511

@@ -515,7 +524,12 @@ utest::v1::status_t us_ticker_teardown(const Case *const source, const size_t pa
515524

516525
prev_irq_handler = NULL;
517526

518-
OS_Tick_Enable();
527+
ticker_resume(get_us_ticker_data());
528+
#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0)
529+
lp_ticker_wrapper_resume();
530+
ticker_resume(get_lp_ticker_data());
531+
#endif
532+
osKernelResume(0);
519533

520534
return greentea_case_teardown_handler(source, passed, failed, reason);
521535
}
@@ -525,7 +539,9 @@ utest::v1::status_t lp_ticker_setup(const Case *const source, const size_t index
525539
{
526540
intf = get_lp_ticker_data()->interface;
527541

528-
OS_Tick_Disable();
542+
/* OS and common ticker may make use of lp ticker so suspend them for this test */
543+
osKernelSuspend();
544+
ticker_suspend(get_lp_ticker_data());
529545

530546
intf->init();
531547

@@ -544,7 +560,8 @@ utest::v1::status_t lp_ticker_teardown(const Case *const source, const size_t pa
544560

545561
prev_irq_handler = NULL;
546562

547-
OS_Tick_Enable();
563+
ticker_resume(get_lp_ticker_data());
564+
osKernelResume(0);
548565

549566
return greentea_case_teardown_handler(source, passed, failed, reason);
550567
}

TESTS/mbed_hal/common_tickers_freq/main.cpp

Lines changed: 83 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ticker_api_test_freq.h"
2929
#include "hal/us_ticker_api.h"
3030
#include "hal/lp_ticker_api.h"
31+
#include "hal/mbed_lp_ticker_wrapper.h"
3132

3233
#if !DEVICE_USTICKER
3334
#error [NOT_SUPPORTED] test not supported
@@ -38,25 +39,51 @@
3839
using namespace utest::v1;
3940

4041
const ticker_interface_t *intf;
41-
42-
static volatile unsigned int overflowCounter;
42+
uint32_t intf_mask;
43+
uint32_t intf_last_tick;
44+
uint32_t intf_elapsed_ticks;
45+
ticker_irq_handler_type prev_handler;
4346

4447
uint32_t ticks_to_us(uint32_t ticks, uint32_t freq)
4548
{
4649
return (uint32_t)((uint64_t)ticks * US_PER_S / freq);
4750
}
4851

49-
void ticker_event_handler_stub(const ticker_data_t *const ticker)
52+
void elapsed_ticks_reset()
5053
{
51-
if (ticker == get_us_ticker_data()) {
52-
us_ticker_clear_interrupt();
53-
} else {
54-
#if DEVICE_LPTICKER
55-
lp_ticker_clear_interrupt();
56-
#endif
57-
}
54+
core_util_critical_section_enter();
55+
56+
const uint32_t ticker_bits = intf->get_info()->bits;
57+
58+
intf_mask = (1 << ticker_bits) - 1;
59+
intf_last_tick = intf->read();
60+
intf_elapsed_ticks = 0;
61+
62+
core_util_critical_section_exit();
63+
}
5864

59-
overflowCounter++;
65+
uint32_t elapsed_ticks_update()
66+
{
67+
core_util_critical_section_enter();
68+
69+
const uint32_t current_tick = intf->read();
70+
intf_elapsed_ticks += (current_tick - intf_last_tick) & intf_mask;
71+
intf_last_tick = current_tick;
72+
73+
/* Schedule next interrupt half way to overflow */
74+
uint32_t next = (current_tick + intf_mask / 2) & intf_mask;
75+
intf->set_interrupt(next);
76+
77+
uint32_t elapsed = intf_elapsed_ticks;
78+
79+
core_util_critical_section_exit();
80+
return elapsed;
81+
}
82+
83+
void ticker_event_handler_stub(const ticker_data_t *const ticker)
84+
{
85+
intf->clear_interrupt();
86+
elapsed_ticks_update();
6087
}
6188

6289
/* Test that the ticker is operating at the frequency it specifies. */
@@ -66,13 +93,13 @@ void ticker_frequency_test()
6693
char _value[128] = { };
6794
int expected_key = 1;
6895
const uint32_t ticker_freq = intf->get_info()->frequency;
69-
const uint32_t ticker_bits = intf->get_info()->bits;
70-
const uint32_t ticker_max = (1 << ticker_bits) - 1;
7196

7297
intf->init();
7398

99+
elapsed_ticks_reset();
100+
74101
/* Detect overflow for tickers with lower counters width. */
75-
intf->set_interrupt(0);
102+
elapsed_ticks_update();
76103

77104
greentea_send_kv("timing_drift_check_start", 0);
78105

@@ -82,19 +109,17 @@ void ticker_frequency_test()
82109
expected_key = strcmp(_key, "base_time");
83110
} while (expected_key);
84111

85-
overflowCounter = 0;
86-
87-
const uint32_t begin_ticks = intf->read();
112+
const uint32_t begin_ticks = elapsed_ticks_update();
88113

89114
/* Assume that there was no overflow at this point - we are just after init. */
90115
greentea_send_kv(_key, ticks_to_us(begin_ticks, ticker_freq));
91116

92117
/* Wait for 2nd signal from host. */
93118
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
94119

95-
const uint32_t end_ticks = intf->read();
120+
const uint32_t end_ticks = elapsed_ticks_update();
96121

97-
greentea_send_kv(_key, ticks_to_us(end_ticks + overflowCounter * ticker_max, ticker_freq));
122+
greentea_send_kv(_key, ticks_to_us(end_ticks, ticker_freq));
98123

99124
/* Get the results from host. */
100125
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
@@ -106,43 +131,74 @@ void ticker_frequency_test()
106131

107132
utest::v1::status_t us_ticker_case_setup_handler_t(const Case *const source, const size_t index_of_case)
108133
{
134+
#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0)
135+
/* Suspend the lp ticker wrapper since it makes use of the us ticker */
136+
ticker_suspend(get_lp_ticker_data());
137+
lp_ticker_wrapper_suspend();
138+
#endif
139+
ticker_suspend(get_us_ticker_data());
109140
intf = get_us_ticker_data()->interface;
110-
set_us_ticker_irq_handler(ticker_event_handler_stub);
141+
prev_handler = set_us_ticker_irq_handler(ticker_event_handler_stub);
111142
return greentea_case_setup_handler(source, index_of_case);
112143
}
113144

145+
utest::v1::status_t us_ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed,
146+
const failure_t reason)
147+
{
148+
set_us_ticker_irq_handler(prev_handler);
149+
ticker_resume(get_us_ticker_data());
150+
#if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0)
151+
lp_ticker_wrapper_resume();
152+
ticker_resume(get_lp_ticker_data());
153+
#endif
154+
return greentea_case_teardown_handler(source, passed, failed, reason);
155+
}
156+
114157
#if DEVICE_LPTICKER
115158
utest::v1::status_t lp_ticker_case_setup_handler_t(const Case *const source, const size_t index_of_case)
116159
{
160+
ticker_suspend(get_lp_ticker_data());
117161
intf = get_lp_ticker_data()->interface;
118-
set_lp_ticker_irq_handler(ticker_event_handler_stub);
162+
prev_handler = set_lp_ticker_irq_handler(ticker_event_handler_stub);
119163
return greentea_case_setup_handler(source, index_of_case);
120164
}
121-
#endif
122165

123-
utest::v1::status_t ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed,
124-
const failure_t reason)
166+
utest::v1::status_t lp_ticker_case_teardown_handler_t(const Case *const source, const size_t passed, const size_t failed,
167+
const failure_t reason)
125168
{
169+
set_lp_ticker_irq_handler(prev_handler);
170+
ticker_resume(get_lp_ticker_data());
126171
return greentea_case_teardown_handler(source, passed, failed, reason);
127172
}
173+
#endif
128174

129175
// Test cases
130176
Case cases[] = {
131177
Case("Microsecond ticker frequency test", us_ticker_case_setup_handler_t, ticker_frequency_test,
132-
ticker_case_teardown_handler_t),
178+
us_ticker_case_teardown_handler_t),
133179
#if DEVICE_LPTICKER
134180
Case("Low power ticker frequency test", lp_ticker_case_setup_handler_t, ticker_frequency_test,
135-
ticker_case_teardown_handler_t),
181+
lp_ticker_case_teardown_handler_t),
136182
#endif
137183
};
138184

139185
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
140186
{
187+
/* Suspend RTOS Kernel so the timers are not in use. */
188+
osKernelSuspend();
189+
141190
GREENTEA_SETUP(120, "timing_drift_auto");
142191
return greentea_test_setup_handler(number_of_cases);
143192
}
144193

145-
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
194+
void greentea_test_teardown(const size_t passed, const size_t failed, const failure_t failure)
195+
{
196+
osKernelResume(0);
197+
198+
greentea_test_teardown_handler(passed, failed, failure);
199+
}
200+
201+
Specification specification(greentea_test_setup, cases, greentea_test_teardown);
146202

147203
int main()
148204
{

0 commit comments

Comments
 (0)