Skip to content

Commit e13dc95

Browse files
committed
Fixes clock_gettime and rt_ktime_boottime_get_ns
Currently the return value of clock_gettime and rt_ktime_boottime_get_ns are restricted by rt_ktime_cputimer_getres, as the value of rt_ktime_cputimer_getres are not exactly represent the frequency of the clock, directly using rt_ktime_cputimer_getfrq will ensure the return value of rt_ktime_boottime_get_ns be more exact. And also add function rt_muldiv_u64 rt_muldiv_u32 for not losing precision when convert between cputimer and hrtimer and nanoseconds. Because rt_ktime_boottime_get_ns depends on rt_ktime_cputimer_getcnt and rt_ktime_cputimer_getcnt depends rt_tick_get So the rt_tick_t should be 64bit for long running program. Use `#if defined(ARCH_CPU_64BIT)` is for future allow rt_tick_t can be 64bit on 32bit CPU. Tick count should not be restricted to the CPU Signed-off-by: Yonggang Luo <[email protected]>
1 parent a81023b commit e13dc95

File tree

12 files changed

+289
-120
lines changed

12 files changed

+289
-120
lines changed

bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -328,16 +328,11 @@ static const struct rk_timer_data rk3399_timer_data =
328328

329329
#ifdef RT_USING_KTIME
330330

331-
uint64_t rt_ktime_hrtimer_getfrq(void)
331+
rt_uint64_t rt_ktime_hrtimer_getfrq(void)
332332
{
333333
return (24 * 1000 * 1000UL);
334334
}
335335

336-
uint64_t rt_ktime_hrtimer_getres(void)
337-
{
338-
return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / (24 * 1000 * 1000UL);
339-
}
340-
341336
/**
342337
* @brief set the timeout function for hrtimer framework
343338
*
@@ -346,7 +341,7 @@ uint64_t rt_ktime_hrtimer_getres(void)
346341
* @param cnt the count of timer dealy
347342
* @return rt_err_t 0 forever
348343
*/
349-
rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt)
344+
rt_err_t rt_ktime_hrtimer_settimeout(rt_uint64_t cnt)
350345
{
351346
struct hrt_timer *timer = &_timer0;
352347
struct rk_timer *time = timer->timer;

components/drivers/ktime/inc/ktime.h

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,14 @@
1818

1919
#include "rtthread.h"
2020

21-
#define RT_KTIME_RESMUL (1000000ULL)
22-
2321
struct rt_ktime_hrtimer
2422
{
2523
rt_uint8_t flag; /**< compatible to tick timer's flag */
2624
char name[RT_NAME_MAX];
2725
rt_list_t node;
2826
void *parameter;
29-
unsigned long delay_cnt;
30-
unsigned long timeout_cnt;
27+
rt_tick_t delay_cnt;
28+
rt_tick_t timeout_cnt;
3129
rt_err_t error;
3230
struct rt_completion completion;
3331
void (*timeout_func)(void *parameter);
@@ -58,26 +56,19 @@ rt_err_t rt_ktime_boottime_get_s(time_t *t);
5856
*/
5957
rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts);
6058

61-
/**
62-
* @brief Get cputimer resolution
63-
*
64-
* @return (resolution * RT_KTIME_RESMUL)
65-
*/
66-
rt_uint64_t rt_ktime_cputimer_getres(void);
67-
6859
/**
6960
* @brief Get cputimer frequency
7061
*
7162
* @return frequency
7263
*/
73-
unsigned long rt_ktime_cputimer_getfrq(void);
64+
rt_uint32_t rt_ktime_cputimer_getfrq(void);
7465

7566
/**
7667
* @brief Get cputimer the value of the cnt counter
7768
*
7869
* @return cnt
7970
*/
80-
unsigned long rt_ktime_cputimer_getcnt(void);
71+
rt_tick_t rt_ktime_cputimer_getcnt(void);
8172

8273
/**
8374
* @brief Init cputimer
@@ -86,26 +77,19 @@ unsigned long rt_ktime_cputimer_getcnt(void);
8677
void rt_ktime_cputimer_init(void);
8778

8879
/**
89-
* @brief Get hrtimer resolution
90-
*
91-
* @return (resolution * RT_KTIME_RESMUL)
92-
*/
93-
rt_uint64_t rt_ktime_hrtimer_getres(void);
94-
95-
/**
96-
* @brief Get hrtimer frequency
80+
* @brief Get hrtimer frequency, you should re-implemented it in hrtimer device driver
9781
*
9882
* @return frequency
9983
*/
100-
unsigned long rt_ktime_hrtimer_getfrq(void);
84+
rt_uint64_t rt_ktime_hrtimer_getfrq(void);
10185

10286
/**
10387
* @brief set hrtimer interrupt timeout count (cnt), you should re-implemented it in hrtimer device driver
10488
*
10589
* @param cnt: hrtimer requires a timing cnt value
10690
* @return rt_err_t
10791
*/
108-
rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt);
92+
rt_err_t rt_ktime_hrtimer_settimeout(rt_uint64_t cnt);
10993

11094
/**
11195
* @brief called in hrtimer device driver isr routinue, it will process the timeouts
@@ -117,7 +101,13 @@ void rt_ktime_hrtimer_init(rt_ktime_hrtimer_t timer,
117101
rt_uint8_t flag,
118102
void (*timeout)(void *parameter),
119103
void *parameter);
120-
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer, unsigned long cnt);
104+
/**
105+
* @brief start the hrtimer
106+
*
107+
* @param cnt the cputimer cnt value
108+
* @return rt_err_t
109+
*/
110+
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer, rt_tick_t cnt);
121111
rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer);
122112
rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg);
123113
rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer);
@@ -140,30 +130,30 @@ void rt_ktime_hrtimer_process(void);
140130
* @param cnt: the cputimer cnt value
141131
* @return rt_err_t
142132
*/
143-
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, unsigned long cnt);
133+
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, rt_tick_t cnt);
144134

