Таймеры очень легко использовать. Необходимо выполнить некоторые начальные действия, указать момент времени окончания ожидания, указать функцию, которая будет выполнена, когда закончится интервал времени ожидания, и активизировать таймер. Указанная функция будет выполнена, когда закончится интервал времени таймера. Таймеры
Таймеры представлены с помощью структур timer_list
, которая определена в файле
следующим образом.
struct timer_list {
struct list_head entry; /* таймеры хранятся в связанном списке */
unsigned long expires; /* время окончание срока ожидания в
импульсах системного таймера (jiffies) */
spinlock_t lock; /* блокировка для защиты данного таймера */
void (*function)(unsigned long); /*функция-обработчик таймера */
unsigned long data; /* единственный аргумент обработчика */
struct tvec_t_base_s *base; /* внутренние данные таймера, не трогать! */
};
К счастью, использование таймеров не требует глубокого понимания назначения полей этой структуры. На самом деле, крайне не рекомендуется использовать поля этой структуры не по назначению, чтобы сохранить совместимость с возможными будущими изменениями кода. Ядро предоставляет семейство интерфейсов для работы с таймерами, чтобы упростить эту работу. Все необходимые определения находятся в файле
. Большинство реализаций находится в файле kernel/timers
.
Первый шаг в создании таймера — это его объявление в следующем виде.
struct timer_list my_timer;
Далее должны быть инициализированы поля структуры, которые предназначены для внутреннего использования. Это делается с помощью вспомогательной функции перед вызовом любых функций, которые работают с таймером.
init_timer(&my_timer);
Далее необходимо заполнить все остальные поля структуры, например, следующим образом.
my_timer.expires = jiffies + delay; /* интервал времени таймера
закончится через delay импульсов */
my_timer.data = 0; /* в функцию-обработчик будет передан параметр,
равный нулю */
my_timer.function = my_function; /* функция, которая будет выполнена,
когда интервал времени таймера истечет */
Значение поля my_timer.expires
указывает время ожидания в импульсах системного таймера (необходимо указывать абсолютное количество импульсов). Когда текущее значение переменной jiffies
становится большим или равным значению поля my_timer.expires
, вызывается функция-обработчик my_timer.function
с параметром my_timer.data
. Как видно из описания структуры timer_list
, функция-обработчик должна соответствовать следующему прототипу.
void my_timer_function(unsigned long data);
Параметр data
позволяет регистрировать несколько таймеров с одним обработчиком и отличать таймеры с различными значениями этого параметра. Если в аргументе нет необходимости, то можно просто указать нулевое (или любое другое) значение.
Последняя операция — это активизация таймера.
add_timer(&my_timer);