Ver código fonte

🐞 fix(ktime): fix wrong boottime

因为tick从中断到设置中间的时延特别大,因此暂不采用tick做基准时间,直接取gtime的cnt做基准时间
xqyjlj 1 ano atrás
pai
commit
d23dd56692

+ 6 - 0
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
  *

+ 8 - 1
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();
+}

+ 12 - 15
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;
 }

+ 5 - 0
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;
+}

+ 8 - 1
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));
+}

+ 7 - 0
libcpu/aarch64/common/gtimer.c

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

+ 7 - 0
libcpu/risc-v/virt64/tick.c

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