Skip to content

Commit 28628d1

Browse files
committed
[nrf fromlist] tests: kernel: timer: timer_api: Add runtime slew rate detection
Instead of fixing at compile time the difference between clocks that runs k_busy_wait and system clock use runtime estimation. Upstream PR #: 87944 Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent c1464b9 commit 28628d1

File tree

1 file changed

+31
-16
lines changed
  • tests/kernel/timer/timer_api/src

1 file changed

+31
-16
lines changed

tests/kernel/timer/timer_api/src/main.c

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ struct timer_data {
1212
int expire_cnt;
1313
int stop_cnt;
1414
int64_t timestamp;
15+
int slew_ppm;
1516
};
1617

1718
#define DURATION 100
@@ -28,15 +29,6 @@ struct timer_data {
2829
*/
2930
#define INEXACT_MS_CONVERT ((CONFIG_SYS_CLOCK_TICKS_PER_SEC % MSEC_PER_SEC) != 0)
3031

31-
#if CONFIG_NRF_RTC_TIMER
32-
/* On Nordic SOCs one or both of the tick and busy-wait clocks may
33-
* derive from sources that have slews that sum to +/- 13%.
34-
*/
35-
#define BUSY_TICK_SLEW_PPM 130000U
36-
#else
37-
/* On other platforms assume the clocks are perfectly aligned. */
38-
#define BUSY_TICK_SLEW_PPM 0U
39-
#endif
4032
#define PPM_DIVISOR 1000000U
4133

4234
/* If the tick clock is faster or slower than the busywait clock the
@@ -45,8 +37,8 @@ struct timer_data {
4537
* between the two clocks. Produce a maximum error for a given
4638
* duration in microseconds.
4739
*/
48-
#define BUSY_SLEW_THRESHOLD_TICKS(_us) \
49-
k_us_to_ticks_ceil32((_us) * (uint64_t)BUSY_TICK_SLEW_PPM \
40+
#define BUSY_SLEW_THRESHOLD_TICKS(_us, slew_ppm) \
41+
k_us_to_ticks_ceil32((_us) * (uint64_t)slew_ppm \
5042
/ PPM_DIVISOR)
5143

5244
static void duration_expire(struct k_timer *timer);
@@ -253,8 +245,8 @@ ZTEST_USER(timer_api, test_timer_period_0)
253245
/** TESTPOINT: set period 0 */
254246
k_timer_start(&period0_timer,
255247
K_TICKS(k_ms_to_ticks_floor32(DURATION)
256-
- BUSY_SLEW_THRESHOLD_TICKS(DURATION
257-
* USEC_PER_MSEC)),
248+
- BUSY_SLEW_THRESHOLD_TICKS(DURATION * USEC_PER_MSEC,
249+
tdata.slew_ppm)),
258250
K_NO_WAIT);
259251
/* Need to wait at least 2 durations to ensure one-shot behavior. */
260252
busy_wait_ms(2 * DURATION + 1);
@@ -291,7 +283,7 @@ ZTEST_USER(timer_api, test_timer_period_k_forever)
291283
k_timer_start(
292284
&period0_timer,
293285
K_TICKS(k_ms_to_ticks_floor32(DURATION) -
294-
BUSY_SLEW_THRESHOLD_TICKS(DURATION * USEC_PER_MSEC)),
286+
BUSY_SLEW_THRESHOLD_TICKS(DURATION * USEC_PER_MSEC, tdata.slew_ppm)),
295287
K_FOREVER);
296288
tdata.timestamp = k_uptime_get();
297289

@@ -648,7 +640,7 @@ ZTEST_USER(timer_api, test_timer_user_data)
648640
} else {
649641
uint32_t wait_us = 1000 * wait_ms;
650642

651-
k_busy_wait(wait_us + (wait_us * BUSY_TICK_SLEW_PPM) / PPM_DIVISOR);
643+
k_busy_wait(wait_us + (wait_us * tdata.slew_ppm) / PPM_DIVISOR);
652644
}
653645

654646
for (ii = 0; ii < 5; ii++) {
@@ -722,7 +714,9 @@ ZTEST_USER(timer_api, test_timer_remaining)
722714
* skew.
723715
*/
724716
delta_ticks = (int32_t)(rem_ticks - target_rem_ticks);
725-
slew_ticks = BUSY_SLEW_THRESHOLD_TICKS(DURATION * USEC_PER_MSEC / 2U);
717+
slew_ticks = BUSY_SLEW_THRESHOLD_TICKS(DURATION * USEC_PER_MSEC / 2U, tdata.slew_ppm);
718+
printk("slew_ticks:%d delta:%d latency:%d\n",
719+
slew_ticks, delta_ticks, latency_ticks);
726720
zassert_true(abs(delta_ticks) <= MAX(slew_ticks, latency_ticks),
727721
"tick/busy slew %d larger than test threshold %u",
728722
delta_ticks, slew_ticks);
@@ -857,8 +851,29 @@ static void timer_init(struct k_timer *timer, k_timer_expiry_t expiry_fn,
857851
k_timer_init(timer, expiry_fn, stop_fn);
858852
}
859853

854+
static uint32_t slew_estimate(void)
855+
{
856+
uint32_t now = k_cycle_get_32();
857+
uint32_t t;
858+
int diff;
859+
860+
/* Compare 10 ms measured by system clock and k_busy_wait and calculate
861+
* the difference. It is used later on in tests.
862+
*/
863+
k_busy_wait(10000);
864+
now = k_cycle_get_32() - now;
865+
t = k_cyc_to_us_floor32(now);
866+
867+
diff = 10000 - t;
868+
diff = diff < 0 ? -diff : diff;
869+
870+
return diff * 100;
871+
}
872+
860873
void *setup_timer_api(void)
861874
{
875+
tdata.slew_ppm = slew_estimate();
876+
862877
timer_init(&duration_timer, duration_expire, duration_stop);
863878
timer_init(&period0_timer, period0_expire, NULL);
864879
timer_init(&expire_timer, NULL, duration_stop);

0 commit comments

Comments
 (0)