mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
2006937ee6
This test is intended to collect statistics about the runtime delays in the periph_timer implementation. This tool is mainly intended to detect problems in the low level driver implementation which can be difficult to detect from higher level systems such as xtimer.
255 lines
6.8 KiB
C
255 lines
6.8 KiB
C
/*
|
|
* Copyright (C) 2018 Eistec AB
|
|
*
|
|
* 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 Configuration definitions for bench_periph_timer
|
|
*
|
|
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
|
*
|
|
* @}
|
|
*/
|
|
#ifndef BENCH_TIMERS_CONFIG_H
|
|
#define BENCH_TIMERS_CONFIG_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "periph/timer.h"
|
|
#include "cpu.h"
|
|
#if TEST_XTIMER
|
|
#include "xtimer.h"
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifndef TIMER_NUMOF
|
|
#error "TIMER_NUMOF not defined!"
|
|
#endif
|
|
|
|
/**
|
|
* @brief Timer under test (TUT)
|
|
*/
|
|
#ifndef TIM_TEST_DEV
|
|
#define TIM_TEST_DEV (TIMER_DEV(0))
|
|
#endif
|
|
#ifndef TIM_TEST_FREQ
|
|
#define TIM_TEST_FREQ 1000000ul
|
|
#endif
|
|
#ifndef TIM_TEST_CHAN
|
|
#define TIM_TEST_CHAN 0
|
|
#endif
|
|
|
|
/* Use separate reference timer to compare against */
|
|
#ifndef USE_REFERENCE
|
|
#define USE_REFERENCE 1
|
|
#endif
|
|
|
|
/* Whether to keep statistics per timer target value, or only totals */
|
|
#ifndef DETAILED_STATS
|
|
#define DETAILED_STATS 1
|
|
#endif
|
|
|
|
/* Group statistics into log2 size buckets, instead of one record per timer target
|
|
* i.e. 1, 2, 3-4, 5-8, 9-16, 17-32 etc. */
|
|
/* Only used if DETAILED_STATS is 1 */
|
|
#ifndef LOG2_STATS
|
|
#define LOG2_STATS 1
|
|
#endif
|
|
|
|
/* Margin to ensure that the rescheduling timer never is hit */
|
|
#ifndef RESCHEDULE_MARGIN
|
|
#define RESCHEDULE_MARGIN (SPIN_MAX_TARGET * 16)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Reference timer to compare against
|
|
*/
|
|
#ifndef TIM_REF_DEV
|
|
/* Avoid using the timer under test as reference */
|
|
#if ((TIM_TEST_DEV) == (TIMER_DEV(0)))
|
|
#define TIM_REF_DEV (TIMER_DEV(1))
|
|
#else
|
|
#define TIM_REF_DEV (TIMER_DEV(0))
|
|
#endif
|
|
#endif
|
|
#ifndef TIM_REF_FREQ
|
|
#define TIM_REF_FREQ 1000000ul
|
|
#endif
|
|
|
|
#if !USE_REFERENCE
|
|
#undef TIM_REF_DEV
|
|
#undef TIM_REF_FREQ
|
|
#undef TIM_TEST_TO_REF
|
|
#define TIM_REF_DEV TIM_TEST_DEV
|
|
#define TIM_REF_FREQ TIM_TEST_FREQ
|
|
#define TIM_TEST_TO_REF(x) (x)
|
|
#endif
|
|
|
|
/* Longest timer timeout tested (TUT ticks)*/
|
|
/* Reduce this if RAM usage is too high */
|
|
#ifndef TEST_MAX
|
|
#define TEST_MAX 128
|
|
#endif
|
|
/* Shortest timer timeout tested (TUT ticks) */
|
|
#ifndef TEST_MIN
|
|
#if TEST_XTIMER
|
|
/* Default minimum delay for xtimer */
|
|
#define TEST_MIN (XTIMER_ISR_BACKOFF)
|
|
#elif TIM_TEST_FREQ < 100000
|
|
/* this usually works for slow timers */
|
|
#define TEST_MIN 1
|
|
#else
|
|
/* avoid problems with timer_set_absolute setting a time in the past because of
|
|
* processing delays */
|
|
#define TEST_MIN 16
|
|
#endif
|
|
#endif
|
|
/* Minimum delay for relative timers, should usually work with any value */
|
|
#ifndef TEST_MIN_REL
|
|
#if TEST_XTIMER
|
|
#define TEST_MIN_REL (TEST_MIN)
|
|
#else
|
|
#define TEST_MIN_REL (0)
|
|
#endif
|
|
#endif
|
|
/* Number of test values */
|
|
#define TEST_NUM ((TEST_MAX) - (TEST_MIN) + 1)
|
|
/* 2-logarithm of TEST_NUM, not possible to compute automatically by the
|
|
* preprocessor unless comparing values like this */
|
|
#if TEST_NUM <= (1 << 2)
|
|
#define TEST_LOG2NUM 2
|
|
#elif TEST_NUM <= (1 << 3)
|
|
#define TEST_LOG2NUM 3
|
|
#elif TEST_NUM <= (1 << 4)
|
|
#define TEST_LOG2NUM 4
|
|
#elif TEST_NUM <= (1 << 5)
|
|
#define TEST_LOG2NUM 5
|
|
#elif TEST_NUM <= (1 << 6)
|
|
#define TEST_LOG2NUM 6
|
|
#elif TEST_NUM <= (1 << 7)
|
|
#define TEST_LOG2NUM 7
|
|
#elif TEST_NUM <= (1 << 8)
|
|
#define TEST_LOG2NUM 8
|
|
#elif TEST_NUM <= (1 << 9)
|
|
#define TEST_LOG2NUM 9
|
|
#elif TEST_NUM <= (1 << 10)
|
|
#define TEST_LOG2NUM 10
|
|
#elif TEST_NUM <= (1 << 11)
|
|
#define TEST_LOG2NUM 11
|
|
#elif TEST_NUM <= (1 << 12)
|
|
#define TEST_LOG2NUM 12
|
|
#elif TEST_NUM <= (1 << 13)
|
|
#define TEST_LOG2NUM 13
|
|
#elif TEST_NUM <= (1 << 14)
|
|
#define TEST_LOG2NUM 14
|
|
#elif TEST_NUM <= (1 << 15)
|
|
#define TEST_LOG2NUM 15
|
|
#elif TEST_NUM <= (1 << 16)
|
|
#define TEST_LOG2NUM 16
|
|
#elif TEST_NUM <= (1 << 20)
|
|
#define TEST_LOG2NUM 20
|
|
#elif TEST_NUM <= (1 << 24)
|
|
#define TEST_LOG2NUM 24
|
|
#else
|
|
#define TEST_LOG2NUM 32
|
|
#endif
|
|
|
|
/* convert TUT ticks to reference ticks */
|
|
/* x is expected to be < 2**16 */
|
|
#ifndef TIM_TEST_TO_REF
|
|
#if (TIM_TEST_FREQ == TIM_REF_FREQ)
|
|
#define TIM_TEST_TO_REF(x) (x)
|
|
#elif (TIM_TEST_FREQ == 32768ul) && (TIM_REF_FREQ == 1000000ul)
|
|
#define TIM_TEST_TO_REF(x) (((uint32_t)(x) * 15625ul) >> 9)
|
|
#elif (TIM_TEST_FREQ == 1000000ul) && (TIM_REF_FREQ == 32768ul)
|
|
#define TIM_TEST_TO_REF(x) (div_u32_by_15625div512(x))
|
|
/* General conversion for Timer with 2^x factor */
|
|
#elif (TIM_TEST_FREQ < TIM_REF_FREQ ) && ((TIM_REF_FREQ % TIM_TEST_FREQ) == 0)
|
|
#ifndef TIM_TEST_TO_REF_SHIFT
|
|
#if ((TIM_REF_FREQ >> 1) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 1
|
|
#elif ((TIM_REF_FREQ >> 2) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 2
|
|
#elif ((TIM_REF_FREQ >> 3) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 3
|
|
#elif ((TIM_REF_FREQ >> 4) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 4
|
|
#elif ((TIM_REF_FREQ >> 5) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 5
|
|
#elif ((TIM_REF_FREQ >> 6) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 6
|
|
#elif ((TIM_REF_FREQ >> 7) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 7
|
|
#elif ((TIM_REF_FREQ >> 8) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 8
|
|
#elif ((TIM_REF_FREQ >> 9) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 9
|
|
#elif ((TIM_REF_FREQ >> 10) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 10
|
|
#elif ((TIM_REF_FREQ >> 11) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 11
|
|
#elif ((TIM_REF_FREQ >> 12) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 12
|
|
#elif ((TIM_REF_FREQ >> 13) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 13
|
|
#elif ((TIM_REF_FREQ >> 14) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 14
|
|
#elif ((TIM_REF_FREQ >> 15) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 15
|
|
#elif ((TIM_REF_FREQ >> 16) == TIM_TEST_FREQ)
|
|
#define TIM_TEST_TO_REF_SHIFT 16
|
|
#else
|
|
#error define TIM_TEST_TO_REF_SHIFT so that TIM_REF_FREQ == (TIM_TEST_FREQ << TIM_TEST_FREQ_SHIFT)
|
|
#endif
|
|
#endif
|
|
#define TIM_TEST_TO_REF(x) ((uint32_t)(x) << (TIM_TEST_TO_REF_SHIFT))
|
|
#else
|
|
#error define TIM_TEST_TO_REF so that TIM_REF_FREQ == TIM_TEST_TO_REF(TIM_TEST_FREQ)
|
|
#endif
|
|
#endif
|
|
|
|
/* Print results every X reference ticks */
|
|
#ifndef TEST_PRINT_INTERVAL_TICKS
|
|
#define TEST_PRINT_INTERVAL_TICKS ((TIM_REF_FREQ) * 30)
|
|
#endif
|
|
|
|
/* If variance or mean exceeds these values the row will be marked with a "SIC!"
|
|
* in the table output */
|
|
#ifndef TEST_UNEXPECTED_STDDEV
|
|
#define TEST_UNEXPECTED_STDDEV 4
|
|
#endif
|
|
#ifndef TEST_UNEXPECTED_MEAN
|
|
#define TEST_UNEXPECTED_MEAN 10
|
|
#endif
|
|
|
|
/* The spin calibration will try to set spin_limit to a number of loop
|
|
* iterations which correspond to this many TUT ticks */
|
|
#ifndef SPIN_MAX_TARGET
|
|
#define SPIN_MAX_TARGET 16
|
|
#endif
|
|
|
|
/* estimate_cpu_overhead will loop for this many iterations to get a proper estimate */
|
|
#define ESTIMATE_CPU_ITERATIONS 2048
|
|
|
|
#if TEST_XTIMER
|
|
#define READ_TUT() _xtimer_now()
|
|
#else
|
|
#define READ_TUT() timer_read(TIM_TEST_DEV)
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* BENCH_TIMERS_CONFIG_H */
|