🐞 fix(ktime): fix wrong boottime

因为tick从中断到设置中间的时延特别大,因此暂不采用tick做基准时间,直接取gtime的cnt做基准时间
This commit is contained in:
xqyjlj 2023-07-26 14:48:00 +08:00 committed by guo
parent 0eaa757cff
commit d23dd56692
7 changed files with 53 additions and 17 deletions

View File

@ -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
*

View File

@ -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();
}

View File

@ -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;
}

View File

@ -29,3 +29,8 @@ rt_weak unsigned long rt_ktime_cputimer_getstep(void)
{
return 1;
}
rt_weak void rt_ktime_cputimer_init(void)
{
return;
}

View File

@ -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));
}

View File

@ -13,6 +13,10 @@
#include <gtimer.h>
#include <cpuport.h>
#ifdef RT_USING_KTIME
#include <ktime.h>
#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();
}

View File

@ -14,6 +14,10 @@
#include <encoding.h>
#include "sbi.h"
#ifdef RT_USING_KTIME
#include <ktime.h>
#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);