mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/ztimer: add auto_adjust module
This commit is contained in:
parent
2005ba53f5
commit
d758cb93ef
@ -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
|
||||
|
@ -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
|
||||
|
@ -160,6 +160,17 @@ extern "C" {
|
||||
#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
|
||||
|
@ -31,9 +31,9 @@ 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.
|
||||
*
|
||||
@ -41,7 +41,18 @@ extern "C" {
|
||||
* @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 */
|
||||
/** @} */
|
||||
|
@ -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()"
|
||||
|
||||
|
@ -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"
|
||||
@ -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 */
|
||||
@ -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
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user