定时器初步认识(二)

时间:2022-01-05 23:32:40
转:
1、内核中最终的计时资源是定时器。定时器用于定时器超时处理程序在未来某个特定时间点执行,或者周期性的
     轮询硬件的状态。Linux提供了内核定时器完成这类工作。
2、定时器的只需要执行一些初始化的操作,如:
(1)设置一个超时时间
(2)指定超时要调用的函数
(3)然后激活定时器就可以了。
3、它的处理和工作队列还是有点类似的。和任务队列一样,内核定时器并不是周期运行,它在超时后自动销毁。
      因此,如果要实现周期轮询,就需要在定时器执行函数返回前再次激活定时器。
4、内核定时器是在时钟中断发生后,作为软中断在下半部的上下文中执行的。所有的定时器结构都以链表的形式
      存储,时钟中断发生后,内核按链表顺序依次执行。

5、注意:内核定时器发在软中断中,定时器执行函数不能够睡眠,也不能够持有信号量。
      一个变通的做法是在内核定时器执行函数里调用工作队列,在工作队列处理函数中实现对硬件的访问。

6、代码实例

struct test_data
{
    struct timer_list test_timer;
    struct work_struct test_poll_work;
};
struct test_data *exam;

static void work_func(struct work_struct *work )
{
    //具体的工作
}
void poll_func(unsigned long arg)
{
    prink("hello\n");
    mod_timer(&(reg_data->test_timer), jiffies + HZ*1);
    schedule_work(&(exam->test_poll_work));
}
exam = kzalloc(sizeof(*exam), GFP_KERNEL);
init_timer(&exam->test_timer);       
exam->test_timer.function = poll_func;
exam->test_timer.data = 0;
exam->test_timer.expires = jiffies + HZ*1;
add_timer(&(exam->test_timer));
INIT_WORK(&(exam->test_poll_work), work_func);