Przeglądaj źródła

Add unified clock_time subsystem core implementation

Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
copilot-swe-agent[bot] 2 tygodni temu
rodzic
commit
7db0837774

+ 50 - 0
components/drivers/clock_time/Kconfig

@@ -0,0 +1,50 @@
+menuconfig RT_USING_CLOCK_TIME
+    bool "Using unified clock_time subsystem"
+    default n
+    help
+        Unified time subsystem that consolidates hwtimer, ktime, and cputime.
+        Provides clock source, clock event, and high-resolution timer support.
+
+if RT_USING_CLOCK_TIME
+
+    config RT_USING_CLOCK_HRTIMER
+        bool "Enable high-resolution timer support"
+        default y
+        help
+            Enable high-resolution software timers built on clock_time devices.
+            
+    config RT_USING_CLOCK_CPUTIME
+        bool "Enable CPU time APIs"
+        default y
+        help
+            Enable CPU time measurement and delay APIs.
+
+    config RT_USING_CLOCK_BOOTTIME
+        bool "Enable boottime APIs"
+        default y
+        help
+            Enable system boottime (monotonic time since boot) APIs.
+
+    # Backward compatibility options
+    config RT_USING_HWTIMER
+        bool
+        default y
+        help
+            Legacy option for backward compatibility with hwtimer.
+            Automatically enabled when RT_USING_CLOCK_TIME is enabled.
+
+    config RT_USING_KTIME
+        bool
+        default y if RT_USING_CLOCK_HRTIMER
+        help
+            Legacy option for backward compatibility with ktime.
+            Automatically enabled when RT_USING_CLOCK_HRTIMER is enabled.
+
+    config RT_USING_CPUTIME
+        bool
+        default y if RT_USING_CLOCK_CPUTIME
+        help
+            Legacy option for backward compatibility with cputime.
+            Automatically enabled when RT_USING_CLOCK_CPUTIME is enabled.
+
+endif

+ 28 - 0
components/drivers/clock_time/SConscript

@@ -0,0 +1,28 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = []
+inc = [cwd + '/inc']
+
+if GetDepend(['RT_USING_CLOCK_TIME']):
+    # Core clock_time device implementation
+    src += ['src/clock_time.c']
+    
+    # High-resolution timer support
+    if GetDepend(['RT_USING_CLOCK_HRTIMER']):
+        src += ['src/hrtimer.c']
+    
+    # CPU time APIs
+    if GetDepend(['RT_USING_CLOCK_CPUTIME']):
+        src += ['src/clock_time_cputime.c']
+    
+    # Boottime APIs  
+    if GetDepend(['RT_USING_CLOCK_BOOTTIME']):
+        src += ['src/clock_time_boottime.c']
+    
+    # Tick-based fallback implementation
+    src += ['src/clock_time_tick.c']
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = inc)
+
+Return('group')

+ 107 - 0
components/drivers/clock_time/src/clock_time.c

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2025-01-01     RT-Thread    Unified clock_time subsystem implementation
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/clock_time.h>
+
+#define DBG_TAG "clock_time"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+/* Default system clock time device */
+static rt_clock_time_t _default_device = RT_NULL;
+
+/**
+ * @brief Register a clock time device
+ */
+rt_err_t rt_clock_time_device_register(struct rt_clock_time_device *dev,
+                                        const char *name,
+                                        rt_uint8_t caps)
+{
+    rt_err_t result;
+    
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(name != RT_NULL);
+    RT_ASSERT(dev->ops != RT_NULL);
+    
+    /* Initialize parent device structure */
+    dev->parent.type = RT_Device_Class_Timer;
+    dev->parent.rx_indicate = RT_NULL;
+    dev->parent.tx_complete = RT_NULL;
+    
+    dev->parent.init = RT_NULL;
+    dev->parent.open = RT_NULL;
+    dev->parent.close = RT_NULL;
+    dev->parent.read = RT_NULL;
+    dev->parent.write = RT_NULL;
+    dev->parent.control = RT_NULL;
+    
+    dev->caps = caps;
+    
+    /* Calculate resolution scale factor */
+    if (dev->ops->get_freq)
+    {
+        rt_uint64_t freq = dev->ops->get_freq();
+        if (freq > 0)
+        {
+            /* res_scale = (1e9 * RT_CLOCK_TIME_RESMUL) / freq */
+            dev->res_scale = ((1000000000ULL * RT_CLOCK_TIME_RESMUL) / freq);
+        }
+        else
+        {
+            dev->res_scale = RT_CLOCK_TIME_RESMUL;
+        }
+    }
+    else
+    {
+        dev->res_scale = RT_CLOCK_TIME_RESMUL;
+    }
+    
+    /* Register device */
+    result = rt_device_register(&dev->parent, name, RT_DEVICE_FLAG_RDWR);
+    if (result != RT_EOK)
+    {
+        LOG_E("Failed to register clock_time device: %s", name);
+        return result;
+    }
+    
+    /* Set as default if none exists */
+    if (_default_device == RT_NULL)
+    {
+        _default_device = dev;
+        LOG_D("Set %s as default clock_time device", name);
+    }
+    
+    LOG_I("Registered clock_time device: %s (caps: 0x%02x)", name, caps);
+    
+    return RT_EOK;
+}
+
+/**
+ * @brief Get the default system clock time device
+ */
+rt_clock_time_t rt_clock_time_default(void)
+{
+    return _default_device;
+}
+
+/**
+ * @brief Set the default system clock time device
+ */
+rt_err_t rt_clock_time_set_default(rt_clock_time_t dev)
+{
+    RT_ASSERT(dev != RT_NULL);
+    
+    _default_device = dev;
+    LOG_D("Changed default clock_time device to: %s", dev->parent.parent.name);
+    
+    return RT_EOK;
+}

