From d23dd56692c6cff65480fbed286362889c96c7ba Mon Sep 17 00:00:00 2001 From: xqyjlj Date: Wed, 26 Jul 2023 14:48:00 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20fix(ktime):=20fix=20wrong=20boot?= =?UTF-8?q?time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 因为tick从中断到设置中间的时延特别大,因此暂不采用tick做基准时间,直接取gtime的cnt做基准时间 --- components/ktime/inc/ktime.h | 6 +++++ components/ktime/src/aarch64/cputimer.c | 9 ++++++- components/ktime/src/boottime.c | 27 +++++++++---------- components/ktime/src/cputimer.c | 5 ++++ components/ktime/src/risc-v/virt64/cputimer.c | 9 ++++++- libcpu/aarch64/common/gtimer.c | 7 +++++ libcpu/risc-v/virt64/tick.c | 7 +++++ 7 files changed, 53 insertions(+), 17 deletions(-) diff --git a/components/ktime/inc/ktime.h b/components/ktime/inc/ktime.h index 86fbefd0bb..891da999bc 100644 --- a/components/ktime/inc/ktime.h +++ b/components/ktime/inc/ktime.h @@ -82,6 +82,12 @@ unsigned long rt_ktime_cputimer_getcnt(void); */ unsigned long rt_ktime_cputimer_getstep(void); +/** + * @brief Init cputimer + * + */ +void rt_ktime_cputimer_init(void); + /** * @brief Get hrtimer resolution * diff --git a/components/ktime/src/aarch64/cputimer.c b/components/ktime/src/aarch64/cputimer.c index 53c60736d4..cc1c5255e9 100644 --- a/components/ktime/src/aarch64/cputimer.c +++ b/components/ktime/src/aarch64/cputimer.c @@ -11,6 +11,8 @@ #include "gtimer.h" #include "ktime.h" +static volatile unsigned long _init_cnt = 0; + unsigned long rt_ktime_cputimer_getres(void) { return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / rt_hw_get_gtimer_frq(); @@ -23,10 +25,15 @@ unsigned long rt_ktime_cputimer_getfrq(void) unsigned long rt_ktime_cputimer_getcnt(void) { - return rt_hw_get_cntpct_val(); + return rt_hw_get_cntpct_val() - _init_cnt; } unsigned long rt_ktime_cputimer_getstep(void) { return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND; } + +void rt_ktime_cputimer_init(void) +{ + _init_cnt = rt_hw_get_cntpct_val(); +} diff --git a/components/ktime/src/boottime.c b/components/ktime/src/boottime.c index 9d05266d71..d380cd7e93 100644 --- a/components/ktime/src/boottime.c +++ b/components/ktime/src/boottime.c @@ -12,40 +12,37 @@ #define __KTIME_MUL ((1000UL * 1000 * 1000) / RT_TICK_PER_SECOND) -rt_err_t rt_ktime_boottime_get_us(struct timeval *tv) +rt_weak rt_err_t rt_ktime_boottime_get_us(struct timeval *tv) { RT_ASSERT(tv != RT_NULL); - rt_tick_t ms = rt_tick_get(); - unsigned long ns = - ((rt_ktime_cputimer_getcnt() % rt_ktime_cputimer_getstep()) * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL; - ns = ((ms % RT_TICK_PER_SECOND) * __KTIME_MUL) + ns; + unsigned long ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL; - tv->tv_sec = ms / RT_TICK_PER_SECOND; - tv->tv_usec = ns / 1000; + tv->tv_sec = ns / (1000UL * 1000 * 1000); + tv->tv_usec = (ns % (1000UL * 1000 * 1000)) / 1000; return RT_EOK; } -rt_err_t rt_ktime_boottime_get_s(time_t *t) +rt_weak rt_err_t rt_ktime_boottime_get_s(time_t *t) { RT_ASSERT(t != RT_NULL); - *t = rt_tick_get() / RT_TICK_PER_SECOND; + unsigned long ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL; + + *t = ns / (1000UL * 1000 * 1000); return RT_EOK; } -rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts) +rt_weak rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts) { RT_ASSERT(ts != RT_NULL); - rt_tick_t ms = rt_tick_get(); - unsigned long ns = - ((rt_ktime_cputimer_getcnt() % rt_ktime_cputimer_getstep()) * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL; + unsigned long ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL; - ts->tv_sec = ms / RT_TICK_PER_SECOND; - ts->tv_nsec = ((ms % RT_TICK_PER_SECOND) * __KTIME_MUL) + ns; + ts->tv_sec = ns / (1000UL * 1000 * 1000); + ts->tv_nsec = ns % (1000UL * 1000 * 1000); return RT_EOK; } diff --git a/components/ktime/src/cputimer.c b/components/ktime/src/cputimer.c index c878581cdf..f182be894c 100644 --- a/components/ktime/src/cputimer.c +++ b/components/ktime/src/cputimer.c @@ -29,3 +29,8 @@ rt_weak unsigned long rt_ktime_cputimer_getstep(void) { return 1; } + +rt_weak void rt_ktime_cputimer_init(void) +{ + return; +} diff --git a/components/ktime/src/risc-v/virt64/cputimer.c b/components/ktime/src/risc-v/virt64/cputimer.c index 9b0f754751..bbc7576c5e 100644 --- a/components/ktime/src/risc-v/virt64/cputimer.c +++ b/components/ktime/src/risc-v/virt64/cputimer.c @@ -10,6 +10,8 @@ #include "ktime.h" +static volatile unsigned long _init_cnt = 0; + unsigned long rt_ktime_cputimer_getres(void) { return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / CPUTIME_TIMER_FREQ; @@ -24,10 +26,15 @@ unsigned long rt_ktime_cputimer_getcnt(void) { unsigned long time_elapsed; __asm__ __volatile__("rdtime %0" : "=r"(time_elapsed)); - return time_elapsed; + return time_elapsed - _init_cnt; } unsigned long rt_ktime_cputimer_getstep(void) { return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND; } + +void rt_ktime_cputimer_init(void) +{ + __asm__ __volatile__("rdtime %0" : "=r"(_init_cnt)); +} diff --git a/libcpu/aarch64/common/gtimer.c b/libcpu/aarch64/common/gtimer.c index 881655c2cf..514ec4e043 100644 --- a/libcpu/aarch64/common/gtimer.c +++ b/libcpu/aarch64/common/gtimer.c @@ -13,6 +13,10 @@ #include #include +#ifdef RT_USING_KTIME +#include +#endif + #define EL1_PHY_TIMER_IRQ_NUM 30 static volatile rt_uint64_t timer_step; @@ -38,6 +42,9 @@ void rt_hw_gtimer_local_enable(void) rt_hw_gtimer_disable(); rt_hw_set_gtimer_val(timer_step); rt_hw_interrupt_umask(EL1_PHY_TIMER_IRQ_NUM); +#ifdef RT_USING_KTIME + rt_ktime_cputimer_init(); +#endif rt_hw_gtimer_enable(); } diff --git a/libcpu/risc-v/virt64/tick.c b/libcpu/risc-v/virt64/tick.c index cd628f0835..3dd9af48a3 100644 --- a/libcpu/risc-v/virt64/tick.c +++ b/libcpu/risc-v/virt64/tick.c @@ -14,6 +14,10 @@ #include #include "sbi.h" +#ifdef RT_USING_KTIME +#include +#endif + static volatile uint64_t time_elapsed = 0; static volatile unsigned long tick_cycles = 0; @@ -49,6 +53,9 @@ int rt_hw_tick_init(void) /* Set timer */ sbi_set_timer(get_ticks() + tick_cycles); +#ifdef RT_USING_KTIME + rt_ktime_cputimer_init(); +#endif /* Enable the Supervisor-Timer bit in SIE */ set_csr(sie, SIP_STIP);