This is an automated email from the ASF dual-hosted git repository.

archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit ed1cb6f9b81d1155a7ea83dc089d523364a3d021
Author: wangchengdong <[email protected]>
AuthorDate: Fri Dec 12 13:54:48 2025 +0800

    sched/hrtimer: Add high-resolution timer support for NuttX
    
    NuttX provides the wdog module to implement timers for the scheduler.
    While it is lightweight and efficient, wdog only supports tick-level timers,
    typically in milliseconds. Although the tick duration can be configured,
    setting it to microsecond or nanosecond resolution is not practical.
    Doing so may cause an interrupt storm, where the CPU is constantly
    occupied handling tick interrupts.
    
    To address this limitation, a new hrtimer module is introduced.
    It coexists with the wdog module, providing both tick-level timers
    for wdog and high-resolution timers (nanosecond-level) directly to users.
    
    Signed-off-by: Chengdong Wang <[email protected]>
---
 .../tc397/a2g-tc397-5v-tft/configs/nsh/defconfig   |   1 +
 include/nuttx/hrtimer.h                            | 198 +++++++++++++++++++++
 sched/Kconfig                                      |   6 +
 sched/hrtimer/CMakeLists.txt                       |  30 ++++
 sched/hrtimer/Make.defs                            |  32 ++++
 sched/hrtimer/hrtimer.h                            | 176 ++++++++++++++++++
 sched/hrtimer/hrtimer_cancel.c                     | 140 +++++++++++++++
 sched/hrtimer/hrtimer_initialize.c                 |  79 ++++++++
 sched/hrtimer/hrtimer_process.c                    | 143 +++++++++++++++
 sched/hrtimer/hrtimer_start.c                      | 148 +++++++++++++++
 10 files changed, 953 insertions(+)

diff --git a/boards/tricore/tc397/a2g-tc397-5v-tft/configs/nsh/defconfig 
b/boards/tricore/tc397/a2g-tc397-5v-tft/configs/nsh/defconfig
index 151937b177c..6c107694a51 100644
--- a/boards/tricore/tc397/a2g-tc397-5v-tft/configs/nsh/defconfig
+++ b/boards/tricore/tc397/a2g-tc397-5v-tft/configs/nsh/defconfig
@@ -53,3 +53,4 @@ CONFIG_TESTING_GETPRIME=y
 CONFIG_TESTING_OSTEST=y
 CONFIG_UART0_SERIAL_CONSOLE=y
 CONFIG_SCHED_EVENTS=y