+ 49 - 0
components/drivers/clock_time/src/clock_time_boottime.c

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2025-01-01     RT-Thread    Boottime APIs implementation
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/clock_time.h>
+#include <sys/time.h>
+
+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;
+
+    tv->tv_sec  = ns / (1000ULL * 1000 * 1000);
+    tv->tv_usec = (ns % (1000ULL * 1000 * 1000)) / 1000;
+
+    return RT_EOK;
+}
+
+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;
+
+    *t = ns / (1000ULL * 1000 * 1000);
+
+    return RT_EOK;
+}
+
+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;
+
+    ts->tv_sec  = ns / (1000ULL * 1000 * 1000);
+    ts->tv_nsec = ns % (1000ULL * 1000 * 1000);
+
+    return RT_EOK;
+}

+ 30 - 0
components/drivers/clock_time/src/clock_time_cputime.c

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2025-01-01     RT-Thread    CPU time APIs (delegates to clock_time core)
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/clock_time.h>
+
+/*
+ * Additional CPU time utility functions
+ * Core implementations are in clock_time_tick.c
+ */
+
+/* These functions are implemented inline or use the core APIs */
+
+/* Note: The main cputime APIs are now:
+ *   rt_clock_cputimer_getres()
+ *   rt_clock_cputimer_getfrq()
+ *   rt_clock_cputimer_getcnt()
+ *   rt_clock_cputimer_init()
+ *
+ * These are defined in clock_time_tick.c as weak functions
+ * that can be overridden by BSP implementations.
+ */

