From 1d57cf9e0f22ec74bc6417d8b7ef4b7bfff6747c Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 13 Dec 2021 13:56:32 +0100 Subject: [PATCH] tests/periph_timer_periodic: spice up test This should detect some bugs regarding incorrect behavior regarding timer_start() not resuming periodic timers as expected. --- tests/periph_timer_periodic/main.c | 71 ++++++++++++++------- tests/periph_timer_periodic/tests/01-run.py | 23 +++++-- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/tests/periph_timer_periodic/main.c b/tests/periph_timer_periodic/main.c index 2f3be4830b..42b4d014bf 100644 --- a/tests/periph_timer_periodic/main.c +++ b/tests/periph_timer_periodic/main.c @@ -18,8 +18,9 @@ * @} */ -#include #include +#include +#include #include "board.h" #include "macros/units.h" @@ -57,6 +58,10 @@ #define MAX_CHANNELS (10) #endif +#ifndef ITERATIONS +#define ITERATIONS 3 +#endif + static unsigned count[MAX_CHANNELS]; static void cb(void *arg, int chan) @@ -75,11 +80,12 @@ static void cb(void *arg, int chan) static const char* _print_ok(int chan, bool *succeeded) { - if (chan == 0 && count[chan] > 0) { - return "OK"; + if (chan == 0) { + if (count[chan] > 0) { + return "OK"; + } } - - if (chan > 0 && count[chan] == 0) { + else if (count[chan] == 0) { return "OK"; } @@ -89,7 +95,7 @@ static const char* _print_ok(int chan, bool *succeeded) int main(void) { - mutex_t lock = MUTEX_INIT_LOCKED; + mutex_t lock = MUTEX_INIT; const unsigned long timer_hz = XTIMER_HZ; const unsigned steps = (CYCLE_MS * timer_hz) / 1000; @@ -100,25 +106,42 @@ int main(void) expect(timer_init(TIMER_CYCL, timer_hz, cb, &lock) == 0); puts("TEST START"); - - /* Only the first channel should trigger and reset the counter */ - /* If subsequent channels trigger this is an error. */ - unsigned channel_numof = 1; - for(unsigned i = 1; i < MAX_CHANNELS; i++) { - if(!timer_set_periodic(TIMER_CYCL, i, (1 + i) * steps, TIM_FLAG_RESET_ON_SET)) { - channel_numof = i; - break; - } - } - timer_set_periodic(TIMER_CYCL, 0, steps, TIM_FLAG_RESET_ON_MATCH); - - mutex_lock(&lock); - - puts("\nCycles:"); - bool succeeded = true; - for (unsigned i = 0; i < channel_numof; ++i) { - printf("channel %u = %02u\t[%s]\n", i, count[i], _print_ok(i, &succeeded)); + unsigned channel_numof = 1; + + for (unsigned iter = 0; iter < ITERATIONS; iter++) { + printf("Running iteration %u of %u\n", iter + 1, (unsigned)ITERATIONS); + lock = (mutex_t)MUTEX_INIT_LOCKED; + memset(count, 0x00, sizeof(count)); + + /* Only the first channel should trigger and reset the counter */ + /* If subsequent channels trigger this is an error. */ + for (unsigned chan = 1; chan < MAX_CHANNELS; chan++) { + if (!timer_set_periodic(TIMER_CYCL, chan, (1 + chan) * steps, + TIM_FLAG_RESET_ON_SET)) + { + channel_numof = chan; + break; + } + } + + if (iter == 0) { + /* configure timer on first iterations */ + timer_set_periodic(TIMER_CYCL, 0, steps, TIM_FLAG_RESET_ON_MATCH); + } + else { + /* resume timer on subsequent iterations */ + timer_start(TIMER_CYCL); + } + + mutex_lock(&lock); + + puts("\nCycles:"); + + for (unsigned i = 0; i < channel_numof; ++i) { + printf("channel %u = %02u\t[%s]\n", + i, count[i], _print_ok(i, &succeeded)); + } } if (succeeded) { diff --git a/tests/periph_timer_periodic/tests/01-run.py b/tests/periph_timer_periodic/tests/01-run.py index 653914f86e..61c93101e1 100755 --- a/tests/periph_timer_periodic/tests/01-run.py +++ b/tests/periph_timer_periodic/tests/01-run.py @@ -17,13 +17,24 @@ PRECISION = float(os.getenv("TEST_PERIPH_TIMER_PERIODIC_PRECISION", "0")) def testfunc(child): child.expect_exact('TEST START') - start = time.time() + while True: + child.expect(r"Running iteration (\d+) of (\d+)\r\n") + iteration = int(child.match.group(1)) + last_iteration = int(child.match.group(2)) + start = time.time() + for i in range(12): + child.expect(r"\[(\d+)\] tick\r\n") + chan = int(child.match.group(1)) + assert chan == 0, "Only channel 0 should tick" + child.expect("Cycles:\r\n") + end = time.time() + # test should run 10 cycles with 25ms each + elapsed = end - start + assert elapsed > 0.25 * (1 - PRECISION), "=< 0.25s ({})".format(elapsed) + assert elapsed < 0.40 * (1 + PRECISION), "=> 0.40s ({})".format(elapsed) + if iteration == last_iteration: + break child.expect_exact('TEST SUCCEEDED') - end = time.time() - # test should run 10 cycles with 25ms each - elapsed = end - start - assert elapsed > 0.25 * (1 - PRECISION), "=< 0.25s ({})".format(elapsed) - assert elapsed < 0.40 * (1 + PRECISION), "=> 0.40s ({})".format(elapsed) if __name__ == "__main__":