145135
/**
146136
* @brief sleep by ns
147137
*
148138
* @param ns: ns
149139
* @return rt_err_t
150140
*/
151-
rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, unsigned long ns);
141+
rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, rt_uint64_t ns);
152142

153143
/**
154144
* @brief sleep by us
155145
*
156146
* @param us: us
157147
* @return rt_err_t
158148
*/
159-
rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, unsigned long us);
149+
rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, rt_uint64_t us);
160150

161151
/**
162152
* @brief sleep by ms
163153
*
164154
* @param ms: ms
165155
* @return rt_err_t
166156
*/
167-
rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, unsigned long ms);
157+
rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, rt_uint64_t ms);
168158

169159
#endif

components/drivers/ktime/src/aarch64/cputimer.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,16 @@
1111
#include "gtimer.h"
1212
#include "ktime.h"
1313

14-
static volatile unsigned long _init_cnt = 0;
14+
static volatile rt_uint64_t _init_cnt = 0;
1515

16-
rt_uint64_t rt_ktime_cputimer_getres(void)
16+
rt_uint32_t rt_ktime_cputimer_getfrq(void)
1717
{
18-
return ((1000ULL * 1000 * 1000) * RT_KTIME_RESMUL) / rt_hw_get_gtimer_frq();
18+
return (rt_uint32_t)rt_hw_get_gtimer_frq();
1919
}
2020

21-
unsigned long rt_ktime_cputimer_getfrq(void)
21+
rt_tick_t rt_ktime_cputimer_getcnt(void)
2222
{
23-
return rt_hw_get_gtimer_frq();
24-
}
25-
26-
unsigned long rt_ktime_cputimer_getcnt(void)
27-
{
28-
return rt_hw_get_cntpct_val() - _init_cnt;
23+
return (rt_tick_t)(rt_hw_get_cntpct_val() - _init_cnt);
2924
}
3025

3126
void rt_ktime_cputimer_init(void)

components/drivers/ktime/src/boottime.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@
1010

1111
#include "ktime.h"
1212

13-
#define __KTIME_MUL ((1000ULL * 1000 * 1000) / RT_TICK_PER_SECOND)
14-
1513
rt_weak rt_err_t rt_ktime_boottime_get_us(struct timeval *tv)
1614
{
1715
RT_ASSERT(tv != RT_NULL);
1816

19-
rt_uint64_t ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
17+
rt_tick_t cnt = rt_ktime_cputimer_getcnt();
18+
rt_uint32_t freq = rt_ktime_cputimer_getfrq();
2019

21-
tv->tv_sec = ns / (1000ULL * 1000 * 1000);
22-
tv->tv_usec = (ns % (1000ULL * 1000 * 1000)) / 1000;
20+
tv->tv_sec = (time_t)(cnt / freq);
21+
tv->tv_usec = rt_muldiv_u32((rt_uint32_t)(cnt % freq), MICROSECOND_PER_SECOND, freq, NULL);
2322

2423
return RT_EOK;
2524
}
@@ -28,9 +27,10 @@ rt_weak rt_err_t rt_ktime_boottime_get_s(time_t *t)
2827
{
2928
RT_ASSERT(t != RT_NULL);
3029

31-
rt_uint64_t ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
30+
rt_tick_t cnt = rt_ktime_cputimer_getcnt();
31+
rt_uint32_t freq = rt_ktime_cputimer_getfrq();
3232

33-
*t = ns / (1000ULL * 1000 * 1000);
33+
*t = (time_t)(cnt / freq);
3434

3535
return RT_EOK;
3636
}
@@ -39,10 +39,11 @@ rt_weak rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts)
3939
{
4040
RT_ASSERT(ts != RT_NULL);
4141

42-
rt_uint64_t ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
42+
rt_tick_t cnt = rt_ktime_cputimer_getcnt();
43+
rt_uint32_t freq = rt_ktime_cputimer_getfrq();
4344

44-
ts->tv_sec = ns / (1000ULL * 1000 * 1000);
45-
ts->tv_nsec = ns % (1000ULL * 1000 * 1000);
45+
ts->tv_sec = (time_t)(cnt / freq);
46+
ts->tv_nsec = rt_muldiv_u32((rt_uint32_t)(cnt % freq), NANOSECOND_PER_SECOND, freq, NULL);
4647

4748
return RT_EOK;
4849
}

components/drivers/ktime/src/cputimer.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,12 @@
1010

1111
#include "ktime.h"
1212

13-
rt_weak rt_uint64_t rt_ktime_cputimer_getres(void)
14-
{
15-
return ((1000ULL * 1000 * 1000) * RT_KTIME_RESMUL) / RT_TICK_PER_SECOND;
16-
}
17-
18-
rt_weak unsigned long rt_ktime_cputimer_getfrq(void)
13+
rt_weak rt_uint32_t rt_ktime_cputimer_getfrq(void)
1914
{
2015
return RT_TICK_PER_SECOND;
2116
}
2217

23-
rt_weak unsigned long rt_ktime_cputimer_getcnt(void)
18+
rt_weak rt_tick_t rt_ktime_cputimer_getcnt(void)
2419
{
2520
return rt_tick_get();
2621
}

0 commit comments

Comments
 (0)