world leader in high performance signal processing
Trace: » high-resolution-timer

High Resolution Timer on Blackfin

Concepts and Document

For the details of “Generic time”, “High Resolution Time”, “clock source”, “clock event device”, please read Documentation/timers/. To make it simple, “clock source” is used for time keeping, “clock event device” is used to generate timer interrupt.

Configure Kernel

To make your timer resolution higher than jiffies in Blackfin, you will need bellow configuration options:

#
# Kernel Timer/Scheduler
#
CONFIG_SCHED_HRTICK=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y

#
# Clock event device
#
# CONFIG_TICKSOURCE_GPTMR0 is not set
CONFIG_TICKSOURCE_CORETMR=y

#
# Clock souce
#
CONFIG_CYCLES_CLOCKSOURCE=y
# CONFIG_GPTMR0_CLOCKSOURCE is not set

CONFIG_TICK_ONESHOT=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y

Especially, you need at least one Clock event device (CONFIG_TICKSOURCE_CORETMR is preferred), and you need at least one high resolution clock source (CONFIG_CYCLES_CLOCKSOURCE is preferred). For SMP (on BF561) a global clock source is required, please choose “CONFIG_GPTMR0_CLOCKSOURCE”.

If you do not select any clock source, kernel will by default use jiffies as clock source.

Is HRT really enabled?

Check /proc/timer_list, whether clock has “resolution: 1 nsecs”. This shows HRT is enabled. Otherwise, the timer uses jiffies as clock source by default, so you got lower resolution, e.g “4000000 nsecs” (HZ=250).

Here is sample output on BF561-ezkit with SMP enabled:

root:/> cat /proc/timer_list 
Timer List Version: v0.4
HRTIMER_MAX_CLOCK_BASES: 2
now at 36318533226 nsecs

cpu: 0
 clock 0:
  .base:       008243f4
  .index:      0
  .resolution: 1 nsecs
  .get_time:   _ktime_get_real
  .offset:     1167609600000000000 nsecs
active timers:
 clock 1:
  .base:       00824428
  .index:      1
  .resolution: 1 nsecs
  .get_time:   _ktime_get
  .offset:     0 nsecs
active timers:
 #0: <00824498>, _tick_sched_timer, S:01
 # expires at 36320000000-36320000000 nsecs [in 1466774 to 1466774 nsecs]
 #1: <029199e0>, _hrtimer_wakeup, S:01
 # expires at 36925498948-36926498936 nsecs [in 606965722 to 607965710 nsecs]
 #2: <0016859c>, _sched_rt_period_timer, S:01
 # expires at 37000000000-37000000000 nsecs [in 681466774 to 681466774 nsecs]
  .expires_next   : 36320000000 nsecs
  .hres_active    : 1
  .nr_events      : 8979
  .nohz_mode      : 0
  .idle_tick      : 0 nsecs
  .tick_stopped   : 0
  .idle_jiffies   : 0
  .idle_calls     : 0
  .idle_sleeps    : 0
  .idle_entrytime : 0 nsecs
  .idle_waketime  : 0 nsecs
  .idle_exittime  : 0 nsecs
  .idle_sleeptime : 0 nsecs
  .last_jiffies   : 0
  .next_jiffies   : 0
  .idle_expires   : 0 nsecs
jiffies: 4294901375

cpu: 1
 clock 0:
  .base:       008273f4
  .index:      0
  .resolution: 1 nsecs
  .get_time:   _ktime_get_real
  .offset:     1167609600000000000 nsecs
active timers:
 clock 1:
  .base:       00827428
  .index:      1
  .resolution: 1 nsecs
  .get_time:   _ktime_get
  .offset:     0 nsecs
active timers:
 #0: <00827498>, _tick_sched_timer, S:01
 # expires at 36321000000-36321000000 nsecs [in 2466774 to 2466774 nsecs]
 #1: <02affe88>, _hrtimer_wakeup, S:01
 # expires at 44012681532-44012681532 nsecs [in 7694148306 to 7694148306 nsecs]
  .expires_next   : 36321000000 nsecs
  .hres_active    : 1
  .nr_events      : 8929
  .nohz_mode      : 0
  .idle_tick      : 0 nsecs
  .tick_stopped   : 0
  .idle_jiffies   : 0
  .idle_calls     : 0
  .idle_sleeps    : 0
  .idle_entrytime : 0 nsecs
  .idle_waketime  : 0 nsecs
  .idle_exittime  : 0 nsecs
  .idle_sleeptime : 0 nsecs
  .last_jiffies   : 0
  .next_jiffies   : 0
  .idle_expires   : 0 nsecs
jiffies: 4294901375


Tick Device: mode:     1
Per CPU device: 0
Clock Event Device: bfin_core_timer
 max_delta_ns:   2147483647
 min_delta_ns:   1000
 mult:           2576980377
 shift:          32
 mode:           3
 next_event:     36320000000 nsecs
 set_next_event: _bfin_coretmr_set_next_event
 set_mode:       _bfin_coretmr_set_mode
 event_handler:  _hrtimer_interrupt

Tick Device: mode:     1
Per CPU device: 1
Clock Event Device: bfin_core_timer
 max_delta_ns:   2147483647
 min_delta_ns:   1000
 mult:           2576980377
 shift:          32
 mode:           3
 next_event:     36321000000 nsecs
 set_next_event: _bfin_coretmr_set_next_event
 set_mode:       _bfin_coretmr_set_mode
 event_handler:  _hrtimer_interrupt

FAQs

When HRT is enabled, is there still jiffies?

Yes. Jiffies (periodic tick) is emulated by HRT, and code relies on jiffies still work as usual (e.g scheduler_tick()).

When HRT is enabled, are timers based on jiffies still available?

Yes. Jiffies (periodic tick) is emulated by HRT, so functions like “add_timer()” still work as usual. Some functions, e.g, setitimer(), nanosleep(), and posix-timers (…) is based on HRT.

TICKLESS means no tick at all?

No. It should be called “Dynamic Tick” - tick does not need to be periodic. Kernel turns off periodic tick when the tick is not necessary (e.g, when CPU goes idle), and resumes tick when tick is needed.

Can gettimeofday() return time with resolution higher than jiffies?

Yes. But you need to turn on at least one clock source.

Is the high-res timer's resolution as high as 1 ns ?

No. The real resolution depends on timer irq latency.