tests/ztimer_periodic: iterate over clocks

Instead of only testing for `ZTIMER_MSEC`, iterate over a list of
clocks and run the test for each. The reasoning is that this test
does not only test `ztimer_periodic`, but also that the used clock
backend operates correctly in a typical use case.
This commit is contained in:
Marian Buschsieweke 2021-03-30 13:12:42 +02:00
parent 9954ac8166
commit 258d384fec
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F
2 changed files with 43 additions and 31 deletions

View File

@ -1,2 +1,3 @@
BOARD_INSUFFICIENT_MEMORY := \ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \ nucleo-l011k4 \
#

View File

@ -32,45 +32,55 @@
static mutex_t _mutex = MUTEX_INIT_LOCKED; static mutex_t _mutex = MUTEX_INIT_LOCKED;
#define MAX_OFFSET 2
#define N 5 #define N 5
#define INTERVAL 100LU
static uint32_t _times[N]; static uint32_t _times[N];
static int _count;
#define CLOCKS { ZTIMER_MSEC, ZTIMER_USEC }
static const char *_names[] = { "ZTIMER_MSEC", "ZTIMER_USEC" };
static uint32_t _intervals[] = { 100, 10000 };
static uint32_t _max_offsets[] = { 2, 100 };
static int callback(void *arg) static int callback(void *arg)
{ {
(void)arg; _times[_count] = ztimer_now(arg);
static int count = 0;
_times[count] = ztimer_now(ZTIMER_MSEC); _count += 1;
count += 1;
/* enable this to test underflow behavior */ /* enable this to test underflow behavior */
#if 0 #if 0
if (count == 2) { if (count == 2) {
ztimer_spin(ZTIMER_MSEC, INTERVAL*2); ztimer_spin(arg, INTERVAL * 2);
} }
#endif #endif
if (count == N) { if (_count == N) {
mutex_unlock(&_mutex); mutex_unlock(&_mutex);
} }
return (count == N); return (_count == N);
} }
int main(void) int main(void)
{ {
ztimer_periodic_t t; ztimer_periodic_t t;
ztimer_clock_t * const clocks[] = CLOCKS;
int failed = 0;
ztimer_periodic_init(ZTIMER_MSEC, &t, callback, NULL, INTERVAL); for (size_t j = 0; j < ARRAY_SIZE(clocks); j++) {
uint32_t last = ztimer_now(ZTIMER_MSEC); printf("Testing clock: %s\n", _names[j]);
ztimer_clock_t *clock = clocks[j];
ztimer_periodic_init(clock, &t, callback, clock, _intervals[j]);
_count = 0;
ztimer_periodic_start(&t); ztimer_periodic_start(&t);
/* ztimer_periodic_start stores the value of ztimer_now() + period into t.last. We use that
* value instead of calling ztimer_now() again, as on slow boards the introduced offset can
* result in a failing test, despite the timeout actually being triggered close enough
* to the target. */
uint32_t last = t.last - _intervals[j];
if (!ztimer_is_set(ZTIMER_MSEC, &t.timer)) { if (!ztimer_is_set(clock, &t.timer)) {
print_str("Test failed\n"); print_str("Test failed\n");
return 1; return 1;
} }
@ -78,18 +88,19 @@ int main(void)
/* wait for periodic to trigger N times */ /* wait for periodic to trigger N times */
mutex_lock(&_mutex); mutex_lock(&_mutex);
int failed = 0;
for (unsigned i = 0; i < N; i++) { for (unsigned i = 0; i < N; i++) {
uint32_t offset = labs((int32_t)(_times[i] - INTERVAL - last)); uint32_t offset = labs((int32_t)(_times[i] - _intervals[j] - last));
printf("i: %u time: %" PRIu32 " offset: %" PRIu32 "\n", printf("i: %u time: %" PRIu32 " offset: %" PRIu32 "\n",
i, _times[i], offset); i, _times[i], offset);
if (offset > MAX_OFFSET) { if (offset > _max_offsets[j]) {
failed = 1; failed = 1;
} }
last = _times[i]; last = _times[i];
} }
ztimer_periodic_stop(&t);
}
if (!failed) { if (!failed) {
print_str("Test successful.\n"); print_str("Test successful.\n");
} }