@@ -665,87 +665,253 @@ 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_wait_policy() **: Waits if the timer callback is still executing.
725+
726+ **hrtimer_current() **: Gets the current time to set relative timers.
727+
728+ After implementing the above three interfaces, users can include one of the
729+ `hrtimer_type_xxx.h ` implementation to compose their own hrtimer
730+ implementation, which mainly includes the following interfaces:
731+
732+ **hrtimer_start(timer, func, arg, delay) **: Starts a timer.
733+
734+ **hrtimer_restart(timer, func, arg, delay) **: Restarts a timer that has
735+ been asynchronously canceled (its callback function might still be executing).
736+ This interface is designed to explicitly remind users to be aware of
737+ concurrency issues,as concurrency problems are prone to occur in actual
738+ programming and are very difficult to locate. Providing such an interface
739+ facilitates quick identification of concurrency issues.
740+
741+ **hrtimer_cancel(timer) **: Asynchronously cancels a timer. Note that
742+ the semantics of this interface are completely different from Linux's
743+ `try_to_cancel `. It ensures that the timer can definitely be canceled
744+ successfully, but may need to wait for its callback function to finish
745+ execution.
746+
747+ **hrtimer_cancel_sync(timer) **: Synchronously cancels a timer. If the timer's
748+ callback function is still executing, this function will spin-wait until
749+ the callback completes. It ensures that the user can always obtain
750+ ownership of the timer.
751+
752+ The state-machine diagram of the HRTimer is as follows:
753+
754+ .. code-block :: text
755+
756+ +------------------------------------------------------+
757+ | HRTIMER State Diagram |
758+ +------------------------------------------------------+
759+ | |
760+ | +----------------------+ |
761+ | | HRTIMER_COMPLETED | |
762+ | | (private) | |
763+ | +----------------------+ |
764+ | | |
765+ | | hrtimer_start |
766+ | | |
767+ | | |
768+ | v |
769+ | +----------------------+ |
770+ | | HRTIMER_PENDING |---------------------+ |
771+ | +-->| (shared) |<---+ | |
772+ | | +----------------------+ | | |
773+ | | | |timer callback | |
774+ | | |hrtimer_expiry |return non-zero | |
775+ | | | | | |
776+ | | v | | |
777+ | | +----------------------+ | | |
778+ | | | HRTIMER_RUNNING |----+ | |
779+ | | | (shared) | | |
780+ | | +----------------------+ | |
781+ | | | | |
782+ | | | | |
783+ | | |timer return zero | |
784+ | | |or | |
785+ | | |hrtimer_cancel | |
786+ | | | | |
787+ | | v | |
788+ | | +----------------------+ | |
789+ | | | HRTIMER_CANCELED |<--------+ |
790+ | +---------------| (half_shared) | |
791+ |hrtimer_restart +----------------------+ |
792+ | | |
793+ | hrtimer_cancel_sync| |
794+ | wait all cores | |
795+ | v |
796+ | +----------------------+ |
797+ | | HRTIMER_COMPLETED | |
798+ | | (private) | |
799+ | +----------------------+ |
800+ | ^ | |
801+ | | | |
802+ | +--+ |
803+ | hrtimer_cancel |
804+ +------------------------------------------------------+
805+
806+ The specific definitions of the states are as follows:
807+
808+ **HRTIMER_PENDING|shared **: `hrtimer->func != NULL `. That is, the hrtimer has
809+ been inserted into the hrtimer_queue and is waiting to be executed.
810+
811+ **HRTIMER_COMPLETED|private **: `hrtimer->func == NULL ` ∧
812+ `∀c ∈ [0, CONFIG_SMP_NCPUS), (hrtimer_queue->running[c] & ~(1u)) != hrtimer `
813+ That is, the hrtimer is not in a pending state, and no core is currently
814+ executing the hrtimer's callback function.
815+
816+ **HRTIMER_RUNNING|shared **: `hrtimer->func == NULL ` ∧
817+ `∃c ∈ [0, CONFIG_SMP_NCPUS), hrtimer_queue->running[c] == hrtimer `.
818+ That is, the hrtimer is not in a pending state, and there exists at least one
819+ core that is currently executing the hrtimer’s callback function.
820+
821+ **HRTIMER_CANCELED|half_shared **: `hrtimer->func == NULL ` ∧
822+ `∀c ∈ [0, CONFIG_SMP_NCPUS), hrtimer_queue->running[c] != hrtimer `.
823+ That is, the hrtimer is not in a pending state, and all cores have lost
824+ ownership of the hrtimer—meaning they can no longer read from or write to the
825+ hrtimer—though its callback function may still be in the process of being
826+ executed.
827+
828+ .. c :function :: int hrtimer_restart (FAR hrtimer_t *timer, hrtimer_callback_t func, uint64_t time, uint32_t mode)
829+
830+ Restart a high-resolution timer with new parameters.
831+
832+ For relative mode timers, converts relative time to absolute expiration time.
833+ The expiration time is capped at HRTIMER_MAX_DELAY.
834+
835+ **Note: ** This function is static inline and intended for internal use.
836+
837+ :param timer: Timer instance to start
692838 :param func: Expiration callback function
693- :param arg: Callback argument
839+ :param time: Expiration time in nanoseconds (relative or absolute)
840+ :param mode: ``HRTIMER_MODE_ABS`` for absolute time,
841+ ``!HRTIMER_MODE_ABS`` for relative time
694842
695- :return: None .
843+ :return: Zero on success; error code on failure .
696844
697- **POSIX Compatibility: ** This is a NON-POSIX interface.
845+ **Assumptions: **
846+ - The caller has ownership of the timer.
698847
699- .. c :function :: int hrtimer_cancel (FAR hrtimer_t *hrtimer )
848+ .. c :function :: int hrtimer_start (FAR hrtimer_t *timer, hrtimer_callback_t func, uint64_t time, uint32_t mode )
700849
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.
850+ Start a high-resolution timer with relative or absolute time in nanoseconds.
703851
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.
852+ The caller must have ownership of the timer. This function validates parameters
853+ and timer state before attempting to start the timer.
707854
708- This function is non-blocking and does not wait for a running callback
709- to finish.
855+ :param timer: Timer instance to start
856+ :param func: Expiration callback function
857+ :param time: Expiration time in nanoseconds (relative or absolute)
858+ :param mode: ``HRTIMER_MODE_ABS`` for absolute time,
859+ ``!HRTIMER_MODE_ABS`` for relative time
860+
861+ :return: Zero on success; ``-EINVAL`` if parameters are invalid or timer is pending.
862+
863+ **Assumptions: **
864+ - Timer is not NULL and callback function is not NULL.
865+ - Timer is not in pending state.
866+
867+ .. c :function :: int hrtimer_cancel (FAR hrtimer_t *timer)
868+
869+ Cancel a high-resolution timer asynchronously.
870+
871+ Sets the timer to cancelled state and returns immediately. The caller acquires
872+ limited ownership, allowing timer restart but not freeing. Callback may still
873+ be executing on another CPU. Use with caution to avoid concurrency issues.
874+
875+ :param timer: Timer instance to cancel
710876
711- :param hrtimer: Timer instance to cancel
877+ :return: `` OK `` on success; `` >0 `` if the timer is running.
712878
713- :return: ``OK `` on success; negated errno on failure.
879+ **Assumptions: **
880+ - Timer is not NULL.
714881
715- ** POSIX Compatibility: ** This is a NON-POSIX interface.
882+ .. c : function :: int hrtimer_cancel_sync (FAR hrtimer_t * timer)
716883
717- .. c : function :: int hrtimer_cancel_sync (FAR hrtimer_t * hrtimer)
884+ Cancel a high-resolution timer and synchronously wait for callback completion.
718885
719- Cancel a high-resolution timer and wait synchronously until the timer
720- becomes inactive.
886+ Sets timer to cancelled state and waits for all references to be released.
887+ Caller acquires full ownership and can safely deallocate the timer after
888+ this function returns.
721889
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.
890+ :param timer: Timer instance to cancel
726891
727- This function may sleep and must not be called from interrupt context .
892+ :return: `` OK `` on success .
728893
729- :param hrtimer: Timer instance to cancel
894+ **Assumptions: **
895+ - Timer is not NULL.
730896
731- :return: `` OK `` on success; negated errno on failure.
897+ .. c : function :: uint64_t hrtimer_gettime (FAR hrtimer_t * timer)
732898
733- ** POSIX Compatibility: ** This is a NON-POSIX interface .
899+ Get the remaining time until timer expiration .
734900
735- .. c :function :: int hrtimer_start (FAR hrtimer_t *hrtimer, uint64_t ns, \
736- enum hrtimer_mode_e mode)
901+ :param timer: Timer instance to query
737902
738- This function starts a high-resolution timer in absolute or relative mode .
903+ :return: Remaining time in nanoseconds until next expiration .
739904
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
905+ **Assumptions: **
906+ - Timer is not NULL.
743907
744- :return: ``OK`` on success; negated errno on failure.
908+ .. c : type :: uint64_t (* hrtimer_callback_t )(FAR const struct hrtimer_s *timer, uint64_t expired)
745909
746- **POSIX Compatibility: ** This is a NON-POSIX interface.
910+ **High-resolution Timer Callback Type **: Function pointer type for timer
911+ expiration callbacks. When a hrtimer expires, a function of this type is called.
747912
748- .. c :type :: void (*hrtentry_t )(FAR struct hrtimer_s *)
913+ :param timer: The hrtimer pointer passed to callback function,
914+ do not modify the hrtimer when executing callback function.
915+ :param expired: Time in nanoseconds when timer expired
749916
750- **High-resolution Timer Callback **: when a hrtimer expires,
751- the callback function with this type is called.
917+ :return: Next delay in nanoseconds until next expiration.
0 commit comments