RT-Thread RTOS
An open source embedded real-time operating system
Clock HRTimer

Overview

The clock hrtimer layer provides high-resolution timeout scheduling on top of clock_time. It keeps a sorted timeout list, programs the next deadline, and runs callbacks when the deadline expires.

Key Concepts

  • Time base: delay counts are expressed in the clock source counter units.
  • Event programming: the next expiry is converted to event units and sent to the clock event device.
  • Fallback: if no hardware event exists, a software timer triggers processing.

API

void rt_clock_hrtimer_init(rt_clock_hrtimer_t timer,
const char *name,
rt_uint8_t flag,
void (*timeout)(void *parameter),
void *parameter);
rt_err_t rt_clock_hrtimer_start(rt_clock_hrtimer_t timer, unsigned long cnt);
rt_err_t rt_clock_hrtimer_stop(rt_clock_hrtimer_t timer);
rt_err_t rt_clock_hrtimer_control(rt_clock_hrtimer_t timer, int cmd, void *arg);
rt_err_t rt_clock_hrtimer_detach(rt_clock_hrtimer_t timer);
void rt_clock_hrtimer_delay_init(struct rt_clock_hrtimer *timer);
void rt_clock_hrtimer_delay_detach(struct rt_clock_hrtimer *timer);
rt_err_t rt_clock_hrtimer_sleep(struct rt_clock_hrtimer *timer, unsigned long cnt);
rt_err_t rt_clock_hrtimer_ndelay(struct rt_clock_hrtimer *timer, unsigned long ns);
rt_err_t rt_clock_hrtimer_udelay(struct rt_clock_hrtimer *timer, unsigned long us);
rt_err_t rt_clock_hrtimer_mdelay(struct rt_clock_hrtimer *timer, unsigned long ms);

Flags reuse RT_TIMER_FLAG_* definitions (one-shot/periodic/hard timer). cnt is a counter delta based on the default clock source.

rt_clock_hrtimer_init

void rt_clock_hrtimer_init(rt_clock_hrtimer_t timer,
const char *name,
rt_uint8_t flag,
void (*timeout)(void *parameter),
void *parameter);
  • Purpose: initialize a high-resolution timer object.
  • Parameters:
    • timer: the hrtimer object to initialize.
    • name: timer name (truncated to RT_NAME_MAX-1).
    • flag: RT_TIMER_FLAG_* (one-shot/periodic/hard timer).
    • timeout: callback function on expiry.
    • parameter: user parameter passed to the callback.
  • Behavior:
    • Clears internal state, initializes list node and completion.
    • Does not start the timer; call rt_clock_hrtimer_start() to arm it.
  • Context: thread context.

rt_clock_hrtimer_start

rt_err_t rt_clock_hrtimer_start(rt_clock_hrtimer_t timer, unsigned long cnt);
  • Purpose: arm a timer to expire after cnt counter ticks.
  • Parameters:
    • cnt: relative delay in clock source counter units.
  • Return values:
    • RT_EOK: timer armed.
    • -RT_ERROR: timer already active or invalid cnt.
  • Notes:
    • cnt must be less than half of the maximum counter range to avoid wrap ambiguity.
    • Starting a timer programs the next clock event if this timer becomes the earliest deadline.

rt_clock_hrtimer_stop

rt_err_t rt_clock_hrtimer_stop(rt_clock_hrtimer_t timer);
  • Purpose: cancel an active timer.
  • Return values:
    • RT_EOK: timer stopped.
    • -RT_ERROR: timer was not active.
  • Notes: stopping a timer may reprogram the next event.

rt_clock_hrtimer_control

rt_err_t rt_clock_hrtimer_control(rt_clock_hrtimer_t timer, int cmd, void *arg);
  • Purpose: query or modify a timer after initialization.
  • Common commands (same as RT-Thread timers):
    • RT_TIMER_CTRL_GET_TIME: get delay_cnt into *(unsigned long *)arg.
    • RT_TIMER_CTRL_SET_TIME: set delay_cnt from *(unsigned long *)arg.
    • RT_TIMER_CTRL_SET_ONESHOT / RT_TIMER_CTRL_SET_PERIODIC: set mode.
    • RT_TIMER_CTRL_GET_STATE: return activated/deactivated state.
    • RT_TIMER_CTRL_GET_REMAIN_TIME: get absolute timeout counter.
    • RT_TIMER_CTRL_GET_FUNC / RT_TIMER_CTRL_SET_FUNC: get/set callback.
    • RT_TIMER_CTRL_GET_PARM / RT_TIMER_CTRL_SET_PARM: get/set parameter.
  • Notes:
    • Changing time or mode while active updates internal deadline but does not implicitly restart a stopped timer.

