The kernel uses the timer kernel callouts to work with the hardware timer (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 (for example, timer_start()) 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 one of the hardware timers to generate a period interrupt (that is,
the clock tick). The tasks that the kernel uses this interrupt for include:
- 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 places the divisor value to load into the hardware timer
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 kernel callout writes the maximum divisor value supported
by the hardware timer to the hardware timer.
- The kernel callout writes the value written to the hardware timer
into the timer_load field in
qtime_entry so that the kernel can see which
value was actually used.
- The kernel reads the timer_load field in
qtime_entry to see what the kernel callout
wrote to the hardware timer.
- timer_reload()
- The kernel assumes that the hardware timer auto-resets (that is, is
periodic). If the timer does not auto-reset, you implement the
timer_reload() kernel callout. The kernel calls
timer_reload() at the beginning of the interrupt.
- If timer_reload() returns 1, the interrupt is treated as
a clock tick. This return value is useful when several interrupts sources
can generate the same interrupt, to distinguish a clock tick interrupt from
other interrupt sources.
- timer_value()
- If the kernel wants to know when to expect the next interrupt, it calls the
timer_value() kernel callout and 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()
kernel callout performs a calculation to provide a value that is equivalent
to one from a count-up timer. The following code is an example of the
timer_value calculation for a
timer_value() kernel callout:
-
curr_hw_timer_value = // read hardware timer value here
value = divisor_value - curr_hw_timer_value
return value;