diff --git a/components/drivers/clock_time/src/clock_time.c b/components/drivers/clock_time/src/clock_time.c index 11458c2698..4a69a95b18 100644 --- a/components/drivers/clock_time/src/clock_time.c +++ b/components/drivers/clock_time/src/clock_time.c @@ -63,8 +63,8 @@ rt_err_t rt_clock_time_device_register(struct rt_clock_time_device *dev, } else { - /* For very low frequencies, calculate more carefully */ - dev->res_scale = (1000000ULL * RT_CLOCK_TIME_RESMUL) / freq * 1000; + /* For very low frequencies, calculate more carefully to avoid precision loss */ + dev->res_scale = ((1000000ULL * RT_CLOCK_TIME_RESMUL * 1000) / freq); } } else diff --git a/components/drivers/clock_time/src/clock_time_boottime.c b/components/drivers/clock_time/src/clock_time_boottime.c index c0b85333a9..0df1c5831c 100644 --- a/components/drivers/clock_time/src/clock_time_boottime.c +++ b/components/drivers/clock_time/src/clock_time_boottime.c @@ -17,10 +17,13 @@ rt_weak rt_err_t rt_clock_boottime_get_us(struct timeval *tv) { RT_ASSERT(tv != RT_NULL); - rt_uint64_t ns = (rt_clock_cputimer_getcnt() * rt_clock_cputimer_getres()) / RT_CLOCK_TIME_RESMUL; + /* Use 64-bit intermediate values to prevent overflow */ + rt_uint64_t cnt = rt_clock_cputimer_getcnt(); + rt_uint64_t res = rt_clock_cputimer_getres(); + rt_uint64_t ns = (cnt * res) / RT_CLOCK_TIME_RESMUL; - tv->tv_sec = ns / (1000ULL * 1000 * 1000); - tv->tv_usec = (ns % (1000ULL * 1000 * 1000)) / 1000; + tv->tv_sec = (long)(ns / (1000ULL * 1000 * 1000)); + tv->tv_usec = (long)((ns % (1000ULL * 1000 * 1000)) / 1000); return RT_EOK; } @@ -29,9 +32,12 @@ rt_weak rt_err_t rt_clock_boottime_get_s(time_t *t) { RT_ASSERT(t != RT_NULL); - rt_uint64_t ns = (rt_clock_cputimer_getcnt() * rt_clock_cputimer_getres()) / RT_CLOCK_TIME_RESMUL; + /* Use 64-bit intermediate values to prevent overflow */ + rt_uint64_t cnt = rt_clock_cputimer_getcnt(); + rt_uint64_t res = rt_clock_cputimer_getres(); + rt_uint64_t ns = (cnt * res) / RT_CLOCK_TIME_RESMUL; - *t = ns / (1000ULL * 1000 * 1000); + *t = (time_t)(ns / (1000ULL * 1000 * 1000)); return RT_EOK; } @@ -40,10 +46,14 @@ rt_weak rt_err_t rt_clock_boottime_get_ns(struct timespec *ts) { RT_ASSERT(ts != RT_NULL); - rt_uint64_t ns = (rt_clock_cputimer_getcnt() * rt_clock_cputimer_getres()) / RT_CLOCK_TIME_RESMUL; + /* Use 64-bit intermediate values to prevent overflow */ + rt_uint64_t cnt = rt_clock_cputimer_getcnt(); + rt_uint64_t res = rt_clock_cputimer_getres(); + rt_uint64_t ns = (cnt * res) / RT_CLOCK_TIME_RESMUL; - ts->tv_sec = ns / (1000ULL * 1000 * 1000); - ts->tv_nsec = ns % (1000ULL * 1000 * 1000); + ts->tv_sec = (time_t)(ns / (1000ULL * 1000 * 1000)); + ts->tv_nsec = (long)(ns % (1000ULL * 1000 * 1000)); return RT_EOK; } + diff --git a/components/drivers/clock_time/src/hrtimer.c b/components/drivers/clock_time/src/hrtimer.c index 630f148fe0..6709b175bc 100644 --- a/components/drivers/clock_time/src/hrtimer.c +++ b/components/drivers/clock_time/src/hrtimer.c @@ -74,8 +74,8 @@ rt_weak rt_err_t rt_clock_hrtimer_settimeout(unsigned long cnt) /** * @brief convert cnt from cputimer cnt to hrtimer cnt * - * @param cnt - * @return unsigned long + * @param cnt Target count value + * @return Converted count for hrtimer */ static unsigned long _cnt_convert(unsigned long cnt) { @@ -94,7 +94,12 @@ static unsigned long _cnt_convert(unsigned long cnt) if (count > (_HRTIMER_MAX_CNT / 2)) return 0; - rtn = (count * rt_clock_cputimer_getres()) / rt_clock_hrtimer_getres(); + /* Use 64-bit intermediate to prevent overflow in multiplication */ + rt_uint64_t count_64 = (rt_uint64_t)count; + rt_uint64_t res_cpu = rt_clock_cputimer_getres(); + rt_uint64_t res_hr = rt_clock_hrtimer_getres(); + + rtn = (unsigned long)((count_64 * res_cpu) / res_hr); return rtn == 0 ? 1 : rtn; /* at least 1 */ }