tests/periph_timer_short_relative_set: initial commit

This commit is contained in:
Kaspar Schleiser 2019-10-30 13:39:53 +01:00
parent 4df6bb425f
commit 81f113ba05
4 changed files with 150 additions and 0 deletions

View File

@ -0,0 +1,17 @@
include ../Makefile.tests_common
FEATURES_REQUIRED = periph_timer
USEMODULE += core_thread_flags
# optionally configure timer under test. Defaults to xtimer config.
# TEST_TIMER_DEV takes a 0-based index to the periph_timer instance defined in
# the board's periph_conf.h. TEST_TIMER_FREQ as an integer number which will
# be used as "freq" parameter in the timer_init() call.
# Note: not all implementations support arbitrary frequencies.
#CFLAGS += -DTEST_TIMER_DEV=foo -DTEST_TIMER_FREQ=bar
# this test currently fails all CI boards and native
TEST_ON_CI_BLACKLIST += all
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,32 @@
# Periph Timer Test for short timer_set() values
## About
This test exposes if timer_set() with very low values (down to zero) underflows.
For each value from 100 to 0, it'll try to set a timer with that length.
In human terms, that should trigger instantly (It depends on TEST_TIMER_FREQ.
The default configuration is 1MHz. Some boards configure 32768kHz, which is the
slowest configuration currently. So each line should trigger after at most
31us.).
See this example of a timer_set() implementation:
int timer_set(tim_t dev, int channel, unsigned int timeout)
{
return timer_set_absolute(dev, channel, timer_read(dev) + timeout);
}
This will probably underflow if "timeout" is 0, or if an ISR interrupts
somewhere between the read and the timerSet_absolute() call.
Depending on the used frequency of the underlying timer and the time it
requires for the involved function calls, reading the timer register, doing the
addition and writing back to the register, this will also fail for higher
timeouts.
For example, as of this writing (30-Oct-19), samr21-xpro fails for values below
8, nrf52dk for values below 2.
## Expected Result
After 100 "interval N ok" messages the test should print "TEST SUCCEEDED".
On failure, the test will print "TEST FAILED".

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2019 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Peripheral timer test application
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "board.h"
#include "thread.h"
#include "thread_flags.h"
#include "periph/timer.h"
#ifndef TEST_TIMER_DEV
# include "xtimer.h"
# define TEST_TIMER_DEV XTIMER_DEV
# define TEST_TIMER_FREQ XTIMER_HZ
#else
# ifndef TEST_TIMER_FREQ
# define TEST_TIMER_FREQ (1000000LU)
# endif
#endif
#ifndef TEST_MAX_DIFF
#define TEST_MAX_DIFF (1000LU)
#endif
static void cb(void *arg, int chan)
{
(void)chan;
thread_flags_set(arg, 1);
}
int main(void)
{
puts("\nTest for peripheral TIMER short timer_set()\n");
printf("This test tries timer_set() with decreasing intervals down to 0.\n"
"You should see lines like 'interval <n> ok', followed by a success"
" message.\n"
"On failure, this test prints an error message.\n\n");
printf("testing periph_timer %u, freq %lu\n", TEST_TIMER_DEV, TEST_TIMER_FREQ);
timer_init(TEST_TIMER_DEV, TEST_TIMER_FREQ, cb, (thread_t *)sched_active_thread);
uint32_t interval = 100;
while (interval--) {
uint32_t before = timer_read(TEST_TIMER_DEV);
timer_set(TEST_TIMER_DEV, 0, interval);
while(!thread_flags_clear(1)) {
uint32_t diff = timer_read(TEST_TIMER_DEV) - before;
if (diff > TEST_MAX_DIFF) {
printf("ERROR: too long delay, aborted after %" PRIu32
" (TEST_MAX_DIFF=%lu)\n"
"TEST FAILED\n",
diff, TEST_MAX_DIFF);
while(1) {}
}
}
printf("interval %" PRIu32 " ok\n", interval);
}
puts("\nTEST SUCCEEDED");
return 0;
}

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# Copyright (C) 2019 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import sys
from testrunner import run
def testfunc(child):
child.expect_exact('TEST SUCCEEDED')
if __name__ == "__main__":
sys.exit(run(testfunc))