summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorxqyjlj <[email protected]>2023-07-17 20:11:58 +0800
committerGitHub <[email protected]>2023-07-17 20:11:58 +0800
commit0eb75ced70a514051fcc6a8f1d232e195b15b4a0 (patch)
treea025fe349198fa0fe6f972ea1100ac31ba64787a /components
parentb424169e1742c1b19d039f9871dd3c672ea7b729 (diff)
[time]时钟框架重构 (#7794)
Diffstat (limited to 'components')
-rw-r--r--components/drivers/include/drivers/rtc.h8
-rw-r--r--components/drivers/rtc/soft_rtc.c131
-rw-r--r--components/ktime/SConscript19
-rw-r--r--components/ktime/inc/ktime.h160
-rw-r--r--components/ktime/src/aarch64/cputimer.c32
-rw-r--r--components/ktime/src/boottime.c51
-rw-r--r--components/ktime/src/cputimer.c31
-rw-r--r--components/ktime/src/hrtimer.c382
-rw-r--r--components/ktime/src/risc-v/virt64/cputimer.c33
-rw-r--r--components/libc/compilers/common/ctime.c725
-rw-r--r--components/libc/compilers/common/include/sys/time.h37
-rw-r--r--components/libc/posix/signal/posix_signal.c2
12 files changed, 1107 insertions, 504 deletions
diff --git a/components/drivers/include/drivers/rtc.h b/components/drivers/include/drivers/rtc.h
index ce364d79a8..0aacc4665f 100644
--- a/components/drivers/include/drivers/rtc.h
+++ b/components/drivers/include/drivers/rtc.h
@@ -27,6 +27,9 @@ extern "C" {
#define RT_DEVICE_CTRL_RTC_SET_TIMEVAL (RT_DEVICE_CTRL_BASE(RTC) + 0x04) /**< set timeval for gettimeofday */
#define RT_DEVICE_CTRL_RTC_GET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x05) /**< get alarm */
#define RT_DEVICE_CTRL_RTC_SET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x06) /**< set alarm */
+#define RT_DEVICE_CTRL_RTC_GET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x07) /**< get timespec for clock_gettime */
+#define RT_DEVICE_CTRL_RTC_SET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x08) /**< set timespec for clock_settime */
+#define RT_DEVICE_CTRL_RTC_GET_TIMERES (RT_DEVICE_CTRL_BASE(RTC) + 0x09) /**< get resolution for clock_getres */
/* used for alarm function */
struct rt_rtc_wkalarm
@@ -64,6 +67,11 @@ rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second);
rt_err_t set_timestamp(time_t timestamp);
rt_err_t get_timestamp(time_t *timestamp);
+#ifdef RT_USING_SYSTEM_WORKQUEUE
+rt_err_t rt_soft_rtc_sync();
+rt_err_t rt_soft_rtc_set_source(const char *name);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/components/drivers/rtc/soft_rtc.c b/components/drivers/rtc/soft_rtc.c
index d80e21372f..3d84e547ad 100644
--- a/components/drivers/rtc/soft_rtc.c
+++ b/components/drivers/rtc/soft_rtc.c
@@ -13,6 +13,8 @@
#include <rtthread.h>
#include <rtdevice.h>
+#include <ktime.h>
+
#ifdef RT_USING_SOFT_RTC
/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50) */
@@ -23,9 +25,21 @@
#define SOFT_RTC_TIME_DEFAULT RTC_TIME_INIT(2018, 1, 1, 0, 0 ,0)
#endif
+#ifndef RTC_AUTO_SYNC_FIRST_DELAY
+#define RTC_AUTO_SYNC_FIRST_DELAY 25
+#endif
+#ifndef RTC_AUTO_SYNC_PERIOD
+#define RTC_AUTO_SYNC_PERIOD 3600
+#endif
+
+static struct rt_work rtc_sync_work;
+static rt_device_t source_device = RT_NULL;
+
static struct rt_device soft_rtc_dev;
static rt_tick_t init_tick;
static time_t init_time;
+static struct timeval init_tv = {0};
+static struct timespec init_ts = {0};
#ifdef RT_USING_ALARM
@@ -55,9 +69,33 @@ static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm)
#endif
+static void set_rtc_time(time_t t)
+{
+ init_time = t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+#ifdef RT_USING_ALARM
+ soft_rtc_alarm_update(&wkalarm);
+#endif
+}
+
+static void _source_device_control(int cmd, void *args)
+{
+ if (source_device == RT_NULL)
+ return;
+
+ if (rt_device_open(source_device, 0) == RT_EOK)
+ {
+ rt_device_control(source_device, cmd, args);
+ rt_device_close(source_device);
+ }
+}
+
static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
{
time_t *t;
+ struct timeval *tv;
+ struct timespec *ts;
+ struct timeval _tv;
+ struct timespec _ts;
struct tm time_temp;
RT_ASSERT(dev != RT_NULL);
@@ -72,10 +110,8 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
case RT_DEVICE_CTRL_RTC_SET_TIME:
{
t = (time_t *) args;
- init_time = *t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
-#ifdef RT_USING_ALARM
- soft_rtc_alarm_update(&wkalarm);
-#endif
+ set_rtc_time(*t);
+ _source_device_control(RT_DEVICE_CTRL_RTC_SET_TIME, t);
break;
}
#ifdef RT_USING_ALARM
@@ -87,6 +123,37 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
soft_rtc_alarm_update(&wkalarm);
break;
#endif
+ case RT_DEVICE_CTRL_RTC_GET_TIMEVAL:
+ tv = (struct timeval *)args;
+ rt_ktime_boottime_get_us(&_tv);
+ tv->tv_sec = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+ tv->tv_usec = init_tv.tv_usec + _tv.tv_usec;
+ break;
+ case RT_DEVICE_CTRL_RTC_SET_TIMEVAL:
+ tv = (struct timeval *)args;
+ rt_ktime_boottime_get_us(&_tv);
+ set_rtc_time(tv->tv_sec);
+ init_tv.tv_usec = tv->tv_usec - _tv.tv_usec;
+ _source_device_control(RT_DEVICE_CTRL_RTC_SET_TIME, &(tv->tv_sec));
+ break;
+ case RT_DEVICE_CTRL_RTC_GET_TIMESPEC:
+ ts = (struct timespec *)args;
+ rt_ktime_boottime_get_ns(&_ts);
+ ts->tv_sec = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+ ts->tv_nsec = init_ts.tv_nsec + _ts.tv_nsec;
+ break;
+ case RT_DEVICE_CTRL_RTC_SET_TIMESPEC:
+ ts = (struct timespec *)args;
+ rt_ktime_boottime_get_ns(&_ts);
+ set_rtc_time(ts->tv_sec);
+ init_ts.tv_nsec = ts->tv_nsec - _ts.tv_nsec;
+ _source_device_control(RT_DEVICE_CTRL_RTC_SET_TIME, &(ts->tv_sec));
+ break;
+ case RT_DEVICE_CTRL_RTC_GET_TIMERES:
+ ts = (struct timespec *)args;
+ ts->tv_sec = 0;
+ ts->tv_nsec = (rt_ktime_cputimer_getres() / RT_KTIME_RESMUL);
+ break;
}
return RT_EOK;
@@ -153,4 +220,60 @@ static int rt_soft_rtc_init(void)
}
INIT_DEVICE_EXPORT(rt_soft_rtc_init);
+#ifdef RT_USING_SYSTEM_WORKQUEUE
+
+rt_err_t rt_soft_rtc_sync()
+{
+ time_t time = 0;
+
+ if (source_device == RT_NULL)
+ {
+ rt_kprintf("error: rtc source not found, please set it!!!\n");
+ return RT_ENOSYS;
+ }
+
+ _source_device_control(RT_DEVICE_CTRL_RTC_GET_TIME, &time);
+ set_rtc_time(time);
+ return RT_EOK;
+}
+
+static void rtc_sync_work_func(struct rt_work *work, void *work_data)
+{
+ rt_soft_rtc_sync();
+ rt_work_submit(work, rt_tick_from_millisecond(RTC_AUTO_SYNC_PERIOD * 1000));
+}
+
+rt_err_t rt_soft_rtc_set_source(const char *name)
+{
+ RT_ASSERT(name != RT_NULL);
+ RT_ASSERT(rt_device_find(name)); // make sure source is exist
+
+ source_device = rt_device_find(name);
+ rt_work_init(&rtc_sync_work, rtc_sync_work_func, RT_NULL);
+ rt_work_submit(&rtc_sync_work, rt_tick_from_millisecond(RTC_AUTO_SYNC_FIRST_DELAY * 1000));
+
+ return RT_EOK;
+}
+
+#ifdef FINSH_USING_MSH
+#include <finsh.h>
+static void cmd_rtc_sync(int argc, char **argv)
+{
+ struct timeval tv = {0};
+ struct timezone tz = {0};
+ time_t now = (time_t)0;
+
+ rt_soft_rtc_sync();
+
+ gettimeofday(&tv, &tz);
+ now = tv.tv_sec;
+ /* output current time */
+ rt_kprintf("local time: %.*s", 25, ctime(&now));
+ rt_kprintf("timestamps: %ld\n", (long)tv.tv_sec);
+}
+MSH_CMD_EXPORT_ALIAS(cmd_rtc_sync, rtc_sync, Update time by real rtc);
+#endif
+
+#endif /* RT_USING_SYSTEM_WORKQUEUE */
+
#endif /* RT_USING_SOFT_RTC */
diff --git a/components/ktime/SConscript b/components/ktime/SConscript
new file mode 100644
index 0000000000..0ec9655697
--- /dev/null
+++ b/components/ktime/SConscript
@@ -0,0 +1,19 @@
+import os
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+
+src = Glob('src/*.c')
+list = os.listdir(cwd + "/src")
+if rtconfig.ARCH in list:
+ if os.path.exists(cwd + "/src/" + rtconfig.ARCH + "/" + rtconfig.CPU):
+ src += Glob("src/" + rtconfig.ARCH + "/" + rtconfig.CPU + "/*.c")
+ else:
+ src += Glob("src/" + rtconfig.ARCH + "/*.c")
+CPPPATH = [cwd, cwd + "/inc"]
+
+group = DefineGroup('ktime', src, depend=[''], CPPPATH=CPPPATH)
+
+Return('group')
diff --git a/components/ktime/inc/ktime.h b/components/ktime/inc/ktime.h
new file mode 100644
index 0000000000..86fbefd0bb
--- /dev/null
+++ b/components/ktime/inc/ktime.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-07-10 xqyjlj The first version.
+ */
+
+#ifndef __KTIME_H__
+#define __KTIME_H__
+
+#include <stdint.h>
+#include <sys/time.h>
+
+#include "rtthread.h"
+
+#define RT_KTIME_RESMUL (1000000UL)
+
+struct rt_ktime_hrtimer
+{
+ struct rt_object parent; /**< inherit from rt_object */
+ rt_list_t row;
+ void *parameter;
+ unsigned long init_cnt;
+ unsigned long timeout_cnt;
+ struct rt_semaphore sem;
+ void (*timeout_func)(void *parameter);
+};
+typedef struct rt_ktime_hrtimer *rt_ktime_hrtimer_t;
+
+/**
+ * @brief Get boottime with us precision
+ *
+ * @param tv: timeval
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_boottime_get_us(struct timeval *tv);
+
+/**
+ * @brief Get boottime with s precision
+ *
+ * @param t: time_t
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_boottime_get_s(time_t *t);
+
+/**
+ * @brief Get boottime with ns precision
+ *
+ * @param ts: timespec
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts);
+
+/**
+ * @brief Get cputimer resolution
+ *
+ * @return (resolution * RT_KTIME_RESMUL)
+ */
+unsigned long rt_ktime_cputimer_getres(void);
+
+/**
+ * @brief Get cputimer frequency
+ *
+ * @return frequency
+ */
+unsigned long rt_ktime_cputimer_getfrq(void);
+
+/**
+ * @brief Get cputimer the value of the cnt counter
+ *
+ * @return cnt
+ */
+unsigned long rt_ktime_cputimer_getcnt(void);
+
+/**
+ * @brief Get cputimer the cnt value corresponding to 1 os tick
+ *
+ * @return step
+ */
+unsigned long rt_ktime_cputimer_getstep(void);
+
+/**
+ * @brief Get hrtimer resolution
+ *
+ * @return (resolution * RT_KTIME_RESMUL)
+ */
+unsigned long rt_ktime_hrtimer_getres(void);
+
+/**
+ * @brief Get hrtimer frequency
+ *
+ * @return frequency
+ */
+unsigned long rt_ktime_hrtimer_getfrq(void);
+
+/**
+ * @brief Get hrtimer the value of the cnt counter
+ *
+ * @return cnt
+ */
+unsigned long rt_ktime_hrtimer_getcnt(void);
+
+/**
+ * @brief set hrtimer timeout, when timeout, the timer callback will call timeout
+ *
+ * @param cnt: hrtimer requires a timing cnt value
+ * @param timeout: timeout callback
+ * @param param: parameter
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)(void *param), void *param);
+
+void rt_ktime_hrtimer_init(rt_ktime_hrtimer_t timer,
+ const char *name,
+ unsigned long cnt,
+ rt_uint8_t flag,
+ void (*timeout)(void *parameter),
+ void *parameter);
+rt_err_t rt_ktime_hrtimer_delete(rt_ktime_hrtimer_t timer);
+rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer);
+rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer);
+rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg);
+rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer);
+
+/**
+ * @brief sleep by the cputimer cnt value
+ *
+ * @param cnt: the cputimer cnt value
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt);
+
+/**
+ * @brief sleep by ns
+ *
+ * @param ns: ns
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns);
+
+/**
+ * @brief sleep by us
+ *
+ * @param us: us
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_hrtimer_udelay(unsigned long us);
+
+/**
+ * @brief sleep by ms
+ *
+ * @param ms: ms
+ * @return rt_err_t
+ */
+rt_err_t rt_ktime_hrtimer_mdelay(unsigned long ms);
+
+#endif
diff --git a/components/ktime/src/aarch64/cputimer.c b/components/ktime/src/aarch64/cputimer.c
new file mode 100644
index 0000000000..53c60736d4
--- /dev/null
+++ b/components/ktime/src/aarch64/cputimer.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-07-10 xqyjlj The first version.
+ */
+
+#include "gtimer.h"
+#include "ktime.h"
+
+unsigned long rt_ktime_cputimer_getres(void)
+{
+ return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / rt_hw_get_gtimer_frq();
+}
+
+unsigned long rt_ktime_cputimer_getfrq(void)
+{
+ return rt_hw_get_gtimer_frq();
+}
+
+unsigned long rt_ktime_cputimer_getcnt(void)
+{
+ return rt_hw_get_cntpct_val();
+}
+
+unsigned long rt_ktime_cputimer_getstep(void)
+{
+ return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND;
+}
diff --git a/components/ktime/src/boottime.c b/components/ktime/src/boottime.c
new file mode 100644
index 0000000000..9d05266d71
--- /dev/null
+++ b/components/ktime/src/boottime.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-07-10 xqyjlj The first version.
+ */
+
+#include "ktime.h"
+
+#define __KTIME_MUL ((1000UL * 1000 * 1000) / RT_TICK_PER_SECOND)
+
+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;
+
+ tv->tv_sec = ms / RT_TICK_PER_SECOND;
+ tv->tv_usec = ns / 1000;
+
+ return RT_EOK;
+}
+
+rt_err_t rt_ktime_boottime_get_s(time_t *t)
+{
+ RT_ASSERT(t != RT_NULL);
+
+ *t = rt_tick_get() / RT_TICK_PER_SECOND;
+
+ return RT_EOK;
+}
+
+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;
+
+ ts->tv_sec = ms / RT_TICK_PER_SECOND;
+ ts->tv_nsec = ((ms % RT_TICK_PER_SECOND) * __KTIME_MUL) + ns;
+
+ return RT_EOK;
+}
diff --git a/components/ktime/src/cputimer.c b/components/ktime/src/cputimer.c
new file mode 100644
index 0000000000..c878581cdf
--- /dev/null
+++ b/components/ktime/src/cputimer.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-07-10 xqyjlj The first version.
+ */
+
+#include "ktime.h"
+
+rt_weak unsigned long rt_ktime_cputimer_getres(void)
+{
+ return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_ktime_cputimer_getfrq(void)
+{
+ return RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_ktime_cputimer_getcnt(void)
+{
+ return rt_tick_get();
+}
+
+rt_weak unsigned long rt_ktime_cputimer_getstep(void)
+{
+ return 1;
+}
diff --git a/components/ktime/src/hrtimer.c b/components/ktime/src/hrtimer.c
new file mode 100644
index 0000000000..81954c3e00
--- /dev/null
+++ b/components/ktime/src/hrtimer.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-07-10 xqyjlj The first version.
+ */
+
+#include <rtdevice.h>
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "ktime.h"
+
+#ifdef ARCH_CPU_64BIT
+#define _HRTIMER_MAX_CNT UINT64_MAX
+#else
+#define _HRTIMER_MAX_CNT UINT32_MAX
+#endif
+
+static rt_list_t _timer_list = RT_LIST_OBJECT_INIT(_timer_list);
+static rt_ktime_hrtimer_t _nowtimer = RT_NULL;
+static struct rt_spinlock _spinlock;
+
+rt_weak unsigned long rt_ktime_hrtimer_getres(void)
+{
+ return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_ktime_hrtimer_getfrq(void)
+{
+ return RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_ktime_hrtimer_getcnt(void)
+{
+ return rt_tick_get();
+}
+
+static void (*_outcb)(void *param) = RT_NULL;
+
+static void _hrtimer_timeout(void *parameter)
+{
+ if (_outcb)
+ _outcb(parameter);
+}
+
+rt_weak rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)(void *param), void *param)
+{
+ static rt_timer_t timer = RT_NULL;
+
+ if (timer == RT_NULL)
+ {
+ timer = rt_timer_create("shrtimer", _hrtimer_timeout, param, cnt, RT_TIMER_FLAG_ONE_SHOT);
+ }
+ else
+ {
+ rt_tick_t tick = cnt;
+ rt_timer_control(timer, RT_TIMER_CTRL_SET_TIME, &tick);
+ rt_timer_control(timer, RT_TIMER_CTRL_SET_PARM, param);
+ }
+
+ _outcb = timeout;
+ if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
+ {
+ rt_timer_stop(timer);
+ }
+ rt_timer_start(timer);
+ return RT_EOK;
+}
+
+/**
+ * @brief convert cnt from cputimer cnt to hrtimer cnt
+ *
+ * @param cnt
+ * @return unsigned long
+ */
+static unsigned long _cnt_convert(unsigned long cnt)
+{
+ int64_t count = cnt - rt_ktime_cputimer_getcnt();
+ if (count <= 0)
+ return 0;
+
+ return (count * rt_ktime_cputimer_getres()) / rt_ktime_hrtimer_getres();
+}
+
+static void _sleep_timeout(void *parameter)
+{
+ struct rt_semaphore *sem;
+ sem = (struct rt_semaphore *)parameter;
+ rt_sem_release(sem);
+}
+
+static void _set_next_timeout(void);
+static void _timeout_callback(void *parameter)
+{
+ rt_ktime_hrtimer_t timer;
+ timer = (rt_ktime_hrtimer_t)parameter;
+ rt_base_t level;
+
+ level = rt_spin_lock_irqsave(&_spinlock);
+ _nowtimer = RT_NULL;
+ rt_list_remove(&(timer->row));
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+ if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
+ {
+ timer->timeout_func(timer->parameter);
+ }
+
+ _set_next_timeout();
+}
+
+static void _set_next_timeout(void)
+{
+ rt_ktime_hrtimer_t t;
+ rt_base_t level;
+
+ if (&_timer_list != _timer_list.prev)
+ {
+ level = rt_spin_lock_irqsave(&_spinlock);
+ t = rt_list_entry((&_timer_list)->next, struct rt_ktime_hrtimer, row);
+ if (_nowtimer != RT_NULL)
+ {
+ if (t != _nowtimer && t->timeout_cnt < _nowtimer->timeout_cnt)
+ {
+ _nowtimer = t;
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+ rt_ktime_hrtimer_settimeout(_cnt_convert(t->timeout_cnt), _timeout_callback, t);
+ }
+ else
+ {
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+ }
+ }
+ else
+ {
+ _nowtimer = t;
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+ rt_ktime_hrtimer_settimeout(_cnt_convert(t->timeout_cnt), _timeout_callback, t);
+ }
+ }
+ else
+ {
+ _nowtimer = RT_NULL;
+ rt_ktime_hrtimer_settimeout(RT_NULL, RT_NULL, RT_NULL);
+ }
+}
+
+void rt_ktime_hrtimer_init(rt_ktime_hrtimer_t timer,
+ const char *name,
+ unsigned long cnt,
+ rt_uint8_t flag,
+ void (*timeout)(void *parameter),
+ void *parameter)
+{
+ /* parameter check */
+ RT_ASSERT(timer != RT_NULL);
+ RT_ASSERT(timeout != RT_NULL);
+ RT_ASSERT(cnt < (_HRTIMER_MAX_CNT / 2));
+
+ /* set flag */
+ timer->parent.flag = flag;
+
+ /* set deactivated */
+ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+ timer->timeout_func = timeout;
+ timer->parameter = parameter;
+ timer->timeout_cnt = cnt + rt_ktime_cputimer_getcnt();
+ timer->init_cnt = cnt;
+
+ rt_list_init(&(timer->row));
+ rt_sem_init(&(timer->sem), "hrtimer", 0, RT_IPC_FLAG_PRIO);
+}
+
+rt_err_t rt_ktime_hrtimer_delete(rt_ktime_hrtimer_t timer)
+{
+ rt_base_t level;
+
+ /* parameter check */
+ RT_ASSERT(timer != RT_NULL);
+
+ level = rt_spin_lock_irqsave(&_spinlock);
+ rt_list_remove(&timer->row);
+ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* stop timer */
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+
+ _set_next_timeout();
+
+ return RT_EOK;
+}
+
+rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer)
+{
+ rt_list_t *timer_list;
+ rt_base_t level;
+
+ /* parameter check */
+ RT_ASSERT(timer != RT_NULL);
+
+ level = rt_spin_lock_irqsave(&_spinlock);
+ rt_list_remove(&timer->row); /* remove timer from list */
+ /* change status of timer */
+ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+ timer_list = &_timer_list;
+ for (; timer_list != _timer_list.prev; timer_list = timer_list->next)
+ {
+ rt_ktime_hrtimer_t t;
+ rt_list_t *p = timer_list->next;
+
+ t = rt_list_entry(p, struct rt_ktime_hrtimer, row);
+
+ if ((t->timeout_cnt - timer->timeout_cnt) == 0)
+ {
+ continue;
+ }
+ else if ((t->timeout_cnt - timer->timeout_cnt) < (_HRTIMER_MAX_CNT / 2))
+ {
+ break;
+ }
+ }
+ rt_list_insert_after(timer_list, &(timer->row));
+ timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+
+ _set_next_timeout();
+
+ return RT_EOK;
+}
+
+rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer)
+{
+ rt_base_t level;
+
+ RT_ASSERT(timer != RT_NULL); /* timer check */
+
+ level = rt_spin_lock_irqsave(&_spinlock);
+ if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
+ {
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+ return -RT_ERROR;
+ }
+ rt_list_remove(&timer->row);
+ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* change status */
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+
+ _set_next_timeout();
+
+ return RT_EOK;
+}
+
+rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg)
+{
+ rt_base_t level;
+
+ /* parameter check */
+ RT_ASSERT(timer != RT_NULL);
+
+ level = rt_spin_lock_irqsave(&_spinlock);
+ switch (cmd)
+ {
+ case RT_TIMER_CTRL_GET_TIME:
+ *(unsigned long *)arg = timer->init_cnt;
+ break;
+
+ case RT_TIMER_CTRL_SET_TIME:
+ RT_ASSERT((*(unsigned long *)arg) < (_HRTIMER_MAX_CNT / 2));
+ timer->init_cnt = *(unsigned long *)arg;
+ timer->timeout_cnt = *(unsigned long *)arg + rt_ktime_cputimer_getcnt();
+ break;
+
+ case RT_TIMER_CTRL_SET_ONESHOT:
+ timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
+ break;
+
+ case RT_TIMER_CTRL_SET_PERIODIC:
+ timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
+ break;
+
+ case RT_TIMER_CTRL_GET_STATE:
+ if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
+ {
+ /*timer is start and run*/
+ *(rt_uint32_t *)arg = RT_TIMER_FLAG_ACTIVATED;
+ }
+ else
+ {
+ /*timer is stop*/
+ *(rt_uint32_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
+ }
+ break;
+
+ case RT_TIMER_CTRL_GET_REMAIN_TIME:
+ *(unsigned long *)arg = timer->timeout_cnt;
+ break;
+ case RT_TIMER_CTRL_GET_FUNC:
+ arg = (void *)timer->timeout_func;
+ break;
+
+ case RT_TIMER_CTRL_SET_FUNC:
+ timer->timeout_func = (void (*)(void *))arg;
+ break;
+
+ case RT_TIMER_CTRL_GET_PARM:
+ *(void **)arg = timer->parameter;
+ break;
+
+ case RT_TIMER_CTRL_SET_PARM:
+ timer->parameter = arg;
+ break;
+
+ default:
+ break;
+ }
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+
+ return RT_EOK;
+}
+
+rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer)
+{
+ rt_base_t level;
+
+ /* parameter check */
+ RT_ASSERT(timer != RT_NULL);
+
+ level = rt_spin_lock_irqsave(&_spinlock);
+ rt_list_remove(&timer->row);
+ /* stop timer */
+ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
+ rt_spin_unlock_irqrestore(&_spinlock, level);
+
+ _set_next_timeout();
+
+ rt_sem_detach(&(timer->sem));
+
+ return RT_EOK;
+}
+
+/************************** delay ***************************/
+
+rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt)
+{
+ struct rt_ktime_hrtimer timer;
+
+ if (cnt == 0)
+ return -RT_EINVAL;
+
+ rt_ktime_hrtimer_init(&timer, "hrtimer_sleep", cnt, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
+ _sleep_timeout, &(timer.sem));
+
+ rt_ktime_hrtimer_start(&timer); /* reset the timeout of thread timer and start it */
+ rt_sem_take_interruptible(&(timer.sem), RT_WAITING_FOREVER);
+
+ rt_ktime_hrtimer_detach(&timer);
+ return RT_EOK;
+}
+
+rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns)
+{
+ unsigned long res = rt_ktime_cputimer_getres();
+ return rt_ktime_hrtimer_sleep((ns * RT_KTIME_RESMUL) / res);
+}
+
+rt_err_t rt_ktime_hrtimer_udelay(unsigned long us)
+{
+ return rt_ktime_hrtimer_ndelay(us * 1000);
+}
+
+rt_err_t rt_ktime_hrtimer_mdelay(unsigned long ms)
+{
+ return rt_ktime_hrtimer_ndelay(ms * 1000000);
+}
+
+static int rt_ktime_hrtimer_lock_init(void)
+{
+ RT_UNUSED(_spinlock);
+ rt_spin_lock_init(&_spinlock);
+ return 0;
+}
+INIT_BOARD_EXPORT(rt_ktime_hrtimer_lock_init);
diff --git a/components/ktime/src/risc-v/virt64/cputimer.c b/components/ktime/src/risc-v/virt64/cputimer.c
new file mode 100644
index 0000000000..9b0f754751
--- /dev/null
+++ b/components/ktime/src/risc-v/virt64/cputimer.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023-07-10 xqyjlj The first version.
+ */
+
+#include "ktime.h"
+
+unsigned long rt_ktime_cputimer_getres(void)
+{
+ return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / CPUTIME_TIMER_FREQ;
+}
+
+unsigned long rt_ktime_cputimer_getfrq(void)
+{
+ return CPUTIME_TIMER_FREQ;
+}
+
+unsigned long rt_ktime_cputimer_getcnt(void)
+{
+ unsigned long time_elapsed;
+ __asm__ __volatile__("rdtime %0" : "=r"(time_elapsed));
+ return time_elapsed;
+}
+
+unsigned long rt_ktime_cputimer_getstep(void)
+{
+ return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND;
+}
diff --git a/components/libc/compilers/common/ctime.c b/components/libc/compilers/common/ctime.c
index 0e148ef56f..ea31cf753d 100644
--- a/components/libc/compilers/common/ctime.c
+++ b/components/libc/compilers/common/ctime.c
@@ -19,13 +19,16 @@
* 2021-03-15 Meco Man fixed a bug of leaking memory in asctime()
* 2021-05-01 Meco Man support fixed timezone
* 2021-07-21 Meco Man implement that change/set timezone APIs
+ * 2023-07-03 xqyjlj refactor posix time and timer
*/
#include "sys/time.h"
-#include <sys/errno.h>
-#include <rtthread.h>
+#include <ktime.h>
#include <rthw.h>
+#include <rtthread.h>
+#include <sys/errno.h>
#include <unistd.h>
+#include "drivers/rtc.h"
#ifdef RT_USING_SMART
#include "lwp.h"
#endif
@@ -82,69 +85,12 @@ static void num2str(char *c, int i)
c[1] = i % 10 + '0';
}
-/**
- * Get time from RTC device (without timezone, UTC+0)
- * @param tv: struct timeval
- * @return the operation status, RT_EOK on successful
- */
-static rt_err_t get_timeval(struct timeval *tv)
-{
-#ifdef RT_USING_RTC
- static rt_device_t device = RT_NULL;
- rt_err_t rst = -RT_ERROR;
-
- if (tv == RT_NULL)
- return -RT_EINVAL;
-
- /* default is 0 */
- tv->tv_sec = 0;
- tv->tv_usec = 0;
-
- /* optimization: find rtc device only first */
- if (device == RT_NULL)
- {
- device = rt_device_find("rtc");
- }
-
- /* read timestamp from RTC device */
- if (device != RT_NULL)
- {
- if (rt_device_open(device, 0) == RT_EOK)
- {
- rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &tv->tv_sec);
- rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIMEVAL, tv);
- rt_device_close(device);
- }
- }
- else
- {
- LOG_W(_WARNING_NO_RTC);
- return -RT_ENOSYS;
- }
-
- return rst;
-
-#else
- LOG_W(_WARNING_NO_RTC);
- return -RT_ENOSYS;
-#endif /* RT_USING_RTC */
-}
-
-/**
- * Set time to RTC device (without timezone)
- * @param tv: struct timeval
- * @return the operation status, RT_EOK on successful
- */
-static int set_timeval(struct timeval *tv)
+static rt_err_t _control_rtc(int cmd, void *arg)
{
#ifdef RT_USING_RTC
static rt_device_t device = RT_NULL;
rt_err_t rst = -RT_ERROR;
- if (tv == RT_NULL)
- return -RT_EINVAL;
-
- /* optimization: find rtc device only first */
if (device == RT_NULL)
{
device = rt_device_find("rtc");
@@ -155,8 +101,7 @@ static int set_timeval(struct timeval *tv)
{
if (rt_device_open(device, 0) == RT_EOK)
{
- rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &tv->tv_sec);
- rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIMEVAL, tv);
+ rst = rt_device_control(device, cmd, arg);
rt_device_close(device);
}
}
@@ -165,9 +110,7 @@ static int set_timeval(struct timeval *tv)
LOG_W(_WARNING_NO_RTC);
return -RT_ENOSYS;
}
-
return rst;
-
#else
LOG_W(_WARNING_NO_RTC);
return -RT_ENOSYS;
@@ -351,51 +294,36 @@ RTM_EXPORT(strftime); /* inherent in the toolchain */
*/
rt_weak time_t time(time_t *t)
{
- struct timeval now;
+ time_t _t;
- if(get_timeval(&now) == RT_EOK)
- {
- if (t)
- {
- *t = now.tv_sec;
- }
- return now.tv_sec;
- }
- else
+ if (_control_rtc(RT_DEVICE_CTRL_RTC_GET_TIME, &_t) != RT_EOK)
{
rt_set_errno(EFAULT);
- return ((time_t)-1);
+ return -1;
}
+
+ if (t)
+ *t = _t;
+
+ return _t;
}
RTM_EXPORT(time);
rt_weak clock_t clock(void)
{
- return rt_tick_get();
+ return rt_tick_get(); // TODO should return cpu usage time
}
RTM_EXPORT(clock);
int stime(const time_t *t)
{
- struct timeval tv;
-
- if (t == RT_NULL)
- {
- rt_set_errno(EFAULT);
- return -1;
- }
-
- tv.tv_sec = *t;
- tv.tv_usec = 0;
- if (set_timeval(&tv) == RT_EOK)
+ if ((t != RT_NULL) && (_control_rtc(RT_DEVICE_CTRL_RTC_SET_TIME, (void *)t) == RT_EOK))
{
return 0;
}
- else
- {
- rt_set_errno(EFAULT);
- return -1;
- }
+
+ rt_set_errno(EFAULT);
+ return -1;
}
RTM_EXPORT(stime);
@@ -497,15 +425,17 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
tz->tz_minuteswest = -(tz_get() * 60);
}
- if (tv != RT_NULL && get_timeval(tv) == RT_EOK)
+ if (tv != RT_NULL)
{
- return 0;
- }
- else
- {
- rt_set_errno(EINVAL);
- return -1;
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+
+ if (_control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMEVAL, tv) == RT_EOK)
+ return 0;
}
+
+ rt_set_errno(EINVAL);
+ return -1;
}
RTM_EXPORT(gettimeofday);
@@ -516,111 +446,65 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
* The tz_dsttime field has never been used under Linux.
* Thus, the following is purely of historic interest.
*/
- if (tv != RT_NULL
- && tv->tv_usec >= 0
- && set_timeval((struct timeval *)tv) == RT_EOK)
+ if (tv != RT_NULL && tv->tv_usec >= 0 && tv->tv_sec >= 0)
{
- return 0;
- }
- else
- {
- rt_set_errno(EINVAL);
- return -1;
+ if (_control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMEVAL, (void *)tv) == RT_EOK)
+ return 0;
}
+
+ rt_set_errno(EINVAL);
+ return -1;
}
RTM_EXPORT(settimeofday);
#ifdef RT_USING_POSIX_DELAY
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
- if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND)
+ struct timespec old_ts = {0};
+ struct timespec new_ts = {0};
+
+ if (rqtp == RT_NULL)
{
- rt_set_errno(EINVAL);
+ rt_set_errno(EFAULT);
return -1;
}
-#ifdef RT_USING_CPUTIME
- rt_uint64_t unit = clock_cpu_getres();
- rt_uint64_t ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
- rt_uint64_t tick = (ns * (1000UL * 1000)) / unit;
- rt_cputime_sleep(tick);
- if (rt_get_errno() == -RT_EINTR)
+ if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND)
{
- if (rmtp)
- {
- uint64_t rmtp_cpu_tick = tick - clock_cpu_gettime();
- rmtp->tv_sec = ((time_t)((rmtp_cpu_tick * unit) / (1000UL * 1000))) / NANOSECOND_PER_SECOND;
- rmtp->tv_nsec = ((long)((rmtp_cpu_tick * unit) / (1000UL * 1000))) % NANOSECOND_PER_SECOND;
- }
- rt_set_errno(EINTR);
+ rt_set_errno(EINVAL);
return -1;
}
-#else
- rt_tick_t tick, tick_old = rt_tick_get();
- tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
- rt_thread_delay(tick);
-
+ unsigned long ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
+ rt_ktime_boottime_get_ns(&old_ts);
+ rt_ktime_hrtimer_ndelay(ns);
if (rt_get_errno() == -RT_EINTR)
{
if (rmtp)
{
- tick = tick_old + tick - rt_tick_get();
- /* get the passed time */
- rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
- rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
+ rt_ktime_boottime_get_ns(&new_ts);
+
+ rmtp->tv_sec = 0;
+ rmtp->tv_nsec =
+ (old_ts.tv_nsec + ns) - ((new_ts.tv_sec - old_ts.tv_sec) * NANOSECOND_PER_SECOND + new_ts.tv_nsec);
+
+ if (rmtp->tv_nsec > NANOSECOND_PER_SECOND)
+ {
+ rmtp->tv_nsec %= NANOSECOND_PER_SECOND;
+ rmtp->tv_sec += rmtp->tv_nsec / NANOSECOND_PER_SECOND;
+ }
}
rt_set_errno(EINTR);
return -1;
}
-#endif
return 0;
}
RTM_EXPORT(nanosleep);
#endif /* RT_USING_POSIX_DELAY */
#ifdef RT_USING_POSIX_CLOCK
-#ifdef RT_USING_RTC
-static volatile struct timeval _timevalue;
-static int _rt_clock_time_system_init(void)
-{
- rt_base_t level;
- time_t time = 0;
- rt_tick_t tick;
- rt_device_t device;
-
- device = rt_device_find("rtc");
- if (device != RT_NULL)
- {
- /* get realtime seconds */
- if(rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time) == RT_EOK)
- {
- level = rt_hw_interrupt_disable();
- tick = rt_tick_get(); /* get tick */
- _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
- _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1;
- rt_hw_interrupt_enable(level);
- return 0;
- }
- }
-
- level = rt_hw_interrupt_disable();
- _timevalue.tv_usec = 0;
- _timevalue.tv_sec = 0;
- rt_hw_interrupt_enable(level);
-
- return -1;
-}
-INIT_COMPONENT_EXPORT(_rt_clock_time_system_init);
-#endif /* RT_USING_RTC */
int clock_getres(clockid_t clockid, struct timespec *res)
{
-#ifndef RT_USING_RTC
- LOG_W(_WARNING_NO_RTC);
- return -1;
-#else
- int ret = 0;
-
if (res == RT_NULL)
{
rt_set_errno(EFAULT);
@@ -629,40 +513,29 @@ int clock_getres(clockid_t clockid, struct timespec *res)
switch (clockid)
{
- case CLOCK_REALTIME:
-#ifndef RT_USING_CPUTIME
- res->tv_sec = 0;
- res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND;
- break;
-#endif
-#ifdef RT_USING_CPUTIME
- case CLOCK_CPUTIME_ID:
- res->tv_sec = 0;
- res->tv_nsec = (clock_cpu_getres() / (1000UL * 1000));
- break;
-#endif
+ case CLOCK_REALTIME: // use RTC
+ case CLOCK_REALTIME_COARSE:
+ return _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMERES, res);
- default:
- res->tv_sec = 0;
- res->tv_nsec = 0;
- ret = -1;
- rt_set_errno(EINVAL);
- break;
- }
+ case CLOCK_MONOTONIC: // use cputimer
+ case CLOCK_MONOTONIC_COARSE:
+ case CLOCK_MONOTONIC_RAW:
+ case CLOCK_BOOTTIME:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
+ res->tv_sec = 0;
+ res->tv_nsec = (rt_ktime_cputimer_getres() / RT_KTIME_RESMUL);
+ return 0;
- return ret;
-#endif /* RT_USING_RTC */
+ default:
+ rt_set_errno(EINVAL);
+ return -1;
+ }
}
RTM_EXPORT(clock_getres);
int clock_gettime(clockid_t clockid, struct timespec *tp)
{
-#ifndef RT_USING_RTC
- LOG_W(_WARNING_NO_RTC);
- return -1;
-#else
- int ret = 0;
-
if (tp == RT_NULL)
{
rt_set_errno(EFAULT);
@@ -671,172 +544,117 @@ int clock_gettime(clockid_t clockid, struct timespec *tp)
switch (clockid)
{
- case CLOCK_REALTIME:
-#ifndef RT_USING_CPUTIME
- {
- rt_tick_t tick;
- rt_base_t level;
+ case CLOCK_REALTIME: // use RTC
+ case CLOCK_REALTIME_COARSE:
+ return _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMESPEC, tp);
- level = rt_hw_interrupt_disable();
- tick = rt_tick_get(); /* get tick */
- tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND;
- tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000U;
- rt_hw_interrupt_enable(level);
- if (tp->tv_nsec > 1000000000ULL)
- {
- tp->tv_nsec %= 1000000000ULL;
- tp->tv_sec += 1;
- }
- }
- break;
-#endif
-#ifdef RT_USING_CPUTIME
- case CLOCK_MONOTONIC:
- case CLOCK_CPUTIME_ID:
- {
- uint64_t unit = 0;
- uint64_t cpu_tick;
+ case CLOCK_MONOTONIC: // use boottime
+ case CLOCK_MONOTONIC_COARSE:
+ case CLOCK_MONOTONIC_RAW:
+ case CLOCK_BOOTTIME:
+ return rt_ktime_boottime_get_ns(tp);
- unit = clock_cpu_getres();
- cpu_tick = clock_cpu_gettime();
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
+ return rt_ktime_boottime_get_ns(tp); // TODO not yet implemented
- tp->tv_sec = ((uint64_t)((cpu_tick * unit) / (1000UL * 1000))) / NANOSECOND_PER_SECOND;
- tp->tv_nsec = ((uint64_t)((cpu_tick * unit) / (1000UL * 1000))) % NANOSECOND_PER_SECOND;
- }
- break;
-#endif
- default:
- tp->tv_sec = 0;
- tp->tv_nsec = 0;
- rt_set_errno(EINVAL);
- ret = -1;
+ default:
+ tp->tv_sec = 0;
+ tp->tv_nsec = 0;
+ rt_set_errno(EINVAL);
+ return -1;
}
-
- return ret;
-#endif /* RT_USING_RTC */
}
RTM_EXPORT(clock_gettime);
int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, struct timespec *rmtp)
{
-#ifndef RT_USING_RTC
- LOG_W(_WARNING_NO_RTC);
- return -1;
-#else
+ struct timespec ts = {0};
+ rt_err_t err;
+
+ if (rqtp == RT_NULL)
+ {
+ rt_set_errno(EFAULT);
+ return -1;
+ }
+
if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND)
{
rt_set_errno(EINVAL);
return -1;
}
+
switch (clockid)
{
- case CLOCK_REALTIME:
- {
- rt_tick_t tick, tick_old = rt_tick_get();
- if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
- {
- rt_int64_t ts = ((rqtp->tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND);
- rt_int64_t tns = (rqtp->tv_nsec - _timevalue.tv_usec * 1000) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
- tick = ts + tns;
- rt_tick_t rt_tick = rt_tick_get();
- tick = tick < rt_tick ? 0 : tick - rt_tick;
- }
- else
- {
- tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)(rqtp->tv_nsec) * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
- }
- rt_thread_delay(tick);
+ case CLOCK_REALTIME: // use RTC
+ if (flags & TIMER_ABSTIME)
+ err = _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMESPEC, &ts);
+ break;
- if (rt_get_errno() == -RT_EINTR)
- {
- if (rmtp)
- {
- tick = tick_old + tick - rt_tick_get();
- /* get the passed time */
- rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
- rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
- }
- rt_set_errno(EINTR);
+ case CLOCK_MONOTONIC: // use boottime
+ case CLOCK_PROCESS_CPUTIME_ID:
+ if (flags & TIMER_ABSTIME)
+ err = rt_ktime_boottime_get_ns(&ts);
+ break;
+
+ default:
+ rt_set_errno(EINVAL);
return -1;
- }
}
- break;
-#ifdef RT_USING_CPUTIME
- case CLOCK_MONOTONIC:
- case CLOCK_CPUTIME_ID:
- {
- rt_uint64_t cpu_tick_old = clock_cpu_gettime();
- uint64_t unit = clock_cpu_getres();
- rt_uint64_t ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
- rt_uint64_t tick = (ns * (1000UL * 1000)) / unit;
- if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
- tick -= cpu_tick_old;
- rt_cputime_sleep(tick);
+ if (err != RT_EOK)
+ return err;
- if (rt_get_errno() == -RT_EINTR)
- {
- if (rmtp)
- {
- uint64_t rmtp_cpu_tick = tick - clock_cpu_gettime();
- rmtp->tv_sec = ((time_t)((rmtp_cpu_tick * unit) / (1000UL * 1000))) / NANOSECOND_PER_SECOND;
- rmtp->tv_nsec = ((long)((rmtp_cpu_tick * unit) / (1000UL * 1000))) % NANOSECOND_PER_SECOND;
- }
- rt_set_errno(EINTR);
- return -1;
- }
+ int64_t ns = rqtp->tv_nsec - ts.tv_nsec + (rqtp->tv_sec - ts.tv_sec) * NANOSECOND_PER_SECOND;
+ if (ns <= 0)
+ return 0;
+
+ if (flags & TIMER_ABSTIME)
+ {
+ ts.tv_nsec = ns % NANOSECOND_PER_SECOND;
+ ts.tv_sec = ns / NANOSECOND_PER_SECOND;
+ return nanosleep(&ts, rmtp);
}
- break;
-#endif
- default:
- rt_set_errno(EINVAL);
- return -1;
+ else
+ {
+ return nanosleep(rqtp, rmtp);
}
- return 0;
-#endif
}
RTM_EXPORT(clock_nanosleep);
int clock_settime(clockid_t clockid, const struct timespec *tp)
{
-#ifndef RT_USING_RTC
- LOG_W(_WARNING_NO_RTC);
- return -1;
-#else
- rt_base_t level;
- int second;
- rt_tick_t tick;
- rt_device_t device;
-
- if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL))
+ if (tp == RT_NULL)
{
rt_set_errno(EFAULT);
return -1;
}
- /* get second */
- second = tp->tv_sec;
-
- level = rt_hw_interrupt_disable();
- tick = rt_tick_get(); /* get tick */
- /* update timevalue */
- _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK;
- _timevalue.tv_sec = second - tick / RT_TICK_PER_SECOND - 1;
- rt_hw_interrupt_enable(level);
-
- /* update for RTC device */
- device = rt_device_find("rtc");
- if (device != RT_NULL)
+ if (tp->tv_sec < 0 || tp->tv_nsec < 0 || tp->tv_nsec >= NANOSECOND_PER_SECOND)
{
- /* set realtime seconds */
- if(rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second) == RT_EOK)
- {
- return 0;
- }
+ rt_set_errno(EINVAL);
+ return -1;
}
- return -1;
-#endif /* RT_USING_RTC */
+ switch (clockid)
+ {
+ case CLOCK_REALTIME:
+ return _control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMESPEC, (void *)tp);
+
+ case CLOCK_REALTIME_COARSE:
+ case CLOCK_MONOTONIC:
+ case CLOCK_MONOTONIC_COARSE:
+ case CLOCK_MONOTONIC_RAW:
+ case CLOCK_BOOTTIME:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
+ rt_set_errno(EPERM);
+ return -1;
+
+ default:
+ rt_set_errno(EINVAL);
+ return -1;
+ }
}
RTM_EXPORT(clock_settime);
@@ -884,18 +702,12 @@ RTM_EXPORT(rt_timespec_to_tick);
struct timer_obj
{
- union
- {
- struct rt_timer timer;
-#ifdef RT_USING_CPUTIME
- struct rt_cputimer cputimer;
-#endif
- };
+ struct rt_ktime_hrtimer hrtimer;
void (*sigev_notify_function)(union sigval val);
union sigval val;
struct timespec interval; /* Reload value */
struct timespec value; /* Reload value */
- rt_uint64_t reload; /* Reload value in ms */
+ unsigned long reload; /* Reload value in ms */
rt_uint32_t status;
int sigev_signo;
clockid_t clockid;
@@ -915,21 +727,13 @@ static void rtthread_timer_wrapper(void *timerobj)
timer->status = NOT_ACTIVE;
}
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
+ timer->reload = ((timer->interval.tv_sec * NANOSECOND_PER_SECOND + timer->interval.tv_nsec) * RT_KTIME_RESMUL) /
+ rt_ktime_cputimer_getres();
+ if (timer->reload)
{
- timer->reload = ((timer->interval.tv_sec * NANOSECOND_PER_SECOND + timer->interval.tv_nsec) * (1000UL * 1000)) / clock_cpu_getres();
- if (timer->reload)
- rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
+ rt_ktime_hrtimer_control(&timer->hrtimer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
+ rt_ktime_hrtimer_start(&timer->hrtimer);
}
- else
-#endif /* RT_USING_CPUTIME */
- {
- timer->reload = (timer->interval.tv_sec * RT_TICK_PER_SECOND) + (timer->interval.tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
- if (timer->reload)
- rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
- }
-
#ifdef RT_USING_SMART
sys_kill(timer->pid, timer->sigev_signo);
#else
@@ -960,14 +764,33 @@ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
struct timer_obj *timer;
char timername[RT_NAME_MAX] = {0};
- if (clockid > CLOCK_ID_MAX ||
- (evp->sigev_notify != SIGEV_NONE &&
- evp->sigev_notify != SIGEV_SIGNAL))
+ if (evp == RT_NULL || timerid == RT_NULL)
+ {
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+
+ if (evp->sigev_notify == SIGEV_THREAD) // TODO need to implement
{
rt_set_errno(EINVAL);
return -1;
}
+ switch (clockid)
+ {
+ case CLOCK_REALTIME:
+ case CLOCK_REALTIME_ALARM:
+ case CLOCK_MONOTONIC:
+ case CLOCK_BOOTTIME:
+ case CLOCK_BOOTTIME_ALARM:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
+ break; // Only these ids are supported
+ default:
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+
timer = rt_malloc(sizeof(struct timer_obj));
if(timer == RT_NULL)
{
@@ -989,19 +812,8 @@ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
timer->status = NOT_ACTIVE;
timer->clockid = clockid;
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- {
- rt_cputimer_init(&timer->cputimer, timername, rtthread_timer_wrapper, timer, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
- }
- else
-#endif /* RT_USING_CPUTIME */
- {
- if (evp->sigev_notify == SIGEV_NONE)
- rt_timer_init(&timer->timer, timername, RT_NULL, RT_NULL, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
- else
- rt_timer_init(&timer->timer, timername, rtthread_timer_wrapper, timer, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
- }
+ rt_ktime_hrtimer_init(&timer->hrtimer, timername, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
+ rtthread_timer_wrapper, timer);
_timerid = resource_id_get(&id_timer);
if (_timerid < 0)
@@ -1048,28 +860,14 @@ int timer_delete(timer_t timerid)
return -1;
}
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- {
- if (timer->status == ACTIVE)
- {
- timer->status = NOT_ACTIVE;
- rt_cputimer_stop(&timer->cputimer);
- }
- rt_cputimer_detach(&timer->cputimer);
- }
- else
-#endif /* RT_USING_CPUTIME */
+ if (timer->status == ACTIVE)
{
- if (timer->status == ACTIVE)
- {
- timer->status = NOT_ACTIVE;
- rt_timer_stop(&timer->timer);
- }
- rt_timer_detach(&timer->timer);
+ timer->status = NOT_ACTIVE;
+ rt_ktime_hrtimer_stop(&timer->hrtimer);
}
- rt_free(timer);
+ rt_ktime_hrtimer_detach(&timer->hrtimer);
+ rt_free(timer);
return 0;
}
RTM_EXPORT(timer_delete);
@@ -1111,45 +909,11 @@ int timer_gettime(timer_t timerid, struct itimerspec *its)
if (timer->status == ACTIVE)
{
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- {
- rt_uint64_t remain_tick;
- rt_uint64_t remaining;
- rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_GET_REMAIN_TIME, &remain_tick);
- remaining = ((remain_tick - clock_cpu_gettime()) * (1000UL * 1000)) / clock_cpu_getres();
- seconds = remaining / NANOSECOND_PER_SECOND;
- nanoseconds = remaining % NANOSECOND_PER_SECOND;
- }
- else
-#endif /* RT_USING_CPUTIME */
- {
- rt_tick_t remain_tick;
- rt_tick_t remaining;
-
- rt_timer_control(&timer->timer, RT_TIMER_CTRL_GET_REMAIN_TIME, &remain_tick);
-
- /* 'remain_tick' is minimum-unit in the RT-Thread' timer,
- * so the seconds, nanoseconds will be calculated by 'remain_tick'.
- */
- remaining = remain_tick - rt_tick_get();
-
- /* calculate 'second' */
- seconds = remaining / RT_TICK_PER_SECOND;
-
- /* calculate 'nanosecond'; To avoid lost of accuracy, because "RT_TICK_PER_SECOND" maybe 100, 1000, 1024 and so on.
- *
- * remain_tick millisecond remain_tick * MILLISECOND_PER_SECOND
- * ------------------------- = -------------------------- ---> millisecond = -------------------------------------------
- * RT_TICK_PER_SECOND MILLISECOND_PER_SECOND RT_TICK_PER_SECOND
- *
- * remain_tick * MILLISECOND_PER_SECOND remain_tick * MILLISECOND_PER_SECOND * MICROSECOND_PER_SECOND
- * millisecond = ---------------------------------------- ---> nanosecond = -------------------------------------------------------------------
- * RT_TICK_PER_SECOND RT_TICK_PER_SECOND
- *
- */
- nanoseconds = (((remaining % RT_TICK_PER_SECOND) * MILLISECOND_PER_SECOND) * MICROSECOND_PER_SECOND) / RT_TICK_PER_SECOND;
- }
+ unsigned long remain_cnt;
+ rt_ktime_hrtimer_control(&timer->hrtimer, RT_TIMER_CTRL_GET_REMAIN_TIME, &remain_cnt);
+ nanoseconds = ((remain_cnt - rt_ktime_cputimer_getcnt()) * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
+ seconds = nanoseconds / NANOSECOND_PER_SECOND;
+ nanoseconds = nanoseconds % NANOSECOND_PER_SECOND;
its->it_value.tv_sec = (rt_int32_t)seconds;
its->it_value.tv_nsec = (rt_int32_t)nanoseconds;
}
@@ -1174,6 +938,9 @@ RTM_EXPORT(timer_gettime);
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
struct itimerspec *ovalue)
{
+ struct timespec ts = {0};
+ rt_err_t err = RT_EOK;
+
struct timer_obj *timer;
timer = _g_timerid[(rt_ubase_t)timerid];
if (timer == NULL ||
@@ -1199,97 +966,61 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
{
if (timer->status == ACTIVE)
{
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- rt_cputimer_stop(&timer->cputimer);
- else
-#endif /* RT_USING_CPUTIME */
- rt_timer_stop(&timer->timer);
+ rt_ktime_hrtimer_stop(&timer->hrtimer);
}
timer->status = NOT_ACTIVE;
return 0;
}
- /* calculate timer period(tick); To avoid lost of accuracy, because "RT_TICK_PER_SECOND" maybe 100, 1000, 1024 and so on.
- *
- * tick nanosecond nanosecond * RT_TICK_PER_SECOND
- * ------------------------- = -------------------------- ---> tick = -------------------------------------
- * RT_TICK_PER_SECOND NANOSECOND_PER_SECOND NANOSECOND_PER_SECOND
- *
- */
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- {
- rt_uint64_t tick;
- uint64_t unit = clock_cpu_getres();
-
- tick = ((value->it_value.tv_sec * NANOSECOND_PER_SECOND + value->it_value.tv_nsec) * (1000UL * 1000)) / unit;
- if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
- {
- tick -= clock_cpu_gettime();
- }
- timer->reload = tick;
- }
- else
-#endif /* RT_USING_CPUTIME */
+ switch (timer->clockid)
{
- if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME)
- {
-#ifndef RT_USING_RTC
- LOG_W(_WARNING_NO_RTC);
+ case CLOCK_REALTIME:
+ case CLOCK_REALTIME_ALARM:
+ if (flags & TIMER_ABSTIME)
+ err = _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMESPEC, &ts);
+ break;
+ case CLOCK_MONOTONIC:
+ case CLOCK_BOOTTIME:
+ case CLOCK_BOOTTIME_ALARM:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID:
+ if (flags & TIMER_ABSTIME)
+ err = rt_ktime_boottime_get_ns(&ts);
+ break;
+ default:
+ rt_set_errno(EINVAL);
return -1;
-#else
- rt_int64_t ts = ((value->it_value.tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND);
- rt_int64_t tns = (value->it_value.tv_nsec - _timevalue.tv_usec * 1000) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
- rt_int64_t reload = ts + tns;
- rt_tick_t rt_tick = rt_tick_get();
-
- timer->reload = reload < rt_tick ? 0 : reload - rt_tick;
-#endif
- }
- else
- timer->reload = (value->it_value.tv_sec * RT_TICK_PER_SECOND) + value->it_value.tv_nsec * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
}
- timer->interval.tv_sec = value->it_interval.tv_sec;
+
+ if (err != RT_EOK)
+ return err;
+
+ int64_t ns = value->it_value.tv_nsec - ts.tv_nsec + (value->it_value.tv_sec - ts.tv_sec) * NANOSECOND_PER_SECOND;
+
+ if (ns <= 0)
+ return 0;
+
+ unsigned long res = rt_ktime_cputimer_getres();
+ timer->reload = (ns * RT_KTIME_RESMUL) / res;
+ timer->interval.tv_sec = value->it_interval.tv_sec;
timer->interval.tv_nsec = value->it_interval.tv_nsec;
- timer->value.tv_sec = value->it_value.tv_sec;
- timer->value.tv_nsec = value->it_value.tv_nsec;
+ timer->value.tv_sec = value->it_value.tv_sec;
+ timer->value.tv_nsec = value->it_value.tv_nsec;
if (timer->status == ACTIVE)
{
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- rt_cputimer_stop(&timer->cputimer);
- else
-#endif /* RT_USING_CPUTIME */
- rt_timer_stop(&timer->timer);
+ rt_ktime_hrtimer_stop(&timer->hrtimer);
}
-
timer->status = ACTIVE;
-#ifdef RT_USING_CPUTIME
- if (timer->clockid == CLOCK_CPUTIME_ID && clock_cpu_issettimeout())
- {
- if ((value->it_interval.tv_sec == 0) && (value->it_interval.tv_nsec == 0))
- rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_ONESHOT, RT_NULL);
- else
- rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_PERIODIC, RT_NULL);
-
- rt_cputimer_control(&timer->cputimer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
- rt_cputimer_start(&timer->cputimer);
- }
+ if ((value->it_interval.tv_sec == 0) && (value->it_interval.tv_nsec == 0))
+ rt_ktime_hrtimer_control(&timer->hrtimer, RT_TIMER_CTRL_SET_ONESHOT, RT_NULL);
else
-#endif /* RT_USING_CPUTIME */
- {
- if ((value->it_interval.tv_sec == 0) && (value->it_interval.tv_nsec == 0))
- rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_ONESHOT, RT_NULL);
- else
- rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_PERIODIC, RT_NULL);
+ rt_ktime_hrtimer_control(&timer->hrtimer, RT_TIMER_CTRL_SET_PERIODIC, RT_NULL);
- rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
- rt_timer_start(&timer->timer);
- }
+ rt_ktime_hrtimer_control(&timer->hrtimer, RT_TIMER_CTRL_SET_TIME, &(timer->reload));
+ rt_ktime_hrtimer_start(&timer->hrtimer);
return 0;
}
diff --git a/components/libc/compilers/common/include/sys/time.h b/components/libc/compilers/common/include/sys/time.h
index 8be8d60f29..f1d8585383 100644
--- a/components/libc/compilers/common/include/sys/time.h
+++ b/components/libc/compilers/common/include/sys/time.h
@@ -139,8 +139,12 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
#if defined(RT_USING_POSIX_CLOCK) || defined (RT_USING_POSIX_TIMER)
/* POSIX clock and timer */
+#ifndef CLOCK_REALTIME_COARSE
+#define CLOCK_REALTIME_COARSE 0
+#endif /* CLOCK_REALTIME_COARSE */
+
#ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME 1
+#define CLOCK_REALTIME 1
#endif /* CLOCK_REALTIME */
#define CLOCK_CPUTIME_ID 2
@@ -150,13 +154,37 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
#endif /* CLOCK_PROCESS_CPUTIME_ID */
#ifndef CLOCK_THREAD_CPUTIME_ID
-#define CLOCK_THREAD_CPUTIME_ID CLOCK_CPUTIME_ID
+#define CLOCK_THREAD_CPUTIME_ID 3
#endif /* CLOCK_THREAD_CPUTIME_ID */
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC 4
#endif /* CLOCK_MONOTONIC */
+#ifndef CLOCK_MONOTONIC_RAW
+#define CLOCK_MONOTONIC_RAW 5
+#endif /* CLOCK_MONOTONIC_RAW */
+
+#ifndef CLOCK_MONOTONIC_COARSE
+#define CLOCK_MONOTONIC_COARSE 6
+#endif /* CLOCK_MONOTONIC_COARSE */
+
+#ifndef CLOCK_BOOTTIME
+#define CLOCK_BOOTTIME 7
+#endif /* CLOCK_BOOTTIME */
+
+#ifndef CLOCK_REALTIME_ALARM
+#define CLOCK_REALTIME_ALARM 8
+#endif /* CLOCK_REALTIME_ALARM */
+
+#ifndef CLOCK_BOOTTIME_ALARM
+#define CLOCK_BOOTTIME_ALARM 9
+#endif /* CLOCK_BOOTTIME_ALARM */
+
+#ifndef CLOCK_SGI_CYCLE
+#define CLOCK_SGI_CYCLE 10 // newlib says they don't have this definition, make the compiler happy
+#endif /* CLOCK_SGI_CYCLE */
+
#ifndef TIMER_ABSTIME
#define TIMER_ABSTIME 4
#endif /* TIMER_ABSTIME */
@@ -166,6 +194,11 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
#else
#define CLOCK_ID_MAX CLOCK_MONOTONIC
#endif
+
+#ifndef CLOCK_TAI
+#define CLOCK_TAI 11 // newlib says they don't have this definition, make the compiler happy
+#endif /* CLOCK_TAI */
+
#endif /* defined(RT_USING_POSIX_CLOCK) || defined (RT_USING_POSIX_TIMER) */
#ifdef RT_USING_POSIX_CLOCK
diff --git a/components/libc/posix/signal/posix_signal.c b/components/libc/posix/signal/posix_signal.c
index 25475bdbad..00d925ea57 100644
--- a/components/libc/posix/signal/posix_signal.c
+++ b/components/libc/posix/signal/posix_signal.c
@@ -172,7 +172,7 @@ int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *ti
if (timeout)
{
- tick = rt_timespec_to_tick(timeout);
+ tick = timeout->tv_sec * RT_TICK_PER_SECOND + timeout->tv_nsec * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;
}
ret = rt_signal_wait(set, info, tick);