-
Notifications
You must be signed in to change notification settings - Fork 2.1k
sys/ztimer: make use of periph_timer_query_freqs #20582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/ztimer: make use of periph_timer_query_freqs #20582
Conversation
6d3abf6
to
4933b9b
Compare
Freeze is over so if anyone wants to pick this up... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately I don't have an MSP430 board, so I tested it with an P-Nucleo-WB55
and nRF52840DK
. The tests/sys/ztimer_msg
tests ran fine on both, so I assume nothing broke?
sys/ztimer/init.c
Outdated
@@ -337,17 +342,21 @@ void ztimer_init(void) | |||
#if MODULE_ZTIMER_USEC | |||
# if ZTIMER_TIMER_FREQ != FREQ_1MHZ | |||
# if ZTIMER_TIMER_FREQ == FREQ_250KHZ | |||
/* 250 kHz ± 5% */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just so that I understand: the +-5% is after searching for a better frequency, right?
Some microcontrollers (the nRF52) report only 10 different frequencies in the tests/periph/timer
test:
main(): This is RIOT! (Version: 2024.07-devel-15-g4933b-ztimer_periph_timer_query_freqs)
Test for peripheral TIMERs
Available timers: 4
TIMER 0
=======
- supported frequencies:
0: 16000000
1: 8000000
2: 4000000
....
9: 31250
Testing timer_get_closest_freq()...
[OK]
Testing timer_query_freqs() for out of bound index...
[OK]
...
Of course it doesn't make any sense to run an nRF52840 without crystal, but my point is that some microcontrollers might exist without fine enough granularity and therefore these asserts might fail.
I don't understand the intricacies of ztimer
enough, so I leave it to you to judge this, so just consider this food for thought :)
Just tried that test on |
The python script checks the time between the messages. It is relatively lax (as measuring the time between two stdio messages is not super precise), but it does fail when the clock is off by too much. At least that was the case back then. The Z1 does indeed use the DCO, but it is using an MSP430F2xx MCU, which has the better clock system. I think the clock calibration on start-up may actually be "good enough" on that board. On the MSP430F1xx, the DCO often maxes out at about 5 MHz, unless an external resistor is supplied. If the nominal CPU clock is 8 MHz and the actual one is at about 5 MHz, the offset is large enough for the test to fail. |
I've rebased this branch on master and tested with $ VERBOSE_ASSERT=1 BUILD_IN_DOCKER=1 make -C tests/sys/ztimer_msg BOARD=telosb flash test
...
sys/ztimer/init.c:359 => FAILED ASSERTION. (on |
This has to rebased after #20581 was merged. |
That is both good and bad:
I'll improve the test and convert the |
31f783a
to
482538c
Compare
This makes use of the `periph_timer_query_freqs` feature: 1. It does choose the closest frequency supported before calling timer_init() in the ztimer_periph_timer backend. 2. It does make use of the actually chosen frequency when using `ztimer_convert_frac`. 3. It does `assert()` the frequency is within 5% of the specified when no frequency conversion is performed or `ztimer_convert_shift_up` is used.
Adding a ztimer configuration that forces the use of frequency conversion will greatly improve timing accuracy, as the frequency detected at runtime will just be too much off from the nominal 1 MHz to run without frequency conversion.
482538c
to
28466c0
Compare
28466c0
to
3189003
Compare
89f20e8
to
b42d7bf
Compare
This updates the `Makefile.ci` entries for all MSP430 boards plus a few low end Cortex-M boards.
b42d7bf
to
c05d546
Compare
Thx a lot :) |
Contribution description
This makes use of the
periph_timer_query_freqs
feature:ztimer_convert_frac
.assert()
the frequency is within 5% of the specified when no frequency conversion is performed orztimer_convert_shift_up
is used.Motivation
We have a number of MCUs that can run from internal oscillators (without using external crystal for accuracy):
periph_timer
, so not relevant here)If those MCUs are used without external crystal, the actual CPU frequency may be off from what the the board config aims for significantly due to large production variance and temperature and supply voltage dependence. As a result, all
periph_timer
instances driven by the same clock will also be off significantly, which can hinder accuracy in time keeping significantly.This adds the support to ztimer to react on the actual frequency information provided by
periph_timer_query_freqs
and adjust the time keeping accordingly.Testing procedure
As of now, only the MSP430 (and the FE310) will measure the actual CPU frequency at runtime, and only the MSP430 timer will compensate frequencies exposed via
timer_query_freqs()
. So only on MSP430 this can really be tested now, e.g. withtests/sys/ztimer_msg
.In
master
this test sadly fails because oftimer_set()
not yet working correctly on small timeouts (and waiting one period longer than needed).With this PR the test passes and the messages at second 30 is indeed about thirty seconds after the start message received. (It would be off by 40 % without compensation.)
Issues/PRs references
timer_get_closest_freq()
#20581Fixes #8251