Skip to content

Commit d56cda4

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 d56cda4

File tree

12 files changed

+291
-142
lines changed

12 files changed

+291
-142
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
uint64_t rt_ktime_hrtimer_getcnt(void)
342337
{
343338
return rk_timer_current_value(_timer0.timer);
@@ -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_uint64_t cnt)
355350
{
356351
struct hrt_timer *timer = &_timer0;
357352
struct rk_timer *time = timer->timer;

components/drivers/ktime/inc/ktime.h

Lines changed: 18 additions & 35 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,18 +77,11 @@ 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_uint64_t rt_ktime_hrtimer_getfrq(void);
10885

10986
/**
11087
* @brief Get hrtimer the value of the cnt counter
@@ -119,7 +96,7 @@ unsigned long rt_ktime_hrtimer_getcnt(void);
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_uint64_t cnt);
123100

124101
/**
125102
* @brief called in hrtimer device driver isr routinue, it will process the timeouts
@@ -131,7 +108,13 @@ 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+
/**
112+
* @brief start the hrtimer
113+
*
114+
* @param cnt the cputimer cnt value
115+
* @return rt_err_t
116+
*/
117+
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer, rt_tick_t cnt);
135118
rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer);
136119
rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg);
137120
rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer);
@@ -154,30 +137,30 @@ void rt_ktime_hrtimer_process(void);
154137
* @param cnt: the cputimer cnt value
155138
* @return rt_err_t
156139
*/
157-
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, unsigned long cnt);
140+
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, rt_tick_t cnt);
158141

159142
/**
160143
* @brief sleep by ns
161144
*
162145
* @param ns: ns
163146
* @return rt_err_t
164147
*/
165-
rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, unsigned long ns);
148+
rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, rt_uint64_t ns);
166149

167150
/**
168151
* @brief sleep by us
169152
*
170153
* @param us: us
171154
* @return rt_err_t
172155
*/
173-
rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, unsigned long us);
156+
rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, rt_uint64_t us);
174157

175158
/**
176159
* @brief sleep by ms
177160
*
178161
* @param ms: ms
179162
* @return rt_err_t
180163
*/
181-
rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, unsigned long ms);
164+
rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, rt_uint64_t ms);
182165

183166
#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_tick_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 = (time_t)(cnt / freq);
22+
tv->tv_usec = rt_muldiv_u32((rt_uint32_t)(cnt % freq), MICROSECOND_PER_SECOND, freq, NULL);
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_tick_t cnt = rt_ktime_cputimer_getcnt();
32+
rt_uint32_t freq = rt_ktime_cputimer_getfrq();
3233

33-
*t = ns / (1000ULL * 1000 * 1000);
34+
*t = (time_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_tick_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 = (time_t)(cnt / freq);
47+
ts->tv_nsec = rt_muldiv_u32((rt_uint32_t)(cnt % freq), NANOSECOND_PER_SECOND, freq, NULL);
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)