2009年12月11日 星期五

Linux clock

clocksource 為一 interface 提供 counter 給 kenel 讀,並提供參數給cyc2ns()將cycles轉換為實際時間 (nsec)

clockevent 則是實際產生 interrupt 推動 Linux time subsystem的

改ARM的HZ直接改arch/arm/Kconfig裡HZ的default,同時clockevent.set_mode()裡CLOCK_EVT_MODE_PERIODIC裡 推動timer的timeout cycle count也要依HZ更新為(1/HZ)sec的相對應cycle(hardware dependent);但如果使用hrtimer(使用CLOCK_EVT_MODE_ONESHOT)則要注意clockevent.mult設定為div_sc(timer_clk_in_hz, NSEC_PER_SEC, shift)即可,跟HZ無關,因為 kernel 要 clockevent發送的 時間 會在clockevents_program_event()用clockevent.multi被轉成cycle再丟給clockevent.set_next_event()


Kernel Timer Systems - eLinux.org
http://elinux.org/Kernel_Timer_Systems#clock_events

第七章 Linux内核的时钟中断(中)
http://www.myfaq.com.cn/2005September/2005-09-13/202037.html

Lab 7 timer interrupt
http://opencsl.openfoundry.org/Lab07_timer_interrupt.rst.html

hrtimer + clockevent + timekeeping
http://www.360doc.com/content/09/0715/19/74585_4282710.shtml
[精华] 研究下hrtimer及内核clock/timer子系统变化
http://www.unixresources.net/linux/clf/linuxK/archive/00/00/66/47/664730.html

struct clocksource
clocksource_register()

struct clock_event_device
clockevents_register_device()

目前kernel内部有periodic/highres/dynamic tick三种时钟中断处理方式

Times in Kernel
  1. system time
    系统启动到现在的nanosecond
    A monotonically increasing value that represents the amount of time the system has been running.
    单调增长的系统运行时间, 可以通过time source, xtime及wall_to_monotonic计算出来.

    system_time = xtime + cyc2ns(clock->read() - clock->cycle_last) + wall_to_monotonic;
  2. wall time (xtime)
    A value representing the the human time of day, as seen on a wrist-watch. Realtime时间. xtime.
  3. time source (clocksource)
    A representation of a free running counter running at a known frequency, usually in hardware, e.g GPT. 可以通过clocksource->read()得到counter值
  4. tick
    A periodic interrupt generated by a hardware-timer, typically with a fixed interval

    defined by HZ: jiffies

real time是从1970年开始到现在的nanosecond
real_time = xtime + cyc2ns(clock->read() - clock->cycle_last)

wall_to_monotonic紀錄boot時的xtime(real time)
system_time = xtime + cyc2ns(clock->read() - clock->cycle_last) + wall_to_monotonic;

2.6.31.1, getrawmonotonic():
system_time = clocksource->raw_time + cyc2ns(clock->read() - clock->cycle_last)

initialization:
xtime=read_persistent_clock() 通常return 0, by arch code might get value from RTC or flash.
wall_to_monotonic = -xtime

沒有留言: