Skip to content

Commit 0bc44ca

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 dc2bce7 commit 0bc44ca

File tree

12 files changed

+292
-145
lines changed

12 files changed

+292
-145
lines changed

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -328,17 +328,12 @@ 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_uint32_t rt_ktime_hrtimer_getfrq(void)
332332
{
333-
return (24 * 1000 * 1000UL);
333+
return (rt_uint32_t)(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-
341-
uint64_t rt_ktime_hrtimer_getcnt(void)
336+
rt_tick_t rt_ktime_hrtimer_getcnt(void)
342337
{
343338
return rk_timer_current_value(_timer0.timer);
344339
}
@@ -351,7 +346,7 @@ uint64_t rt_ktime_hrtimer_getcnt(void)
351346
* @param cnt the count of timer dealy
352347
* @return rt_err_t 0 forever
353348
*/
354-
rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt)
349+
rt_err_t rt_ktime_hrtimer_settimeout(rt_tick_t cnt)
355350
{
356351
struct hrt_timer *timer = &_timer0;
357352
struct rk_timer *time = timer->timer;

components/drivers/ktime/inc/ktime.h

Lines changed: 14 additions & 37 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,33 +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);
81-
82-
/**
83-
* @brief Get cputimer the cnt value corresponding to 1 os tick
84-
*
85-
* @return step
86-
*/
87-
unsigned long rt_ktime_cputimer_getstep(void);
71+
rt_tick_t rt_ktime_cputimer_getcnt(void);
8872

8973
/**
9074
* @brief Init cputimer
@@ -93,33 +77,26 @@ unsigned long rt_ktime_cputimer_getstep(void);
9377
void rt_ktime_cputimer_init(void);
9478

9579
/**
96-
* @brief Get hrtimer resolution
97-
*
98-
* @return (resolution * RT_KTIME_RESMUL)
99-
*/
100-
rt_uint64_t rt_ktime_hrtimer_getres(void);
101-
102-
/**
103-
* @brief Get hrtimer frequency
80+
* @brief Get hrtimer frequency, you should re-implemented it in hrtimer device driver
10481
*
10582
* @return frequency
10683
*/
107-
unsigned long rt_ktime_hrtimer_getfrq(void);
84+
rt_uint32_t rt_ktime_hrtimer_getfrq(void);
10885

10986
/**
110-
* @brief Get hrtimer the value of the cnt counter
87+
* @brief Get hrtimer the value of the cnt counter, you should re-implemented it in hrtimer device driver
11188
*
11289
* @return cnt
11390
*/
114-
unsigned long rt_ktime_hrtimer_getcnt(void);
91+
rt_tick_t rt_ktime_hrtimer_getcnt(void);
11592

11693
/**
11794
* @brief set hrtimer interrupt timeout count (cnt), you should re-implemented it in hrtimer device driver
11895
*
11996
* @param cnt: hrtimer requires a timing cnt value
12097
* @return rt_err_t
12198
*/
122-
rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt);
99+
rt_err_t rt_ktime_hrtimer_settimeout(rt_tick_t cnt);
123100

124101
/**
125102
* @brief called in hrtimer device driver isr routinue, it will process the timeouts
@@ -131,7 +108,7 @@ void rt_ktime_hrtimer_init(rt_ktime_hrtimer_t timer,
131108
rt_uint8_t flag,
132109
void (*timeout)(void *parameter),
133110
void *parameter);
134-
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer, unsigned long cnt);
111+
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer, rt_tick_t cnt);
135112
rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer);
136113
rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg);
137114
rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer);
@@ -154,30 +131,30 @@ void rt_ktime_hrtimer_process(void);
154131
* @param cnt: the cputimer cnt value
155132
* @return rt_err_t
156133
*/
157-
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, unsigned long cnt);
134+
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, rt_tick_t cnt);
158135

159136
/**
160137
* @brief sleep by ns
161138
*
162139
* @param ns: ns
163140
* @return rt_err_t
164141
*/
165-
rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, unsigned long ns);
142+
rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, rt_uint64_t ns);
166143

167144
/**
168145
* @brief sleep by us
169146
*
170147
* @param us: us
171148
* @return rt_err_t
172149
*/
173-
rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, unsigned long us);
150+
rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, rt_uint64_t us);
174151

175152
/**
176153
* @brief sleep by ms
177154
*
178155
* @param ms: ms
179156
* @return rt_err_t
180157
*/
181-
rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, unsigned long ms);
158+
rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, rt_uint64_t ms);
182159

183160
#endif

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +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;
29-
}
30-
31-
unsigned long rt_ktime_cputimer_getstep(void)
32-
{
33-
return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND;
23+
return (rt_tick_t)(rt_hw_get_cntpct_val() - _init_cnt);
3424
}
3525

3626
void rt_ktime_cputimer_init(void)

components/drivers/ktime/src/boottime.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@
99
*/
1010

1111
#include "ktime.h"
12-
13-
#define __KTIME_MUL ((1000ULL * 1000 * 1000) / RT_TICK_PER_SECOND)
12+
#include "rttypes.h"
1413

1514
rt_weak rt_err_t rt_ktime_boottime_get_us(struct timeval *tv)
1615
{
1716
RT_ASSERT(tv != RT_NULL);
1817

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

21-
tv->tv_sec = ns / (1000ULL * 1000 * 1000);
22-
tv->tv_usec = (ns % (1000ULL * 1000 * 1000)) / 1000;
21+
tv->tv_sec = cnt / freq;
22+
tv->tv_usec = (cnt % freq) * MICROSECOND_PER_SECOND / freq;
2323

2424
return RT_EOK;
2525
}
@@ -28,9 +28,10 @@ rt_weak rt_err_t rt_ktime_boottime_get_s(time_t *t)
2828
{
2929
RT_ASSERT(t != RT_NULL);
3030

31-
rt_uint64_t ns = (rt_ktime_cputimer_getcnt() * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
31+
rt_uint64_t cnt = rt_ktime_cputimer_getcnt();
32+
rt_uint32_t freq = rt_ktime_cputimer_getfrq();
3233

33-
*t = ns / (1000ULL * 1000 * 1000);
34+
*t = cnt / freq;
3435

3536
return RT_EOK;
3637
}
@@ -39,10 +40,11 @@ rt_weak rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts)
3940
{
4041
RT_ASSERT(ts != RT_NULL);
4142

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

44-
ts->tv_sec = ns / (1000ULL * 1000 * 1000);
45-
ts->tv_nsec = ns % (1000ULL * 1000 * 1000);
46+
ts->tv_sec = cnt / freq;
47+
ts->tv_nsec = (cnt % freq) * NANOSECOND_PER_SECOND / freq;
4648

4749
return RT_EOK;
4850
}

components/drivers/ktime/src/cputimer.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,16 @@
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
}
2722

28-
rt_weak unsigned long rt_ktime_cputimer_getstep(void)
29-
{
30-
return 1;
31-
}
32-
3323
rt_weak void rt_ktime_cputimer_init(void)
3424
{
3525
return;

0 commit comments

Comments
 (0)