+CONFIG_HRTIMER=y
\ No newline at end of file
diff --git a/include/nuttx/hrtimer.h b/include/nuttx/hrtimer.h
new file mode 100644
index 00000000000..ddbff6707d6
--- /dev/null
+++ b/include/nuttx/hrtimer.h
@@ -0,0 +1,198 @@
+/****************************************************************************
+ * include/nuttx/hrtimer.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_HRTIMER_H
+#define __INCLUDE_NUTTX_HRTIMER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/clock.h>
+#include <nuttx/compiler.h>
+#include <nuttx/spinlock.h>
+
+#include <stdint.h>
+#include <sys/tree.h>
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* High-resolution timer modes
+ *
+ * HRTIMER_MODE_ABS - Absolute expiration time
+ * HRTIMER_MODE_REL - Relative timeout from the current time
+ */
+
+enum hrtimer_mode_e
+{
+  HRTIMER_MODE_ABS = 0,  /* Absolute expiration time */
+  HRTIMER_MODE_REL       /* Relative delay from now */
+};
+
+/* High-resolution timer states
+ *
+ * State transitions are managed internally by the hrtimer framework.
+ * Callers must not modify the state directly.
+ */
+
+enum hrtimer_state_e
+{
+  HRTIMER_STATE_INACTIVE = 0, /* Timer is inactive and not queued */
+  HRTIMER_STATE_ARMED,        /* Timer is armed and waiting for expiry */
+  HRTIMER_STATE_RUNNING,      /* Timer callback is currently executing */
+  HRTIMER_STATE_CANCELED      /* Timer canceled (callback may be running) */
+};
+
+/* Forward declarations */
+
+struct hrtimer_s;
+struct hrtimer_node_s;
+
+typedef struct hrtimer_s      hrtimer_t;
+typedef struct hrtimer_node_s hrtimer_node_t;
+
+/* Callback type for high-resolution timer expiration
+ *
+ * The callback is invoked when the timer expires. It is executed in
+ * timer context and must not block.
+ */
+
+typedef uint32_t (*hrtimer_cb)(FAR struct hrtimer_s *hrtimer);
+
+/* Red-black tree node used to order hrtimers by expiration time */
+
+struct hrtimer_node_s
+{
+  RB_ENTRY(hrtimer_node_s) entry;  /* RB-tree linkage */
+};
+
+/* High-resolution timer object
+ *
+ * The timer is ordered by absolute expiration time and managed by the
+ * hrtimer core. The content of this structure should not be accessed
+ * directly by users except through the provided APIs.
+ */
+
+struct hrtimer_s
+{
+  hrtimer_node_t          node;    /* RB-tree node for sorted insertion */
+  enum hrtimer_state_e    state;   /* Current timer state */
+  hrtimer_cb              func;    /* Expiration callback function */
+  FAR void               *arg;     /* Argument passed to callback */
+  uint64_t                expired; /* Absolute expiration time (ns) */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: hrtimer_init
+ *
+ * Description:
+ *   Initialize a high-resolution timer instance. This function sets the
+ *   expiration callback and its argument. The timer is initialized in the
+ *   inactive state and is not armed until hrtimer_start() is called.
+ *
+ * Input Parameters:
+ *   hrtimer - Pointer to the hrtimer instance to be initialized
+ *   func    - Expiration callback function
+ *   arg     - Argument passed to the callback
+ *
+ * Returned Value:
+ *   None
+ ****************************************************************************/
+
+static inline_function
+void hrtimer_init(FAR hrtimer_t *hrtimer,
+                  hrtimer_cb func,
+                  FAR void *arg)
+{
+  hrtimer->state = HRTIMER_STATE_INACTIVE;
+  hrtimer->func  = func;
+  hrtimer->arg   = arg;
+}
+
+/****************************************************************************
+ * Name: hrtimer_cancel
+ *
+ * Description:
+ *   Cancel a high-resolution timer.
+ *
+ *   If the timer is armed but has not yet expired, it will be removed from
+ *   the timer queue and the callback will not be invoked.
+ *
+ *   If the timer callback is currently executing, this function will mark
+ *   the timer as canceled and return immediately. The running callback is
+ *   allowed to complete, but it will not be invoked again.
+ *
+ *   This function is non-blocking and does not wait for a running callback
+ *   to finish.
+ *
+ * Input Parameters:
+ *   hrtimer - Timer instance to cancel
+ *
+ * Returned Value:
+ *   OK on success; a negated errno value on failure.
+ ****************************************************************************/
+
+int hrtimer_cancel(FAR hrtimer_t *hrtimer);
+
+/****************************************************************************
+ * Name: hrtimer_start
+ *
+ * Description:
+ *   Start a high-resolution timer with the specified expiration time.
+ *
+ *   The expiration time may be specified as either an absolute time or
+ *   a relative timeout, depending on the selected mode.
+ *
+ * Input Parameters:
+ *   hrtimer - Timer instance to start
+ *   ns      - Expiration time in nanoseconds
+ *   mode    - HRTIMER_MODE_ABS or HRTIMER_MODE_REL
+ *
+ * Returned Value:
+ *   OK on success; a negated errno value on failure.
+ ****************************************************************************/
+
+int hrtimer_start(FAR hrtimer_t *hrtimer,
+                  uint64_t ns,
+                  enum hrtimer_mode_e mode);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_HRTIMER_H */
diff --git a/sched/Kconfig b/sched/Kconfig
index 4e17db70868..5370be5e5fa 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -2020,3 +2020,9 @@ config CUSTOM_SEMAPHORE_MAXVALUE
        ---help---
                Enable to support custom max value for semaphores.
                When this option is enabled, the max value of a semaphore can 
be set
+
+config HRTIMER
+       bool "High resolution timer support"
+       default n
+       ---help---
+               Enable to support high resolution timer
diff --git a/sched/hrtimer/CMakeLists.txt b/sched/hrtimer/CMakeLists.txt
new file mode 100644
index 00000000000..d7b0639dc25
--- /dev/null
+++ b/sched/hrtimer/CMakeLists.txt
@@ -0,0 +1,30 @@
+# 
##############################################################################
+# sched/hrtimer/CMakeLists.txt
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more 
contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may 
not
+# use this file except in compliance with the License.  You may obtain a copy 
of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+# 
##############################################################################
+
+# Add hrtimer-related files to the build
+set(CSRCS)
+if(CONFIG_HRTIMER)
+  list(APPEND CSRCS hrtimer_cancel.c hrtimer_initialize.c hrtimer_process.c
+       hrtimer_start.c)
+endif()
+
+target_sources(sched PRIVATE ${CSRCS})
diff --git a/sched/hrtimer/Make.defs b/sched/hrtimer/Make.defs
new file mode 100644
index 00000000000..65fb6ab3161
--- /dev/null
+++ b/sched/hrtimer/Make.defs
@@ -0,0 +1,32 @@
+############################################################################
+# sched/hrtimer/Make.defs
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# Add hrtimer-related files to the build
+
+ifeq ($(CONFIG_HRTIMER),y)
+  CSRCS += hrtimer_cancel.c hrtimer_initialize.c hrtimer_process.c 
hrtimer_start.c
+endif
+
+# Include hrtimer build support
+
+DEPPATH += --dep-path hrtimer
+VPATH += :hrtimer
diff --git a/sched/hrtimer/hrtimer.h b/sched/hrtimer/hrtimer.h
new file mode 100644
index 00000000000..de206e25eb7
--- /dev/null
+++ b/sched/hrtimer/hrtimer.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+ * sched/hrtimer/hrtimer.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_HRTIMER_HRTIMER_H
+#define __SCHED_HRTIMER_HRTIMER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include <nuttx/hrtimer.h>
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* Spinlock protecting access to the hrtimer RB-tree and timer state */
+
+extern spinlock_t g_hrtimer_spinlock;
+
+/* Red-Black tree containing all active high-resolution timers */
+
+extern struct hrtimer_tree_s g_hrtimer_tree;
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Red-black tree head for managing active hrtimers */
+
+RB_HEAD(hrtimer_tree_s, hrtimer_node_s);
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hrtimer_process
+ *
+ * Description:
+ *   Called from the timer interrupt handler to process expired
+ *   high-resolution timers. If a timer has expired, its callback
+ *   function will be executed in the context of the timer interrupt.
+ *
+ * Input Parameters:
+ *   now - The current time (nsecs).
+ *
+ * Returned Value:
+ *   None
+ ****************************************************************************/
+
+void hrtimer_process(uint64_t now);
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hrtimer_gettime
+ *
+ * Description:
+ *   Get the current high-resolution time in nanoseconds.
+ *
+ * Returned Value:
+ *   Current time in nanoseconds.
+ ****************************************************************************/
+
+static inline_function
+uint64_t hrtimer_gettime(void)
+{
+  struct timespec ts;
+
+  /* Get current time from platform-specific timer */
+
+  clock_systime_timespec(&ts);
+
+  /* Convert timespec to nanoseconds */
+
+  return clock_time2nsec(&ts);
+}
+
+/****************************************************************************
+ * Name: hrtimer_starttimer
+ *
+ * Description:
+ *   Start the hardware timer to expire at a specified nanosecond time.
+ *   Converts the nanosecond time to timespec and calls the platform-specific
+ *   timer start function.
+ *
+ * Input Parameters:
+ *   ns - Expiration time in nanoseconds.
+ *
+ * Returned Value:
+ *   OK (0) on success, negated errno on failure.
+ ****************************************************************************/
+
+static inline_function
+int hrtimer_starttimer(uint64_t ns)
+{
+  struct timespec ts;
+  int ret;
+
+  /* Convert nanoseconds to timespec */
+
+  clock_nsec2time(&ts, ns);
+
+#ifdef CONFIG_ALARM_ARCH
+  ret = up_alarm_start(&ts);
+#elif defined(CONFIG_TIMER_ARCH)
+  ret = up_timer_start(&ts);
+#endif
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: hrtimer_compare
+ *
+ * Description:
+ *   Compare two high-resolution timer nodes to determine their ordering
+ *   in the red-black tree. Used internally by the RB-tree macros.
+ *
+ * Input Parameters:
+ *   a - Pointer to the first hrtimer node.
+ *   b - Pointer to the second hrtimer node.
+ *
+ * Returned Value:
+ *   >0 if b expires before a
+ *    0 if a and b expire at the same time
+ *   <0 if b expires after a
+ ****************************************************************************/
+
+static inline_function
+int hrtimer_compare(FAR const hrtimer_node_t *a,
+                FAR const hrtimer_node_t *b)
+{
+  FAR const hrtimer_t *atimer = (FAR const hrtimer_t *)a;
+  FAR const hrtimer_t *btimer = (FAR const hrtimer_t *)b;
+
+  return clock_compare(atimer->expired, btimer->expired) ? -1 : 1;
+}
+
+/****************************************************************************
+ * Red-Black Tree Prototype for high-resolution timers
+ *
+ * Description:
+ *   Declare the RB-tree prototype that manages all active high-resolution
+ *   timers. This tree provides efficient insertion, removal, and lookup
+ *   operations based on timer expiration time.
+ ****************************************************************************/
+
+RB_PROTOTYPE(hrtimer_tree_s, hrtimer_node_s, entry, hrtimer_compare);
+
+#endif /* __SCHED_HRTIMER_HRTIMER_H */
diff --git a/sched/hrtimer/hrtimer_cancel.c b/sched/hrtimer/hrtimer_cancel.c
new file mode 100644
index 00000000000..44dc7b1784f
--- /dev/null
+++ b/sched/hrtimer/hrtimer_cancel.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * sched/hrtimer/hrtimer_cancel.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+
+#include <errno.h>
+
+#include "hrtimer/hrtimer.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hrtimer_cancel
+ *
+ * Description:
+ *   Cancel a high-resolution timer.
+ *
+ *   If the timer is currently armed, it will be removed from the active
+ *   hrtimer red-black tree and will not be executed.
+ *
+ *   If the timer callback is currently executing, the timer will be marked
+ *   as canceled. The running callback is allowed to complete, but it will
+ *   not be re-armed or executed again.
+ *
+ *   If the canceled timer was the earliest (head) timer in the tree, the
+ *   expiration of the underlying hardware timer will be updated to:
+ *
+ *     1. The expiration time of the next earliest timer, or
+ *     2. A safe default expiration if no timers remain.
+ *
+ *   This function is non-blocking and does not wait for a running callback
+ *   to finish.
+ *
+ * Input Parameters:
+ *   hrtimer - Pointer to the high-resolution timer instance to cancel.
+ *
+ * Returned Value:
+ *   OK (0) on success; a negated errno value on failure.
+ *
+ * Assumptions/Notes:
+ *   - This function acquires the global hrtimer spinlock to protect the
+ *     red-black tree and timer state.
+ *   - The caller must ensure that the timer structure is not freed until
+ *     it is guaranteed that any running callback has returned.
+ ****************************************************************************/
+
+int hrtimer_cancel(FAR hrtimer_t *hrtimer)
+{
+  FAR hrtimer_t *first;
+  irqstate_t flags;
+  int ret = OK;
+
+  DEBUGASSERT(hrtimer != NULL);
+
+  /* Enter critical section to protect the hrtimer tree and state */
+
+  flags = spin_lock_irqsave(&g_hrtimer_spinlock);
+
+  /* Capture the current earliest timer before removal */
+
+  first = (FAR hrtimer_t *)RB_MIN(hrtimer_tree_s, &g_hrtimer_tree);
+
+  switch (hrtimer->state)
+    {
+      case HRTIMER_STATE_ARMED:
+        {
+          /* Remove the timer from the active tree */
+
+          RB_REMOVE(hrtimer_tree_s, &g_hrtimer_tree, &hrtimer->node);
+          hrtimer->state = HRTIMER_STATE_INACTIVE;
+          break;
+        }
+
+      case HRTIMER_STATE_RUNNING:
+        {
+          /* The callback is currently executing.
+           *
+           * Mark the timer as canceled so it will not be re-armed or
+           * executed again. The running callback is allowed to complete.
+           *
+           * NOTE: The timer node is expected to have already been removed
+           *       from the tree when the callback started executing.
+           */
+
+          hrtimer->state = HRTIMER_STATE_CANCELED;
+          break;
+        }
+
+      case HRTIMER_STATE_INACTIVE:
+      case HRTIMER_STATE_CANCELED:
+      default:
+        {
+          ret = -EINVAL;
+          break;
+        }
+    }
+
+  /* If the canceled timer was the earliest one, update the hardware timer */
+
+  if ((ret == OK) && (first == hrtimer))
+    {
+      first = (FAR hrtimer_t *)RB_MIN(hrtimer_tree_s, &g_hrtimer_tree);
+      if (first != NULL)
+        {
+          ret = hrtimer_starttimer(first->expired);
+        }
+    }
+
+  /* Leave critical section */
+
+  spin_unlock_irqrestore(&g_hrtimer_spinlock, flags);
+  return ret;
+}
diff --git a/sched/hrtimer/hrtimer_initialize.c 
b/sched/hrtimer/hrtimer_initialize.c
new file mode 100644
index 00000000000..02ac80d3ce6
--- /dev/null
+++ b/sched/hrtimer/hrtimer_initialize.c
@@ -0,0 +1,79 @@
+/****************************************************************************
+ * sched/hrtimer/hrtimer_initialize.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "hrtimer/hrtimer.h"
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* Global spinlock protecting the high-resolution timer subsystem.
+ *
+ * This spinlock serializes access to the hrtimer red-black tree and
+ * protects timer state transitions. It must be held whenever the
+ * timer tree or hrtimer state is modified.
+ */
+
+spinlock_t g_hrtimer_spinlock = SP_UNLOCKED;
+
+/* Red-black tree containing all active high-resolution timers.
+ *
+ * Only timers in the ARMED state are present in this tree. Timers in
+ * the RUNNING, CANCELED, or INACTIVE states must not be inserted.
+ *
+ * The tree is ordered by absolute expiration time.
+ */
+
+struct hrtimer_tree_s g_hrtimer_tree =
+  RB_INITIALIZER(g_hrtimer_tree);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: RB_GENERATE
+ *
+ * Description:
+ *   Instantiate the red-black tree helper functions for the hrtimer
+ *   subsystem.
+ *
+ *   This macro generates the static inline functions required to
+ *   manipulate the hrtimer red-black tree, including insertion,
+ *   removal, and lookup operations.
+ *
+ * Assumptions/Notes:
+ *   - The tree key is the absolute expiration time stored in
+ *     hrtimer_node_s and compared via hrtimer_compare().
+ *   - All accesses to the tree must be serialized using
+ *     g_hrtimer_spinlock.
+ *   - These generated functions are used internally by the hrtimer
+ *     core (e.g., hrtimer_start(), hrtimer_cancel(), and expire paths).
+ ****************************************************************************/
+
+RB_GENERATE(hrtimer_tree_s, hrtimer_node_s, entry, hrtimer_compare);
diff --git a/sched/hrtimer/hrtimer_process.c b/sched/hrtimer/hrtimer_process.c
new file mode 100644
index 00000000000..3e7a3c938f6
--- /dev/null
+++ b/sched/hrtimer/hrtimer_process.c
@@ -0,0 +1,143 @@
+/****************************************************************************
+ * sched/hrtimer/hrtimer_process.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <assert.h>
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include "hrtimer/hrtimer.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hrtimer_process
+ *
+ * Description:
+ *   Process all expired high-resolution timers. This function repeatedly
+ *   retrieves the earliest timer from the active timer RB-tree, checks if it
+ *   has expired relative to the current time, removes it from the tree,
+ *   and invokes its callback function. Processing continues until:
+ *
+ *     1. No additional timers have expired, or
+ *     2. The active timer set is empty.
+ *
+ *   After all expired timers are processed, the next expiration event is
+ *   scheduled based on:
+ *
+ *     - The earliest remaining timer, or
+ *     - A fallback expiration (current time + HRTIMER_DEFAULT_INCREMENT)
+ *       if no timers remain.
+ *
+ * Input Parameters:
+ *   ts - Pointer to the current high-resolution timestamp.
+ *
+ * Returned Value:
+ *   None.
+ *
+ * Assumptions/Notes:
+ *   - This function acquires a spinlock to protect the timer RB-tree.
+ *   - Timer callbacks are invoked with interrupts enabled
+ *     to avoid deadlocks.
+ *   - DEBUGASSERT ensures that timer callbacks are valid.
+ ****************************************************************************/
+
+void hrtimer_process(uint64_t now)
+{
+  FAR hrtimer_t *hrtimer;
+  uint64_t expired;
+  uint32_t period = 0;
+  irqstate_t flags;
+
+  /* Lock the hrtimer RB-tree to protect access */
+
+  flags = spin_lock_irqsave(&g_hrtimer_spinlock);
+
+  /* Fetch the earliest active timer */
+
+  hrtimer = (FAR hrtimer_t *)RB_MIN(hrtimer_tree_s, &g_hrtimer_tree);
+
+  while (hrtimer != NULL)
+    {
+      /* Check if the timer has expired */
+
+      if (!clock_compare(hrtimer->expired, now))
+        {
+          break;
+        }
+
+      /* Remove the expired timer from the active tree */
+
+      RB_REMOVE(hrtimer_tree_s, &g_hrtimer_tree, &hrtimer->node);
+
+      /* Ensure the timer callback is valid */
+
+      DEBUGASSERT(hrtimer->func != NULL);
+
+      hrtimer->state = HRTIMER_STATE_RUNNING;
+
+      spin_unlock_irqrestore(&g_hrtimer_spinlock, flags);
+
+      /* Invoke the timer callback */
+
+      period = hrtimer->func(hrtimer);
+
+      flags = spin_lock_irqsave(&g_hrtimer_spinlock);
+
+      if ((hrtimer->state == HRTIMER_STATE_CANCELED) || (period == 0))
+        {
+          /* Timer is canceled or one-shot; mark it inactive */
+
+          hrtimer->state = HRTIMER_STATE_INACTIVE;
+        }
+      else
+        {
+          /* Restart the periodic timer */
+
+          hrtimer->expired += period;
+          hrtimer->state = HRTIMER_STATE_ARMED;
+          RB_INSERT(hrtimer_tree_s, &g_hrtimer_tree, &hrtimer->node);
+        }
+
+      /* Fetch the next earliest timer */
+
+      hrtimer = (FAR hrtimer_t *)RB_MIN(hrtimer_tree_s, &g_hrtimer_tree);
+    }
+
+  /* Schedule the next timer expiration */
+
+  if (hrtimer != NULL)
+    {
+      /* Start timer for the next earliest expiration */
+
+      (void)hrtimer_starttimer(hrtimer->expired);
+    }
+
+  /* Leave critical section */
+
+  spin_unlock_irqrestore(&g_hrtimer_spinlock, flags);
+}
diff --git a/sched/hrtimer/hrtimer_start.c b/sched/hrtimer/hrtimer_start.c
new file mode 100644
index 00000000000..b3bde40eee0
--- /dev/null
+++ b/sched/hrtimer/hrtimer_start.c
@@ -0,0 +1,148 @@
+/****************************************************************************
+ * sched/hrtimer/hrtimer_start.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include <errno.h>
+
+#include "hrtimer/hrtimer.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hrtimer_insert
+ *
+ * Description:
+ *   Insert the given high-resolution timer into the active timer RB-tree.
+ *   If the timer is already in the tree, it will be replaced.
+ *   If the inserted timer becomes the earliest timer in the tree, the
+ *   hardware timer will be configured to fire at its expiration.
+ *
+ * Input Parameters:
+ *   hrtimer - Pointer to the hrtimer structure to be inserted.
+ *
+ * Returned Value:
+ *   OK (0) on success; negated errno value on failure.
+ *
+ * Assumptions/Notes:
+ *   - This function should be called with interrupts disabled or under
+ *     spinlock protection to ensure RB-tree integrity.
+ *   - If the timer is currently running, insertion is rejected with -EBUSY.
+ ****************************************************************************/
+
+static inline int hrtimer_insert(FAR hrtimer_t *hrtimer)
+{
+  DEBUGASSERT(hrtimer != NULL);
+
+  /* Insert (or replace) the timer into the RB-tree ordered by expiration */
+
+  RB_INSERT(hrtimer_tree_s, &g_hrtimer_tree, &hrtimer->node);
+
+  /* Mark the timer as armed */
+
+  hrtimer->state = HRTIMER_STATE_ARMED;
+
+  /* If the inserted timer is now the earliest, start hardware timer */
+
+  if (&hrtimer->node == RB_MIN(hrtimer_tree_s, &g_hrtimer_tree))
+    {
+      return hrtimer_starttimer(hrtimer->expired);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hrtimer_start
+ *
+ * Description:
+ *   Start a high-resolution timer to expire after a specified duration
+ *   in nanoseconds, either as an absolute or relative time.
+ *
+ * Input Parameters:
+ *   hrtimer - Pointer to the hrtimer structure.
+ *   ns      - Expiration time in nanoseconds. Interpretation
+ *             depends on mode.
+ *   mode    - Timer mode (HRTIMER_MODE_ABS or HRTIMER_MODE_REL).
+ *
+ * Returned Value:
+ *   OK (0) on success, or a negated errno value on failure.
+ *
+ * Assumptions/Notes:
+ *   - This function disables interrupts briefly via spinlock to safely
+ *     insert the timer into the RB-tree.
+ *   - Absolute mode sets the timer to expire at the given absolute time.
+ *   - Relative mode sets the timer to expire after 'ns'
+ *     nanoseconds from the current time.
+ ****************************************************************************/
+
+int hrtimer_start(FAR hrtimer_t *hrtimer,
+                  uint64_t ns,
+                  enum hrtimer_mode_e mode)
+{
+  irqstate_t flags;
+  int ret = OK;
+
+  DEBUGASSERT(hrtimer != NULL);
+
+  /* Protect RB-tree manipulation with spinlock and disable interrupts */
+
+  flags = spin_lock_irqsave(&g_hrtimer_spinlock);
+
+  /* Reject start if the timer is already running or armed */
+
+  if ((hrtimer->state == HRTIMER_STATE_RUNNING) ||
+      (hrtimer->state == HRTIMER_STATE_ARMED))
+    {
+      spin_unlock_irqrestore(&g_hrtimer_spinlock, flags);
+      return -EBUSY;
+    }
+
+  /* Compute absolute expiration time */
+
+  if (mode == HRTIMER_MODE_ABS)
+    {
+      hrtimer->expired = ns;
+    }
+  else
+    {
+      hrtimer->expired = hrtimer_gettime() + ns;
+    }
+
+  /* Insert the timer into the RB-tree */
+
+  ret = hrtimer_insert(hrtimer);
+
+  spin_unlock_irqrestore(&g_hrtimer_spinlock, flags);
+  return ret;
+}


Reply via email to