@@ -665,87 +665,215 @@ require nanosecond-level task timing, which tick-based timers
665665like wdog cannot provide. Reducing the tick interval to micro-
666666or nanoseconds is impractical, as it would overload the CPU with interrupts.
667667
668- To address this, NuttX provides a high-resolution timer (hrtimer),
669- which delivers true nanosecond-level precision. Unlike wdog’s list-based timers,
670- hrtimer uses a red-black tree for efficient management of large numbers of timers,
671- an important advantage in hard real-time systems like vehicle control.
672-
673- A user can register an hrtimer callback to execute after a specified delay.
674- The callback runs in the timer interrupt context, so only limited NuttX interfaces
675- are available, such as ``mq_send() ``, ``sigqueue() ``, ``nxevent_post() ``, or ``kill() ``,
676- to communicate with tasks.
677-
678- - :c:func: `hrtimer_init `
679- - :c:func: `hrtimer_cancel `
680- - :c:func: `hrtimer_cancel_sync `
681- - :c:func: `hrtimer_start `
682- - High-resolution Timer Callback
683-
684- .. c :function :: void hrtimer_init (FAR hrtimer_t *hrtimer, hrtentry_t func, \
685- FAR void *arg)
686-
687- This function initializes a high-resolution timer instance.
688- Sets the expiration callback and its argument. The timer is
689- not started by this function.
690-
691- :param hrtimer: Pointer to hrtimer instance
668+ High-resolution Timer (HRTimer) is a timer abstraction capable of achieving
669+ nanosecond-level timing resolution, primarily used in scenarios requiring
670+ high-resolution clock events. With the advancement of integrated circuit
671+ technology, modern high-resolution timer hardware, such as the typical x86
672+ HPET, can already meet sub-nanosecond timing requirements and offer
673+ femtosecond-level jitter control.
674+
675+ Although the current hardware timer abstraction (`up_alarm/up_timer `)
676+ in the NuttX kernel already supports nanosecond-level timing, its software
677+ timer abstraction, wdog, and the timer timeout interrupt handling process
678+ remain at microsecond-level (tick) resolution, which falls short of
679+ high-resolution timing demands. Therefore, it is necessary to implement a
680+ new timer abstraction, HRTimer, to address the resolution limitations of
681+ wdog. HRTimer primarily provides the following functional interfaces:
682+
683+ **Set a timer in nanoseconds **: Configure a software timer to trigger at
684+ a specified nanosecond time.
685+
686+ **Cancel a timer **: Cancel the software timer.
687+
688+ **Handle timer timeout **: Execute timeout processing after the timer event
689+ is triggered.
690+
691+ The new NuttX HRTimer is designed to address the issues of insufficient
692+ resolution in the current NuttX wdog. It draws on the strengths of the Linux
693+ HRTimer design while improving upon its weaknesses.
694+ The HRTimer design is divided into two parts: the `HRTimer Queue ` and the
695+ `HRTimer `. The `HRTimer Queue ` is a reusable component that allows users to
696+ freely customize their own `HRTimer ` interface by pairing it with a private
697+ timer driver, without needing to modify the kernel code.
698+
699+ The HRTimer Queue is a zero-performance-overhead, composable, and
700+ customizable abstraction that provides only asynchronous-style interfaces:
701+
702+ **hrtimer_queue_start(queue, timer) **: Asynchronously sends an HRTimer to
703+ HRTimer queue.
704+
705+ **hrtimer_queue_async_cancel(queue, timer) **:
706+ Asynchronously cancels anHRTimer and returns the current reference count
707+ of the timer.
708+
709+ **hrtimer_queue_wait(queue, timer) **:
710+ Waits for the release of all references to the HRTimer to obtain ownership
711+ of the HRTimer data structure.
712+
713+ All other user interfaces can be composed based on these three interfaces.
714+
715+ On top of the `HRTimer Queue `, users only need to implement the following
716+ interfaces to customize their own HRTimer implementation:
717+
718+ **hrtimer_expiry(current) **: Handles timer expiration, typically called
719+ within the execution path of the corresponding timer hardware
720+ interrupt handler.
721+
722+ **hrtimer_reprogram(queue, next_expired) **: Sets the next timer event.
723+
724+ **hrtimer_current() **: Gets the current time to set relative timers.
725+
726+ After implementing the above three interfaces, users can include one of the
727+ `hrtimer_type_xxx.h ` implementation to compose their own hrtimer
728+ implementation, which mainly includes the following interfaces:
729+
730+ **hrtimer_start(timer, func, arg, delay) **: Starts a timer.
731+
732+ **hrtimer_restart(timer, func, arg, delay) **: Restarts a timer that has
733+ been asynchronously canceled (its callback function might still be executing).
734+ This interface is designed to explicitly remind users to be aware of
735+ concurrency issues,as concurrency problems are prone to occur in actual
736+ programming and are very difficult to locate. Providing such an interface
737+ facilitates quick identification of concurrency issues.
738+
739+ **hrtimer_cancel(timer) **: Asynchronously cancels a timer. Note that
740+ the semantics of this interface are completely different from Linux's
741+ `try_to_cancel `. It ensures that the timer can definitely be canceled
742+ successfully, but may need to wait for its callback function to finish
743+ execution.
744+
745+ **hrtimer_cancel_sync(timer) **: Synchronously cancels a timer. If the timer's
746+ callback function is still executing, this function will spin-wait until
747+ the callback completes. It ensures that the user can always obtain
748+ ownership of the timer.
749+
750+ The state-machine diagram of the HRTimer is as follows:
751+
752+ .. code-block :: text
753+
754+ ┌─────────────────────────────────────────────────────────────────────┐
755+ │ │
756+ │ ┌─────────────────────┐ hrtimer_start ┌────────────────┐ │
757+ │ │ HRTIMER_COMPLETED │ ─────────────────────> │ HRTIMER_PENDING│ │
758+ │ │ (private) │ │ (shared) │ │
759+ │ └─────────────────────┘ └────────────────┘ │
760+ │ ^ │ │
761+ │ │ │ │
762+ │ │ hrtimer callback return 0 │ │
763+ │ │ in hrtimer_expiry │ │
764+ │ │ │ │
765+ │ │ ▼ │
766+ │ │ ┌───────────────────────────────────────────┐ │
767+ │ │ │ HRTIMER_CANCELED │ │
768+ │ │ │ (half_shared) │ │
769+ │ │ └───────────────────────────────────────────┘ │
770+ │ │ │ ▲ │
771+ │ │ │ │ │
772+ │ │ │ hrtimer_cancel │ hrtimer_restart │
773+ │ │ │ wait all cores │ │
774+ │ │ │ release the │ │
775+ │ │ │ references to │ │
776+ │ │ │ the timer. │ │
777+ │ │ ▼ │ │
778+ │ │ ┌───────────────────────────────────────────┐ │
779+ │ │ │ HRTIMER_CANCELED │ │
780+ │ │ │ (private) │ │
781+ │ │ └───────────────────────────────────────────┘ │
782+ │ │ │ │
783+ │ │ │ Complete the cancel │
784+ │ └────────────────────┘ │
785+ │ │
786+ │ Note: HRTIMER_PENDING has a self-transition for │
787+ │ "hrtimer callback return non-zero in hrtimer_expiry" │
788+ │ │
789+ └─────────────────────────────────────────────────────────────────────┘
790+
791+ .. c :function :: int hrtimer_restart (hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t delay)
792+ .. c:function:: int hrtimer_restart_absolute(hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t expired)
793+
794+ Restart a high-resolution timer with new parameters.
795+
796+ For relative mode timers, converts relative time to absolute expiration time.
797+ The expiration time is capped at HRTIMER_MAX_DELAY.
798+
799+ **Note: ** This function is static inline and intended for internal use.
800+
801+ :param timer: Timer instance to restart
692802 :param func: Expiration callback function
693- :param arg: Callback argument
803+ :param arg: Argument passed to callback function
804+ :param delay/expired: Expiration time in nanoseconds (relative or absolute)
694805
695- :return: None .
806+ :return: Zero on success; error code on failure .
696807
697- **POSIX Compatibility: ** This is a NON-POSIX interface.
808+ **Assumptions: **
809+ - The caller has ownership of the timer.
698810
699- .. c :function :: int hrtimer_cancel (FAR hrtimer_t *hrtimer)
811+ .. c :function :: int hrtimer_start (FAR hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t delay)
812+ .. c:function:: int hrtimer_start_absolute(FAR hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t expired)
700813
701- If the timer is armed but has not yet expired, it will be removed from
702- the timer queue and the callback will not be invoked.
814+ Start a high-resolution timer with relative or absolute time in nanoseconds.
703815
704- If the timer callback is currently executing, this function will mark
705- the timer as canceled and return immediately. The running callback is
706- allowed to complete, but it will not be invoked again.
816+ The caller must have ownership of the timer. This function validates parameters
817+ and timer state before attempting to start the timer.
707818
708- This function is non-blocking and does not wait for a running callback
709- to finish.
819+ :param timer: Timer instance to start
820+ :param func: Expiration callback function
821+ :param arg: Argument passed to callback function
822+ :param delay/expired: Expiration time in nanoseconds (relative or absolute)
823+
824+ :return: Zero on success; ``-EINVAL`` if parameters are invalid or timer is pending.
825+
826+ **Assumptions: **
827+ - Timer is not NULL and callback function is not NULL.
828+ - Timer is not in pending state.
829+
830+ .. c :function :: int hrtimer_cancel (FAR hrtimer_t *timer)
831+
832+ Cancel a high-resolution timer asynchronously.
833+
834+ Sets the timer to cancelled state and returns immediately. The caller acquires
835+ limited ownership, allowing timer restart but not freeing. Callback may still
836+ be executing on another CPU. Use with caution to avoid concurrency issues.
837+
838+ :param timer: Timer instance to cancel
710839
711- :param hrtimer: Timer instance to cancel
840+ :return: `` OK `` on success; `` -EINVAL `` if timer is not pending.
712841
713- :return: ``OK `` on success; negated errno on failure.
842+ **Assumptions: **
843+ - Timer is not NULL.
714844
715- ** POSIX Compatibility: ** This is a NON-POSIX interface.
845+ .. c : function :: int hrtimer_cancel_sync (FAR hrtimer_t * timer)
716846
717- .. c : function :: int hrtimer_cancel_sync (FAR hrtimer_t * hrtimer)
847+ Cancel a high-resolution timer and synchronously wait for callback completion.
718848
719- Cancel a high-resolution timer and wait synchronously until the timer
720- becomes inactive.
849+ Sets timer to cancelled state and waits for all references to be released.
850+ Caller acquires full ownership and can safely deallocate the timer after
851+ this function returns.
721852
722- This function first calls hrtimer_cancel() to request cancellation of
723- the timer. If the timer callback is currently executing, this function
724- will wait until the callback has completed and the timer state has
725- transitioned to HRTIMER_STATE_INACTIVE.
853+ :param timer: Timer instance to cancel
726854
727- This function may sleep and must not be called from interrupt context .
855+ :return: `` OK `` on success; `` -EINVAL `` if timer is not pending .
728856
729- :param hrtimer: Timer instance to cancel
857+ **Assumptions: **
858+ - Timer is not NULL.
730859
731- :return: `` OK `` on success; negated errno on failure.
860+ .. c : function :: uint64_t hrtimer_gettime (FAR hrtimer_t * timer)
732861
733- ** POSIX Compatibility: ** This is a NON-POSIX interface .
862+ Get the remaining time until timer expiration .
734863
735- .. c :function :: int hrtimer_start (FAR hrtimer_t *hrtimer, uint64_t ns, \
736- enum hrtimer_mode_e mode)
864+ :param timer: Timer instance to query
737865
738- This function starts a high-resolution timer in absolute or relative mode .
866+ :return: Remaining time in nanoseconds until next expiration .
739867
740- :param hrtimer: Timer instance to cancel
741- :param ns: Timer expiration in nanoseconds (absolute or relative)
742- :param mode: HRTIMER_MODE_ABS or HRTIMER_MODE_REL
868+ **Assumptions: **
869+ - Timer is not NULL.
743870
744- :return: ``OK`` on success; negated errno on failure.
871+ .. c : type :: uitn64_t (* hrtimer_callback_t )( void *arg, uint64_t expired)
745872
746- **POSIX Compatibility: ** This is a NON-POSIX interface.
873+ **High-resolution Timer Callback Type **: Function pointer type for timer
874+ expiration callbacks. When a hrtimer expires, a function of this type is called.
747875
748- .. c :type :: void (*hrtentry_t )(FAR struct hrtimer_s *)
876+ :param arg: Argument passed to callback function
877+ :param expired: Time in nanoseconds when timer expired
749878
750- **High-resolution Timer Callback **: when a hrtimer expires,
751- the callback function with this type is called.
879+ :return: Next delay in nanoseconds until next expiration.
0 commit comments