+ 40 - 0
components/drivers/clock_time/src/clock_time_tick.c

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2025-01-01     RT-Thread    Tick-based fallback implementation for clock_time
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/clock_time.h>
+
+/*
+ * CPU Timer APIs - Default tick-based implementation
+ * These are weak functions that can be overridden by BSP-specific implementations
+ */
+
+rt_weak rt_uint64_t rt_clock_cputimer_getres(void)
+{
+    /* Resolution in nanoseconds * RT_CLOCK_TIME_RESMUL */
+    return ((1000ULL * 1000 * 1000) * RT_CLOCK_TIME_RESMUL) / RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_clock_cputimer_getfrq(void)
+{
+    return RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_clock_cputimer_getcnt(void)
+{
+    return rt_tick_get();
+}
+
+rt_weak void rt_clock_cputimer_init(void)
+{
+    /* Default: no initialization needed for tick-based implementation */
+    return;
+}

+ 386 - 0
components/drivers/clock_time/src/hrtimer.c

@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-07-10     xqyjlj       The first version (ktime)
+ * 2023-09-15     xqyjlj       perf rt_hw_interrupt_disable/enable
+ * 2025-01-01     RT-Thread    Migrated to unified clock_time subsystem
+ */
+
+#include <rtdevice.h>
+#include <rthw.h>
+#include <rtthread.h>
+#include <drivers/clock_time.h>
+
+#define DBG_SECTION_NAME               "clock.hrtimer"
+#define DBG_LEVEL                      DBG_INFO
+#include <rtdbg.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_DEFINE_SPINLOCK(_spinlock);
+
+rt_inline rt_clock_hrtimer_t _first_hrtimer(void)
+{
+    return rt_list_isempty(&_timer_list) ? RT_NULL : rt_list_first_entry(&_timer_list, struct rt_clock_hrtimer, node);
+}
+
+rt_weak rt_uint64_t rt_clock_hrtimer_getres(void)
+{
+    return ((1000ULL * 1000 * 1000) * RT_CLOCK_TIME_RESMUL) / RT_TICK_PER_SECOND;
+}
+
+rt_weak unsigned long rt_clock_hrtimer_getfrq(void)
+{
+    return RT_TICK_PER_SECOND;
+}
+
+rt_weak rt_err_t rt_clock_hrtimer_settimeout(unsigned long cnt)
+{
+    static rt_timer_t timer = RT_NULL;
+    static struct rt_timer _sh_rtimer;
+
+    RT_ASSERT(cnt > 0);
+
+    if (timer == RT_NULL)
+    {
+        timer = &_sh_rtimer;
+        rt_timer_init(timer, "shrtimer", (void (*)(void *))rt_clock_hrtimer_process, RT_NULL, 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, RT_NULL);
+    }
+
+    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)
+{
+    unsigned long rtn   = 0;
+    unsigned long count = cnt - rt_clock_cputimer_getcnt();
+    if (count > (_HRTIMER_MAX_CNT / 2))
+        return 0;
+
+    rtn = (count * rt_clock_cputimer_getres()) / rt_clock_hrtimer_getres();
+    return rtn == 0 ? 1 : rtn; /* at least 1 */
+}
+
+static void _sleep_timeout(void *parameter)
+{
+    struct rt_clock_hrtimer *timer = parameter;
+    rt_completion_done(&timer->completion);
+}
+
+static void _insert_timer_to_list_locked(rt_clock_hrtimer_t timer)
+{
+    rt_clock_hrtimer_t iter;
+
+    rt_list_for_each_entry(iter, &_timer_list, node)
+    {
+        if (iter->timeout_cnt > timer->timeout_cnt)
+        {
+            break;
+        }
+    }
+    rt_list_insert_before(&iter->node, &(timer->node));
+
+    timer->flag |= RT_TIMER_FLAG_ACTIVATED;
+}
+
+static void _hrtimer_process_locked(void)
+{
+    rt_clock_hrtimer_t timer;
+
+    for (timer = _first_hrtimer();
+        (timer != RT_NULL) && (timer->timeout_cnt <= rt_clock_cputimer_getcnt());
+        timer = _first_hrtimer())
+    {
+        rt_list_remove(&(timer->node));
+
+        if (timer->flag & RT_TIMER_FLAG_PERIODIC)
+        {
+            timer->timeout_cnt = timer->delay_cnt + rt_clock_cputimer_getcnt();
+            _insert_timer_to_list_locked(timer);
+        }
+        else
+        {
+            timer->flag &= ~RT_TIMER_FLAG_ACTIVATED;
+        }
+
+        if (timer->timeout_func)
+        {
+            timer->timeout_func(timer->parameter);
+        }
+    }
+}
+
+static void _set_next_timeout_locked(void)
+{
+    rt_clock_hrtimer_t timer;
+    rt_ubase_t next_timeout_hrtimer_cnt;
+    rt_bool_t find_next;
+
+    do
+    {
+        find_next = RT_FALSE;
+        if ((timer = _first_hrtimer()) != RT_NULL)
+        {
+            next_timeout_hrtimer_cnt = _cnt_convert(timer->timeout_cnt);
+            if (next_timeout_hrtimer_cnt > 0)
+            {
+                rt_clock_hrtimer_settimeout(next_timeout_hrtimer_cnt);
+            }
+            else
+            {
+                _hrtimer_process_locked();
+                find_next = RT_TRUE;
+            }
+        }
+    }
+    while (find_next);
+}
+
+void rt_clock_hrtimer_process(void)
+{
+    rt_base_t level = rt_spin_lock_irqsave(&_spinlock);
+
+    _hrtimer_process_locked();
+    _set_next_timeout_locked();
+
+    rt_spin_unlock_irqrestore(&_spinlock, level);
+}
+
+void rt_clock_hrtimer_init(rt_clock_hrtimer_t timer,
+                           const char        *name,
+                           rt_uint8_t         flag,
+                           void (*timeout)(void *parameter),
+                           void *parameter)
+{
+    /* parameter check */
+    RT_ASSERT(timer != RT_NULL);
+    RT_ASSERT(timeout != RT_NULL);
+
+    rt_memset(timer, 0, sizeof(struct rt_clock_hrtimer));
+
+    timer->flag         = flag & ~RT_TIMER_FLAG_ACTIVATED;
+    timer->timeout_func = timeout;
+    timer->parameter    = parameter;
+    rt_strncpy(timer->name, name, RT_NAME_MAX - 1);
+    rt_list_init(&(timer->node));
+    rt_completion_init(&timer->completion);
+}
+
+rt_err_t rt_clock_hrtimer_start(rt_clock_hrtimer_t timer, unsigned long delay_cnt)
+{
+    rt_base_t  level;
+
+    /* parameter check */
+    RT_ASSERT(timer != RT_NULL);
+    RT_ASSERT(delay_cnt < (_HRTIMER_MAX_CNT / 2));
+
+    timer->delay_cnt    = delay_cnt;
+    timer->timeout_cnt  = timer->delay_cnt + rt_clock_cputimer_getcnt();
+
+    level = rt_spin_lock_irqsave(&_spinlock);
+
+    if (timer->flag & RT_TIMER_FLAG_ACTIVATED)
+    {
+        rt_spin_unlock_irqrestore(&_spinlock, level);
+        return -RT_ERROR;
+    }
+
+    _insert_timer_to_list_locked(timer);
+    _set_next_timeout_locked();
+
+    rt_spin_unlock_irqrestore(&_spinlock, level);
+
+    return RT_EOK;
+}
+
+rt_err_t rt_clock_hrtimer_stop(rt_clock_hrtimer_t timer)
+{
+    rt_base_t level;
+
+    RT_ASSERT(timer != RT_NULL); /* timer check */
+
+    level = rt_spin_lock_irqsave(&_spinlock);
+
+    if (!(timer->flag & RT_TIMER_FLAG_ACTIVATED))
+    {
+        rt_spin_unlock_irqrestore(&_spinlock, level);
+        return -RT_ERROR;
+    }
+
+    rt_list_remove(&timer->node);
+    timer->flag &= ~RT_TIMER_FLAG_ACTIVATED;
+    _set_next_timeout_locked();
+
+    rt_spin_unlock_irqrestore(&_spinlock, level);
+
+    return RT_EOK;
+}
+
+rt_err_t rt_clock_hrtimer_control(rt_clock_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->delay_cnt;
+        break;
+
+    case RT_TIMER_CTRL_SET_TIME:
+        RT_ASSERT((*(unsigned long *)arg) < (_HRTIMER_MAX_CNT / 2));
+        timer->delay_cnt    = *(unsigned long *)arg;
+        timer->timeout_cnt  = *(unsigned long *)arg + rt_clock_cputimer_getcnt();
+        break;
+
+    case RT_TIMER_CTRL_SET_ONESHOT:
+        timer->flag &= ~RT_TIMER_FLAG_PERIODIC;
+        break;
+
+    case RT_TIMER_CTRL_SET_PERIODIC:
+        timer->flag |= RT_TIMER_FLAG_PERIODIC;
+        break;
+
+    case RT_TIMER_CTRL_GET_STATE:
+        if (timer->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_clock_hrtimer_detach(rt_clock_hrtimer_t timer)
+{
+    rt_base_t level;
+
+    /* parameter check */
+    RT_ASSERT(timer != RT_NULL);
+
+    /* notify the timer stop event */
+    rt_completion_wakeup_by_errno(&timer->completion, RT_ERROR);
+
+    level = rt_spin_lock_irqsave(&_spinlock);
+
+    /* stop timer */
+    timer->flag &= ~RT_TIMER_FLAG_ACTIVATED;
+    /* when interrupted */
+    if (timer->error == -RT_EINTR || timer->error == RT_EINTR)
+    {
+        rt_list_remove(&timer->node);
+        _set_next_timeout_locked();
+    }
+
+    rt_spin_unlock_irqrestore(&_spinlock, level);
+
+    return RT_EOK;
+}
+
+/************************** delay ***************************/
+
+void rt_clock_hrtimer_delay_init(struct rt_clock_hrtimer *timer)
+{
+    rt_clock_hrtimer_init(timer, "hrtimer_sleep", RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
+                          _sleep_timeout, timer);
+}
+
+void rt_clock_hrtimer_delay_detach(struct rt_clock_hrtimer *timer)
+{
+    rt_clock_hrtimer_detach(timer);
+}
+
+rt_err_t rt_clock_hrtimer_sleep(struct rt_clock_hrtimer *timer, unsigned long cnt)
+{
+    rt_err_t err;
+
+    if (cnt == 0)
+        return -RT_EINVAL;
+
+    err = rt_clock_hrtimer_start(timer, cnt);
+    if (err)
+        return err;
+
+    err = rt_completion_wait_flags(&(timer->completion), RT_WAITING_FOREVER,
+                                   RT_INTERRUPTIBLE);
+    rt_clock_hrtimer_keep_errno(timer, err);
+
+    return err;
+}
+
+rt_err_t rt_clock_hrtimer_ndelay(struct rt_clock_hrtimer *timer, unsigned long ns)
+{
+    rt_uint64_t res = rt_clock_cputimer_getres();
+    return rt_clock_hrtimer_sleep(timer, (ns * RT_CLOCK_TIME_RESMUL) / res);
+}
+
+rt_err_t rt_clock_hrtimer_udelay(struct rt_clock_hrtimer *timer, unsigned long us)
+{
+    return rt_clock_hrtimer_ndelay(timer, us * 1000);
+}
+
+rt_err_t rt_clock_hrtimer_mdelay(struct rt_clock_hrtimer *timer, unsigned long ms)
+{
+    return rt_clock_hrtimer_ndelay(timer, ms * 1000000);
+}

+ 349 - 0
components/drivers/include/drivers/clock_time.h

@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2025-01-01     RT-Thread    Unified clock_time subsystem (replaces hwtimer/ktime/cputime)
+ */
+
+#ifndef __CLOCK_TIME_H__
+#define __CLOCK_TIME_H__
+
+#include <rtthread.h>
+#include <sys/time.h>
+#include <ipc/completion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Resolution multiplier for time calculations */
+#define RT_CLOCK_TIME_RESMUL (1000000ULL)
+
+/* Clock time device capabilities */
+#define RT_CLOCK_TIME_CAP_CLOCKSOURCE   (1 << 0)  /* Device provides time source */
+#define RT_CLOCK_TIME_CAP_CLOCKEVENT    (1 << 1)  /* Device provides event generation */
+
+/**
+ * @brief Clock time device operations structure
+ * 
+ * This structure defines the hardware interface for clock/timer devices.
+ * BSPs should implement these operations for their specific hardware.
+ */
+struct rt_clock_time_ops
+{
+    /**
+     * Get the counting frequency in Hz
+     * @return Frequency in Hz
+     */
+    rt_uint64_t (*get_freq)(void);
+    
+    /**
+     * Get the current free-running counter value
+     * @return Current counter value
+     */
+    rt_uint64_t (*get_counter)(void);
+    
+    /**
+     * Set a timeout relative to current counter value
+     * @param delta Timeout in counter ticks (0 to cancel)
+     * @return RT_EOK on success, error code otherwise
+     */
+    rt_err_t (*set_timeout)(rt_uint64_t delta);
+};
+
+/**
+ * @brief Clock time device structure
+ * 
+ * Unified device abstraction for time sources and event generators.
+ * This replaces the separate hwtimer, ktime, and cputime devices.
+ */
+struct rt_clock_time_device
+{
+    struct rt_device parent;                    /* Standard device interface */
+    const struct rt_clock_time_ops *ops;        /* Hardware operations */
+    rt_uint64_t res_scale;                      /* Resolution scale factor */
+    rt_uint8_t caps;                            /* Device capabilities (RT_CLOCK_TIME_CAP_*) */
+};
+typedef struct rt_clock_time_device *rt_clock_time_t;
+
+/**
+ * @brief High-resolution timer structure
+ * 
+ * Software timer built on top of clock_time device.
+ * Compatible with rt_ktime_hrtimer interface.
+ */
+struct rt_clock_hrtimer
+{
+    rt_uint8_t flag;                            /* Timer flags (compatible with rt_timer) */
+    char name[RT_NAME_MAX];                     /* Timer name */
+    rt_list_t node;                             /* List node for timer management */
+    void *parameter;                            /* User parameter */
+    unsigned long delay_cnt;                    /* Delay count */
+    unsigned long timeout_cnt;                  /* Absolute timeout count */
+    rt_err_t error;                             /* Last error code */
+    struct rt_completion completion;            /* For synchronous waiting */
+    void (*timeout_func)(void *parameter);      /* Timeout callback */
+};
+typedef struct rt_clock_hrtimer *rt_clock_hrtimer_t;
+
+/*
+ * ============================================================================
+ * Device Management APIs
+ * ============================================================================
+ */
+
+/**
+ * @brief Register a clock time device
+ * 
+ * @param dev Clock time device to register
+ * @param name Device name (e.g., "cputimer", "hwtimer0")
+ * @param caps Device capabilities (RT_CLOCK_TIME_CAP_*)
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_time_device_register(struct rt_clock_time_device *dev, 
+                                        const char *name, 
+                                        rt_uint8_t caps);
+
+/**
+ * @brief Get the default system clock time device
+ * @return Pointer to default device, or RT_NULL if none
+ */
+rt_clock_time_t rt_clock_time_default(void);
+
+/**
+ * @brief Set the default system clock time device
+ * @param dev Device to set as default
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_time_set_default(rt_clock_time_t dev);
+
+/*
+ * ============================================================================
+ * Clock Source APIs (Boottime)
+ * ============================================================================
+ */
+
+/**
+ * @brief Get boottime with microsecond precision
+ * @param tv Output timeval structure
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_boottime_get_us(struct timeval *tv);
+
+/**
+ * @brief Get boottime with second precision
+ * @param t Output time_t value
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_boottime_get_s(time_t *t);
+
+/**
+ * @brief Get boottime with nanosecond precision
+ * @param ts Output timespec structure
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_boottime_get_ns(struct timespec *ts);
+
+/*
+ * ============================================================================
+ * CPU Timer APIs (Clock Source)
+ * ============================================================================
+ */
+
+/**
+ * @brief Get CPU timer resolution (resolution * RT_CLOCK_TIME_RESMUL)
+ * @return Resolution value
+ */
+rt_uint64_t rt_clock_cputimer_getres(void);
+
+/**
+ * @brief Get CPU timer frequency in Hz
+ * @return Frequency in Hz
+ */
+unsigned long rt_clock_cputimer_getfrq(void);
+
+/**
+ * @brief Get current CPU timer counter value
+ * @return Counter value
+ */
+unsigned long rt_clock_cputimer_getcnt(void);
+
+/**
+ * @brief Initialize CPU timer subsystem
+ */
+void rt_clock_cputimer_init(void);
+
+/*
+ * ============================================================================
+ * High-Resolution Timer APIs
+ * ============================================================================
+ */
+
+/**
+ * @brief Get hrtimer resolution (resolution * RT_CLOCK_TIME_RESMUL)
+ * @return Resolution value
+ */
+rt_uint64_t rt_clock_hrtimer_getres(void);
+
+/**
+ * @brief Get hrtimer frequency in Hz
+ * @return Frequency in Hz
+ */
+unsigned long rt_clock_hrtimer_getfrq(void);
+
+/**
+ * @brief Set hrtimer interrupt timeout (BSP should implement)
+ * @param cnt Timeout in counter ticks
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_settimeout(unsigned long cnt);
+
+/**
+ * @brief Process expired hrtimers (call from ISR)
+ */
+void rt_clock_hrtimer_process(void);
+
+/**
+ * @brief Initialize a high-resolution timer
+ * 
+ * @param timer Timer structure to initialize
+ * @param name Timer name
+ * @param flag Timer flags (RT_TIMER_FLAG_*)
+ * @param timeout Timeout callback function
+ * @param parameter User parameter for callback
+ */
+void rt_clock_hrtimer_init(rt_clock_hrtimer_t timer,
+                            const char *name,
+                            rt_uint8_t flag,
+                            void (*timeout)(void *parameter),
+                            void *parameter);
+
+/**
+ * @brief Start a high-resolution timer
+ * @param timer Timer to start
+ * @param cnt Timeout in counter ticks
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_start(rt_clock_hrtimer_t timer, unsigned long cnt);
+
+/**
+ * @brief Stop a high-resolution timer
+ * @param timer Timer to stop
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_stop(rt_clock_hrtimer_t timer);
+
+/**
+ * @brief Control a high-resolution timer
+ * @param timer Timer to control
+ * @param cmd Control command
+ * @param arg Command argument
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_control(rt_clock_hrtimer_t timer, int cmd, void *arg);
+
+/**
+ * @brief Detach a high-resolution timer
+ * @param timer Timer to detach
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_detach(rt_clock_hrtimer_t timer);
+
+/**
+ * @brief Keep errno in timer structure
+ * @param timer Timer structure
+ * @param err Error code to keep
+ */
+rt_inline void rt_clock_hrtimer_keep_errno(rt_clock_hrtimer_t timer, rt_err_t err)
+{
+    RT_ASSERT(timer != RT_NULL);
+    timer->error = err;
+    rt_set_errno(-err);
+}
+
+/**
+ * @brief Initialize timer for delay operations
+ * @param timer Timer structure
+ */
+void rt_clock_hrtimer_delay_init(struct rt_clock_hrtimer *timer);
+
+/**
+ * @brief Detach timer after delay operations
+ * @param timer Timer structure
+ */
+void rt_clock_hrtimer_delay_detach(struct rt_clock_hrtimer *timer);
+
+/**
+ * @brief Sleep for specified counter ticks
+ * @param timer Timer structure to use
+ * @param cnt Number of counter ticks to sleep
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_sleep(struct rt_clock_hrtimer *timer, unsigned long cnt);
+
+/**
+ * @brief Delay for specified nanoseconds
+ * @param timer Timer structure to use
+ * @param ns Nanoseconds to delay
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_ndelay(struct rt_clock_hrtimer *timer, unsigned long ns);
+
+/**
+ * @brief Delay for specified microseconds
+ * @param timer Timer structure to use
+ * @param us Microseconds to delay
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_udelay(struct rt_clock_hrtimer *timer, unsigned long us);
+
+/**
+ * @brief Delay for specified milliseconds
+ * @param timer Timer structure to use
+ * @param ms Milliseconds to delay
+ * @return RT_EOK on success, error code otherwise
+ */
+rt_err_t rt_clock_hrtimer_mdelay(struct rt_clock_hrtimer *timer, unsigned long ms);
+
+/*
+ * ============================================================================
+ * Legacy Compatibility Macros (Will be removed in future versions)
+ * ============================================================================
+ */
+
+/* Compatibility with rt_ktime_* APIs */
+#define RT_KTIME_RESMUL                     RT_CLOCK_TIME_RESMUL
+#define rt_ktime_hrtimer                    rt_clock_hrtimer
+#define rt_ktime_hrtimer_t                  rt_clock_hrtimer_t
+#define rt_ktime_boottime_get_us            rt_clock_boottime_get_us
+#define rt_ktime_boottime_get_s             rt_clock_boottime_get_s
+#define rt_ktime_boottime_get_ns            rt_clock_boottime_get_ns
+#define rt_ktime_cputimer_getres            rt_clock_cputimer_getres
+#define rt_ktime_cputimer_getfrq            rt_clock_cputimer_getfrq
+#define rt_ktime_cputimer_getcnt            rt_clock_cputimer_getcnt
+#define rt_ktime_cputimer_init              rt_clock_cputimer_init
+#define rt_ktime_hrtimer_getres             rt_clock_hrtimer_getres
+#define rt_ktime_hrtimer_getfrq             rt_clock_hrtimer_getfrq
+#define rt_ktime_hrtimer_settimeout         rt_clock_hrtimer_settimeout
+#define rt_ktime_hrtimer_process            rt_clock_hrtimer_process
+#define rt_ktime_hrtimer_init               rt_clock_hrtimer_init
+#define rt_ktime_hrtimer_start              rt_clock_hrtimer_start
+#define rt_ktime_hrtimer_stop               rt_clock_hrtimer_stop
+#define rt_ktime_hrtimer_control            rt_clock_hrtimer_control
+#define rt_ktime_hrtimer_detach             rt_clock_hrtimer_detach
+#define rt_ktime_hrtimer_keep_errno         rt_clock_hrtimer_keep_errno
+#define rt_ktime_hrtimer_delay_init         rt_clock_hrtimer_delay_init
+#define rt_ktime_hrtimer_delay_detach       rt_clock_hrtimer_delay_detach
+#define rt_ktime_hrtimer_sleep              rt_clock_hrtimer_sleep
+#define rt_ktime_hrtimer_ndelay             rt_clock_hrtimer_ndelay
+#define rt_ktime_hrtimer_udelay             rt_clock_hrtimer_udelay
+#define rt_ktime_hrtimer_mdelay             rt_clock_hrtimer_mdelay
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLOCK_TIME_H__ */

+ 113 - 0
components/drivers/include/drivers/hwtimer_compat.h

@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2025-01-01     RT-Thread    Compatibility layer for legacy hwtimer API
+ *
+ * DEPRECATED: This header provides backward compatibility for the legacy hwtimer API.
+ * New code should use the unified clock_time subsystem instead.
+ * This compatibility layer will be removed in a future release.
+ */
+
+#ifndef __HWTIMER_H__
+#define __HWTIMER_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 
+ * For backward compatibility, we keep the hwtimer types and APIs.
+ * If RT_USING_CLOCK_TIME is defined, these will map to clock_time.
+ * Otherwise, we include the original hwtimer implementation.
+ */
+
+#ifdef RT_USING_CLOCK_TIME
+
+/* Timer Control Command */
+typedef enum
+{
+    HWTIMER_CTRL_FREQ_SET = RT_DEVICE_CTRL_BASE(Timer) + 0x01,           /* set the count frequency */
+    HWTIMER_CTRL_STOP = RT_DEVICE_CTRL_BASE(Timer) + 0x02,               /* stop timer */
+    HWTIMER_CTRL_INFO_GET = RT_DEVICE_CTRL_BASE(Timer) + 0x03,           /* get a timer feature information */
+    HWTIMER_CTRL_MODE_SET = RT_DEVICE_CTRL_BASE(Timer) + 0x04            /* Setting the timing mode(oneshot/period) */
+} rt_hwtimer_ctrl_t;
+
+/* Timing Mode */
+typedef enum
+{
+    HWTIMER_MODE_ONESHOT = 0x01,
+    HWTIMER_MODE_PERIOD
+} rt_hwtimer_mode_t;
+
+/* Time Value */
+typedef struct rt_hwtimerval
+{
+    rt_int32_t sec;      /* second */
+    rt_int32_t usec;     /* microsecond */
+} rt_hwtimerval_t;
+
+#define HWTIMER_CNTMODE_UP      0x01 /* increment count mode */
+#define HWTIMER_CNTMODE_DW      0x02 /* decreasing count mode */
+
+struct rt_hwtimer_device;
+
+struct rt_hwtimer_ops
+{
+    void (*init)(struct rt_hwtimer_device *timer, rt_uint32_t state);
+    rt_err_t (*start)(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
+    void (*stop)(struct rt_hwtimer_device *timer);
+    rt_uint32_t (*count_get)(struct rt_hwtimer_device *timer);
+    rt_err_t (*control)(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args);
+};
+
+/* Timer Feature Information */
+struct rt_hwtimer_info
+{
+    rt_int32_t maxfreq;    /* the maximum count frequency timer support */
+    rt_int32_t minfreq;    /* the minimum count frequency timer support */
+    rt_uint32_t maxcnt;    /* counter maximum value */
+    rt_uint8_t  cntmode;   /* count mode (inc/dec) */
+};
+
+typedef struct rt_hwtimer_device
+{
+    struct rt_device parent;
+    const struct rt_hwtimer_ops *ops;
+    const struct rt_hwtimer_info *info;
+
+    rt_int32_t freq;                /* counting frequency set by the user */
+    rt_int32_t overflow;            /* timer overflows */
+    float period_sec;
+    rt_int32_t cycles;              /* how many times will generate a timeout event after overflow */
+    rt_int32_t reload;              /* reload cycles(using in period mode) */
+    rt_hwtimer_mode_t mode;         /* timing mode(oneshot/period) */
+} rt_hwtimer_t;
+
+rt_err_t rt_device_hwtimer_register(rt_hwtimer_t *timer, const char *name, void *user_data);
+void rt_device_hwtimer_isr(rt_hwtimer_t *timer);
+
+#ifdef RT_USING_DM
+extern void (*rt_device_hwtimer_us_delay)(rt_uint32_t us);
+#endif
+
+#else /* !RT_USING_CLOCK_TIME */
+
+#warning "RT_USING_HWTIMER is deprecated. Please migrate to RT_USING_CLOCK_TIME."
+#warning "Include <drivers/clock_time.h> instead and use rt_clock_time_* APIs."
+
+/* If clock_time is not enabled, this means the old hwtimer module should still exist */
+/* The build system should handle this by including the old hwtimer directory */
+
+#endif /* RT_USING_CLOCK_TIME */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HWTIMER_H__ */