The kernel uses the timer callouts to work with the hardware timer (i.e., the
timer/counter chip).
In many cases, a board can have several hardware timers. You choose one of these timers to use
for timer_*() functions in the startup code and timer_*()
kernel callouts.
In general, hardware timers either count up or count down and may or may not be auto-reset
(also called periodic).
The kernel uses a hardware timer to generate a periodic interrupt (i.e., the clock tick).
The kernel uses this interrupt for:
- Updating the system time and other software clocks
- Firing software timers
- Thread scheduling
Kernel callouts
The kernel interacts with the specified hardware timer through a set of timer kernel
callouts.
- timer_load()
- The kernel assumes that the hardware timer starts at 0, counts up to a
number (the divisor value), and then generates an interrupt. The kernel uses
the following method to specify a divisor value for the hardware timer:
-
- The kernel provides the divisor value to be loaded into the hardware timer,
by writing the value in the timer_load field in the
qtime_entry element of the system page.
- The kernel calls timer_load().
- Because the kernel doesn't know the characteristics of the hardware
timer, timer_load() validates the divisor value.
For example, if the divisor value provided by the kernel is too
high, the callout writes the maximum divisor value supported
by the hardware timer into the hardware timer.
- The callout copies the value written to the hardware timer
into the timer_load field in
qtime_entry.
- The kernel reads the timer_load field in
qtime_entry to see what the callout
wrote to the hardware timer.
- timer_reload()
- The kernel assumes that the hardware timer auto-resets (i.e., it's
periodic). If the timer does not auto-reset, you must implement the
timer_reload() callout. The kernel calls
timer_reload() at the beginning of the interrupt.
- If this callout returns 1, the interrupt is treated as
a clock tick. This return value is useful when several interrupt sources
can generate the same interrupt, to distinguish a clock tick from the
other sources.
- timer_value()
- If the kernel wants to know when to expect the next interrupt, it calls the
timer_value() callout and uses the following formula:
jiffies_until_interrupt = divisor_value - timer_value()
where a jiffy is how long it takes for the timer count to increment by one.
- If the hardware timer counts down, the timer_value()
callout performs a calculation to provide a value that is equivalent
to one from a count-up timer. The following pseudo-code is an example of the
timer_value calculation for a
timer_value() callout:
curr_hw_timer_value = // read hardware timer value here
value = divisor_value - curr_hw_timer_value
return value