rt_clock_hrtimer_detach

rt_err_t rt_clock_hrtimer_detach(rt_clock_hrtimer_t timer);
  • Purpose: detach a timer and wake any waiters.
  • Behavior:
    • Marks the timer inactive and wakes rt_clock_hrtimer_sleep() waiters with an error code.
    • Removes the timer from the list if needed.
  • Use case: cleanup when a timer is no longer valid.

rt_clock_hrtimer_delay_init

void rt_clock_hrtimer_delay_init(struct rt_clock_hrtimer *timer);
  • Purpose: initialize a one-shot hrtimer for blocking delays.
  • Behavior: sets a built-in timeout callback that signals a completion.

rt_clock_hrtimer_delay_detach

void rt_clock_hrtimer_delay_detach(struct rt_clock_hrtimer *timer);
  • Purpose: detach a delay timer created by rt_clock_hrtimer_delay_init().
  • Notes: safe to call even if the timer has already expired.

rt_clock_hrtimer_sleep

rt_err_t rt_clock_hrtimer_sleep(struct rt_clock_hrtimer *timer, unsigned long cnt);
  • Purpose: block the current thread until the delay expires.
  • Parameters: timer must be initialized (typically by delay_init).
  • Return values:
    • RT_EOK: timeout expired normally.
    • -RT_EINTR: interrupted by signal or detach.
    • -RT_EINVAL: cnt is zero.
  • Context: thread context only.

rt_clock_hrtimer_ndelay / udelay / mdelay

rt_err_t rt_clock_hrtimer_ndelay(struct rt_clock_hrtimer *timer, unsigned long ns);
rt_err_t rt_clock_hrtimer_udelay(struct rt_clock_hrtimer *timer, unsigned long us);
rt_err_t rt_clock_hrtimer_mdelay(struct rt_clock_hrtimer *timer, unsigned long ms);
  • Purpose: sleep for a duration expressed in nanoseconds, microseconds, or milliseconds.
  • Behavior:
    • Converts the time into counter units using the current clock_time resolution and calls rt_clock_hrtimer_sleep().
  • Notes:
    • The actual delay is limited by the clock source resolution and event programming granularity.

Typical Flow

  1. Initialize a hrtimer with a callback.
  2. Convert a time interval to counter units, or use the ndelay/udelay/mdelay helpers.
  3. Start the timer; the subsystem will program the next event.
  4. When the event ISR fires, rt_clock_time_event_isr() runs hrtimer processing and dispatches callbacks.

Example: One-shot Timeout

#include <drivers/clock_time.h>
static struct rt_clock_hrtimer demo_timer;
static void demo_timeout(void *parameter)
{
RT_UNUSED(parameter);
rt_kprintf("hrtimer timeout\n");
}
static void demo_hrtimer_start(void)
{
rt_uint64_t ns = 5ULL * 1000 * 1000; /* 5 ms */
unsigned long cnt = (unsigned long)rt_clock_time_ns_to_counter(ns);
rt_clock_hrtimer_init(&demo_timer, "demo", RT_TIMER_FLAG_ONE_SHOT,
demo_timeout, RT_NULL);
rt_clock_hrtimer_start(&demo_timer, cnt);
}
#define RT_TIMER_FLAG_ONE_SHOT
Definition: rtdef.h:528

Example: Sleep Helper

static void demo_hrtimer_sleep(void)
{
struct rt_clock_hrtimer timer;
rt_clock_hrtimer_delay_init(&timer);
rt_clock_hrtimer_mdelay(&timer, 10);
rt_clock_hrtimer_delay_detach(&timer);
}

Notes

  • Callbacks may run in interrupt context when using a hardware event device.
  • rt_clock_hrtimer_sleep() waits on a completion and may return -RT_EINTR if interrupted.