Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 10 additions & 0 deletions boards/arduino-uno/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
#ifndef BOARD_H
#define BOARD_H

/**
* @name ztimer configuration values
*
* @note Overrides arduino-atmega defaults
* @{
*/
#define CONFIG_ZTIMER_USEC_ADJUST_SET (128)
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP (116)
/** @} */

#include "board_common.h"

#ifdef __cplusplus
Expand Down
4 changes: 2 additions & 2 deletions boards/atmega256rfr2-xpro/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ extern "C" {
* @name ztimer configuration values
* @{
*/
#define CONFIG_ZTIMER_USEC_ADJUST_SET (128)
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP (128)
#define CONFIG_ZTIMER_USEC_ADJUST_SET (132)
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP (120)
/** @} */

/**
Expand Down
8 changes: 6 additions & 2 deletions boards/common/arduino-atmega/include/board_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,12 @@ extern "C" {
#define CONFIG_ZTIMER_USEC_DEV (TIMER_DEV(0))
#define CONFIG_ZTIMER_USEC_FREQ (250000LU)
#define CONFIG_ZTIMER_USEC_WIDTH (16)
#define CONFIG_ZTIMER_USEC_ADJUST_SET (124)
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP (120)
#ifndef CONFIG_ZTIMER_USEC_ADJUST_SET
#define CONFIG_ZTIMER_USEC_ADJUST_SET (128)
#endif
#ifndef CONFIG_ZTIMER_USEC_ADJUST_SLEEP
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP (116)
#endif
/** @} */

/**
Expand Down
2 changes: 2 additions & 0 deletions dist/tools/doccheck/exclude_patterns
Original file line number Diff line number Diff line change
Expand Up @@ -14707,3 +14707,5 @@ drivers/ft5x06/include/ft5x06_constants\.h:[0-9]+: warning: Member FT5X06_G_MODE
drivers/ft5x06/include/ft5x06_constants\.h:[0-9]+: warning: Member FT5X06_G_MODE_INTERRUPT_POLLING \(macro definition\) of file ft5x06_constants\.h is not documented\.
drivers/ft5x06/include/ft5x06_constants\.h:[0-9]+: warning: Member FT5X06_G_MODE_INTERRUPT_TRIGGER \(macro definition\) of file ft5x06_constants\.h is not documented\.
drivers/ft5x06/include/ft5x06_params\.h:[0-9]+: warning: Member FT5X06_PARAM_TYPE \(macro definition\) of file ft5x06_params\.h is not documented\.
boards/arduino\-uno/include/board\.h:[0-9]+: warning: Member CONFIG_ZTIMER_USEC_ADJUST_SET \(macro definition\) of file board\.h is not documented\.
boards/arduino\-uno/include/board\.h:[0-9]+: warning: Member CONFIG_ZTIMER_USEC_ADJUST_SLEEP \(macro definition\) of file board\.h is not documented\.
4 changes: 4 additions & 0 deletions makefiles/default_modules.deps.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ ifneq (,$(filter auto_init_ztimer,$(USEMODULE)))
USEMODULE += ztimer_init
endif

ifneq (,$(filter ztimer_auto_adjust,$(USEMODULE)))
USEMODULE += ztimer_overhead
endif

ifneq (,$(filter auto_init_saul,$(USEMODULE)))
USEMODULE += saul_init_devs
endif
14 changes: 14 additions & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,20 @@ PSEUDOMODULES += ztimer
PSEUDOMODULES += ztimer_%
PSEUDOMODULES += ztimer64_%

## @defgroup pseudomodule_ztimer_auto_adjust ztimer_auto_adjust
## @brief A module to set on init ztimer->adjust_sleep/adjust_set values
##
## When this module is active, then on init if no CONFIG_ZTIMER_USEC_ADJUST_%
## values are set for the BOARD correction values adjust_sleep and adjust_set
## will be calculated in set for the required clocks.
##
## Note that some BOARDs clocks require a startup time to get accuarate values,
## a configurable @ref CONFIG_ZTIMER_AUTO_ADJUST_SETTLE value can be set for this.
##
## Alternatively CONFIG_ZTIMER_USEC_ADJUST_% values can be set in the BOARDs
## configuration header board.h. These can be found out by running tests/ztimer_overhead
PSEUDOMODULES += ztimer_auto_adjust

# ztimer's main module is called "ztimer_core"
NO_PSEUDOMODULES += ztimer_core
NO_PSEUDOMODULES += netdev_ieee802154_submac
Expand Down
35 changes: 35 additions & 0 deletions sys/include/ztimer/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,41 @@ extern "C" {
# endif
#endif

/**
* @brief An offset for ZTIMER_USEC allowing to compensate for the offset
* of @ref ztimer_set(). It can be measured with @ref ztimer_overhead_set()
*
* This value should be configured in the board.h.
*
*/
#ifndef CONFIG_ZTIMER_USEC_ADJUST_SET
#define CONFIG_ZTIMER_USEC_ADJUST_SET 0
#endif

/**
* @brief An offset for ZTIMER_USEC allowing to compentsate for the offset
* of @ref ztimer_sleep().
*
* @note As internally @ref ztimer_sleep() uses @ref ztimer_set()
* @ref CONFIG_ZTIMER_USEC_ADJUST_SET should be tuned before.
*
* This value should be configured in the board.h.
*/
#ifndef CONFIG_ZTIMER_USEC_ADJUST_SLEEP
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP 0
#endif

/**
* @brief Some MCUs clocks need some warm-up time during which timing is
* inaccurate. This can be a hindrance when using the @ref
* pseudomodule_ztimer_auto_adjust module.
*
* @warning This value will increase the boards start-up time
*/
#ifndef CONFIG_ZTIMER_AUTO_ADJUST_SETTLE
#define CONFIG_ZTIMER_AUTO_ADJUST_SETTLE 0
#endif

#ifdef __cplusplus
}
#endif
Expand Down
17 changes: 14 additions & 3 deletions sys/include/ztimer/overhead.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,28 @@ extern "C" {
#endif

/**
* @brief Measure ztimer overhead
* @brief Measure overhead for ztimer_set()
*
* This function can be used to measure the overhead incurred by ztimer.
* This function can be used to measure the overhead incurred by ztimer_set().
* It will configure a callback to trigger after @p base ticks, then return the
* number of ticks that have passed, minus @p base.
*
* @param[in] clock ztimer clock to operate on
* @param[in] base base interval to use
* @return (time from ztimer_set() until callback) - base
*/
int32_t ztimer_overhead(ztimer_clock_t *clock, uint32_t base);
int32_t ztimer_overhead_set(ztimer_clock_t *clock, uint32_t base);

/**
* @brief Measure overhead for ztimer_sleep()
*
* This function can be used to measure the overhead incurred by ztimer_sleep().
*
* @param[in] clock ztimer clock to operate on
* @param[in] base base interval to use
* @return (time(ztimer_sleep(base))) - base
*/
int32_t ztimer_overhead_sleep(ztimer_clock_t *clock, uint32_t base);

#endif /* ZTIMER_OVERHEAD_H */
/** @} */
4 changes: 4 additions & 0 deletions sys/ztimer/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ config MODULE_AUTO_INIT_ZTIMER
select MODULE_ZTIMER_INIT
default y

config MODULE_ZTIMER_AUTO_ADJUST
bool "Auto adjust ztimer set and sleep values"
select MODULE_ZTIMER_OVERHEAD

config MODULE_ZTIMER_NOW64
bool "Use a 64-bits result for ztimer_now()"

Expand Down
70 changes: 60 additions & 10 deletions sys/ztimer/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "ztimer/convert_frac.h"
#include "ztimer/convert_shift.h"
#include "ztimer/convert_muldiv64.h"
#include "ztimer/overhead.h"
#include "ztimer/periph_timer.h"
#include "ztimer/periph_rtt.h"
#include "ztimer/periph_rtc.h"
Expand Down Expand Up @@ -212,6 +213,29 @@ ztimer_clock_t *const ZTIMER_SEC = &_ztimer_convert_frac_sec.super.super;
# endif
#endif

#if IS_USED(MODULE_ZTIMER_USEC)
#ifndef CONFIG_ZTIMER_AUTO_ADJUST_BASE_ITVL
#define CONFIG_ZTIMER_AUTO_ADJUST_BASE_ITVL 1000
#endif
#ifndef CONFIG_ZTIMER_AUTO_ADJUST_ITER
#define CONFIG_ZTIMER_AUTO_ADJUST_ITER 100
#endif

static void _ztimer_usec_overhead(unsigned samples, unsigned base, uint16_t *adjust_value,
int32_t (*overhead_fn)(ztimer_clock_t *clock, uint32_t base))
{
int32_t min = INT32_MAX;

for (unsigned i = 0; i < samples; i++) {
int32_t overhead = overhead_fn(ZTIMER_USEC, base);
if (overhead < min) {
min = overhead;
}
}
*adjust_value = min;
}
#endif

void ztimer_init(void)
{
/* Step 4: initialize used ztimer-periphery */
Expand Down Expand Up @@ -266,16 +290,42 @@ void ztimer_init(void)
# else
LOG_DEBUG("ztimer_init(): ZTIMER_USEC without conversion\n");
# endif
# ifdef CONFIG_ZTIMER_USEC_ADJUST_SET
LOG_DEBUG("ztimer_init(): ZTIMER_USEC setting adjust_set value to %i\n",
CONFIG_ZTIMER_USEC_ADJUST_SET );
ZTIMER_USEC->adjust_set = CONFIG_ZTIMER_USEC_ADJUST_SET;
# endif
# ifdef CONFIG_ZTIMER_USEC_ADJUST_SLEEP
LOG_DEBUG("ztimer_init(): ZTIMER_USEC setting adjust_sleep value to %i\n",
CONFIG_ZTIMER_USEC_ADJUST_SLEEP );
ZTIMER_USEC->adjust_sleep = CONFIG_ZTIMER_USEC_ADJUST_SLEEP;
# endif

/* warm-up time if set and needed */
if (IS_USED(MODULE_ZTIMER_AUTO_ADJUST) &&
!(CONFIG_ZTIMER_USEC_ADJUST_SET && CONFIG_ZTIMER_USEC_ADJUST_SLEEP)) {
if (CONFIG_ZTIMER_AUTO_ADJUST_SETTLE) {
ztimer_sleep(ZTIMER_USEC, CONFIG_ZTIMER_AUTO_ADJUST_SETTLE);
}
}

/* calculate or set 'adjust_set' */
if (CONFIG_ZTIMER_USEC_ADJUST_SET) {
ZTIMER_USEC->adjust_set = CONFIG_ZTIMER_USEC_ADJUST_SET;
}
else if (IS_USED(MODULE_ZTIMER_AUTO_ADJUST)) {
_ztimer_usec_overhead(CONFIG_ZTIMER_AUTO_ADJUST_ITER, CONFIG_ZTIMER_AUTO_ADJUST_BASE_ITVL,
&ZTIMER_USEC->adjust_set, ztimer_overhead_set);
}
if (ZTIMER_USEC->adjust_set) {
LOG_DEBUG("ztimer_init(): ZTIMER_USEC setting adjust_set value to %i\n",
ZTIMER_USEC->adjust_set);
}

/* calculate or set 'adjust_sleep' */
if (CONFIG_ZTIMER_USEC_ADJUST_SLEEP) {
ZTIMER_USEC->adjust_sleep = CONFIG_ZTIMER_USEC_ADJUST_SLEEP;
}
else if (IS_USED(MODULE_ZTIMER_AUTO_ADJUST)) {
_ztimer_usec_overhead(CONFIG_ZTIMER_AUTO_ADJUST_ITER,
CONFIG_ZTIMER_AUTO_ADJUST_BASE_ITVL, &ZTIMER_USEC->adjust_sleep,
ztimer_overhead_sleep);
}

if (ZTIMER_USEC->adjust_sleep) {
LOG_DEBUG("ztimer_init(): ZTIMER_USEC setting adjust_sleep value to %i\n",
ZTIMER_USEC->adjust_sleep);
}
#endif

#if MODULE_ZTIMER_MSEC
Expand Down
12 changes: 11 additions & 1 deletion sys/ztimer/overhead.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static void _callback(void *arg)
*callback_arg->val = ztimer_now(callback_arg->clock);
}

int32_t ztimer_overhead(ztimer_clock_t *clock, uint32_t base)
int32_t ztimer_overhead_set(ztimer_clock_t *clock, uint32_t base)
{
volatile uint32_t after = 0;
uint32_t pre;
Expand All @@ -48,3 +48,13 @@ int32_t ztimer_overhead(ztimer_clock_t *clock, uint32_t base)
while (!after) {}
return after - pre - base;
}

int32_t ztimer_overhead_sleep(ztimer_clock_t *clock, uint32_t base)
{
uint32_t pre = ztimer_now(clock);

ztimer_sleep(clock, base);
uint32_t after = ztimer_now(clock);

return after - pre - base;
}
5 changes: 4 additions & 1 deletion tests/ztimer_overhead/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
DEVELHELP ?= 0

include ../Makefile.tests_common

USEMODULE += ztimer_overhead ztimer_usec
USEMODULE += ztimer_auto_adjust
USEMODULE += ztimer_overhead
USEMODULE += ztimer_usec

include $(RIOTBASE)/Makefile.include
19 changes: 18 additions & 1 deletion tests/ztimer_overhead/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,22 @@
This test application sets up a ztimer_periph at 1MHz, then measures 1024
times how much overhead ztimer adds.

It uses the "ztimer_overhead()" function. See it's documentation for more
It uses the "ztimer_overhead_set()" function. See it's documentation for more
information.

It then sets `adjust_set` parameter and sleeps 1024 times and measure how
much overhead ztimer_sleep adds.

It uses the "ztimer_overhead_sleep()" function. See it's documentation for more
information.

At the end of the test `adjust_set` and `adjust_sleep` values are printed
that can be set for the target `BOARD` in `board.h`.

e.g for dwm1001:

```shell
ZTIMER_USEC adjust params for dwm1001:
CONFIG_ZTIMER_USEC_ADJUST_SET 6
CONFIG_ZTIMER_USEC_ADJUST_SLEEP 21
```
1 change: 1 addition & 0 deletions tests/ztimer_overhead/app.config.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
CONFIG_MODULE_ZTIMER=y
CONFIG_ZTIMER_USEC=y
CONFIG_MODULE_ZTIMER_OVERHEAD=y
CONFIG_MODULE_ZTIMER_AUTO_ADJUST=y
32 changes: 26 additions & 6 deletions tests/ztimer_overhead/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,25 @@
#include <stdlib.h>
#include <inttypes.h>

#include "board.h"
#include "ztimer.h"
#include "ztimer/overhead.h"

#define BASE 1000
#define SAMPLES 1024

int main(void)
static int32_t _ztimer_usec_overhead(unsigned samples, unsigned base,
int32_t (*overhead_fn)(ztimer_clock_t *clock, uint32_t base))
{
uint32_t total = 0;

int32_t min = INT32_MAX;
int32_t max = INT32_MIN;

/* unset configured adjustment */
/* ZTIMER_USEC->adjust_set = 0; */
printf("ZTIMER_USEC->adjust_set = %" PRIu16 "\n", ZTIMER_USEC->adjust_set);
unsigned n = samples;

unsigned n = SAMPLES;
while (n--) {
int32_t overhead = ztimer_overhead(ZTIMER_USEC, BASE);
int32_t overhead = overhead_fn(ZTIMER_USEC, base);
total += labs(overhead);
if (overhead < min) {
min = overhead;
Expand All @@ -55,5 +54,26 @@ int main(void)
printf("min=%" PRIi32 " max=%" PRIi32 " avg_diff=%" PRIi32 "\n", min, max,
(total / SAMPLES));

return min;
}

int main(void)
{
/* unset configured adjustment */
printf("ZTIMER_USEC auto_adjust params:\n");
printf(" ZTIMER_USEC->adjust_set = %" PRIu16 "\n", ZTIMER_USEC->adjust_set);
ZTIMER_USEC->adjust_set = 0;
printf(" ZTIMER_USEC->adjust_sleep = %" PRIu16 "\n", ZTIMER_USEC->adjust_sleep);
ZTIMER_USEC->adjust_sleep = 0;
printf("ZTIMER_USEC auto_adjust params cleared\n");

printf("zitmer_overhead_set...\n");
ZTIMER_USEC->adjust_set = _ztimer_usec_overhead(SAMPLES, BASE, ztimer_overhead_set);
printf("zitmer_overhead_sleep...\n");
ZTIMER_USEC->adjust_sleep = _ztimer_usec_overhead(SAMPLES, BASE, ztimer_overhead_sleep);
printf("ZTIMER_USEC adjust params for %s:\n", RIOT_BOARD);
printf(" CONFIG_ZTIMER_USEC_ADJUST_SET %" PRIi16 "\n", ZTIMER_USEC->adjust_set);
printf(" CONFIG_ZTIMER_USEC_ADJUST_SLEEP %" PRIi16 "\n", ZTIMER_USEC->adjust_sleep);

return 0;
}
Loading