Skip to content

Provide fixes for HAL ticker test #6472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 69 additions & 31 deletions TESTS/mbed_hal/common_tickers/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,69 @@

#define NUM_OF_CYCLES 100000

#define US_TICKER_OV_LIMIT 20000
#define LP_TICKER_OV_LIMIT 4000

using namespace utest::v1;

volatile int intFlag = 0;
const ticker_interface_t* intf;
unsigned int ticker_overflow_delta;


/* Auxiliary function to count ticker ticks elapsed during execution of N cycles of empty while loop.
* Parameter <step> is used to disable compiler optimisation. */
uint32_t count_ticks(uint32_t cycles, uint32_t step)
{
register uint32_t reg_cycles = cycles;

const ticker_info_t* p_ticker_info = intf->get_info();
const uint32_t max_count = ((1 << p_ticker_info->bits) - 1);

core_util_critical_section_enter();

const uint32_t start = intf->read();

while (cycles -= step) {
while (reg_cycles -= step) {
/* Just wait. */
}

const uint32_t stop = intf->read();

core_util_critical_section_exit();

return (stop - start);
/* Handle overflow - overflow protection may not work in this case. */
uint32_t diff = (start <= stop) ? (stop - start) : (uint32_t)(max_count - start + stop + 1);

return (diff);
}

/* Since according to the ticker requirements min acceptable counter size is
* - 12 bits for low power timer - max count = 4095,
* - 16 bits for high frequency timer - max count = 65535
* then all test cases must be executed in this time windows.
* HAL ticker layer handles counter overflow and it is not handled in the target
* ticker drivers. Ensure we have enough time to execute test case without overflow.
*/
void overflow_protect()
{
uint32_t time_window;

if (intf == get_us_ticker_data()->interface) {
time_window = US_TICKER_OV_LIMIT;
} else {
time_window = LP_TICKER_OV_LIMIT;
}

const uint32_t ticks_now = intf->read();
const ticker_info_t* p_ticker_info = intf->get_info();

const uint32_t max_count = ((1 << p_ticker_info->bits) - 1);

if ((max_count - ticks_now) > time_window) {
return;
}

while (intf->read() > ticks_now);
}

void ticker_event_handler_stub(const ticker_data_t * const ticker)
Expand Down Expand Up @@ -94,6 +131,8 @@ void wait_cycles(volatile unsigned int cycles)
*/
void ticker_init_test()
{
overflow_protect();

intFlag = 0;

intf->init();
Expand Down Expand Up @@ -134,6 +173,8 @@ void ticker_interrupt_test(void)
{
uint32_t ticker_timeout[] = { 100, 200, 300, 500 };

overflow_protect();

for (uint32_t i = 0; i < (sizeof(ticker_timeout) / sizeof(uint32_t)); i++) {
intFlag = 0;
const uint32_t tick_count = intf->read();
Expand Down Expand Up @@ -186,6 +227,8 @@ void ticker_past_test(void)
/* Test that ticker can be rescheduled repeatedly before the handler has been called. */
void ticker_repeat_reschedule_test(void)
{
overflow_protect();

intFlag = 0;

const uint32_t tick_count = intf->read();
Expand Down Expand Up @@ -298,13 +341,32 @@ void ticker_increment_test(void)

TEST_ASSERT_UINT32_WITHIN(1, next_tick_count, base_tick_count);
} else { // high frequency tickers
const uint32_t base_tick_count = count_ticks(NUM_OF_CYCLES, 1);

uint32_t num_of_cycles = NUM_OF_CYCLES;

const uint32_t base_tick_count = count_ticks(num_of_cycles, 1);
uint32_t next_tick_count = base_tick_count;
uint32_t inc_val = 0;

while (next_tick_count == base_tick_count) {
next_tick_count = count_ticks(NUM_OF_CYCLES + inc_val, 1);
inc_val++;
while (inc_val < 100) {
next_tick_count = count_ticks(num_of_cycles + inc_val, 1);

if (next_tick_count == base_tick_count) {
/* Same tick count, so increase num of cycles. */
inc_val++;
} else {
/* It is possible that the difference between base and next
* tick count on some platforms is greater that 1, in this case we need
* to repeat counting with the reduced number of cycles (for slower boards).
* In cases if difference is exactly 1 we can exit the loop.
*/
num_of_cycles /= 2;

if (next_tick_count - base_tick_count == 1 ||
base_tick_count - next_tick_count == 1) {
break;
}
}
}

/* Since we are here we know that next_tick_count != base_tick_count.
Expand Down Expand Up @@ -376,26 +438,6 @@ void ticker_speed_test(void)
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
}

/* Since according to the ticker requirements min acceptable counter size is
* 12 bits (low power timer) for which max count is
* 4095, then all test cases must be executed in this time window.
* HAL ticker layer handles overflow and it is not handled in the target
* ticker drivers.
*/
void overflow_protect()
{
const uint32_t ticks_now = intf->read();
const ticker_info_t* p_ticker_info = intf->get_info();

const uint32_t max_count = (1 << p_ticker_info->bits - 1);

if ((max_count - ticks_now) > 4000) {
return;
}

while (intf->read() > ticks_now);
}

utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index_of_case)
{
intf = get_us_ticker_data()->interface;
Expand All @@ -406,8 +448,6 @@ utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index

ticker_overflow_delta = US_TICKER_OVERFLOW_DELTA;

overflow_protect();

return greentea_case_setup_handler(source, index_of_case);
}

Expand All @@ -422,8 +462,6 @@ utest::v1::status_t lp_ticker_setup(const Case *const source, const size_t index

ticker_overflow_delta = LP_TICKER_OVERFLOW_DELTA;

overflow_protect();

return greentea_case_setup_handler(source, index_of_case);
}
#endif
Expand Down