内核定时器编程

内核定时器是通过硬件定时器驱动实现的,时钟中断触发后检查并执行到期的定时器处理函数。在Linux驱动编程中,开发者可以使用内核提供的函数和结构体如time_list来创建和管理定时任务。定时器处理函数执行完毕后通常会重新设置过期时间并重新加入到内核定时器链表,以待下次触发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

软件意义上的定时器最终以来硬件定时器来实现,内核在时钟中断发生后执行检测各定时器是否到期,到期后的定时器处理函数将作为软中断在底半部执行。实质上,时钟中断处理程序会唤起TIMER——SOFTIRQ软中断,运行当前处理器上到期的所有定时器。

在LINUX驱动编程中,可以利用Linux内核中提供的一组函数和数据结构来完成定时触发工作或完成某周期性的事务。

time_list结构体的一个实例对应一个定时器。

struct timer_list {
    struct list_head entry; /* 定时器列表 */
    unsigned long expires;  /* 定时器到期时间 */
    void (*function)(unsigned long);    /* 定时器处理函数 */
    unsigned long data;     /* 作为参数被传入定时器处理函数 */
    struct timer_base_s *base;
    ... 
};

内核定时器使用模板:

/* xxx设备结构体 */
struct xxx_dev {
    struct cdev cdev;
    ... 
    timer_list xxx_timer;   /* 设备要使用的定时器 */
};

/* xxx驱动中的某函数 */
xxx_funcl(...)
{
    struct xxx_dev *dev = filp->private_data;
    ... 
    /* 初始化定时器 */
    init_timer(&dev->xxx_timer);
    dev->xxx_timer.function = &xxx_do_timer;
    dev->xxx_timer.data = (unsigned long)dev;   /* 设备结构体指针作为定时器处理函数参数 */

    dev->xxx_timer.expires = jiffies + delay;
    /* 添加(注册)定时器 */
    add_timer(&dev->xxx_timer);
    ... 
}

/* xxx驱动中的某函数 */
xxx_fun2(...)
{
    ....
    /* 删除定时器 */
    del_timer(&dev->xxx_timer);
    ... 
}

/* 定时器处理函数 */
static void xxx_do_timer(unsigned long arg)
{
    struct xxx_device *dev = (struct xxx_device *)(arg);
    ... 
    dev->xxx_timer.expires = jiffies + delay;
    add_timer(&dev->xxx_timer);
    ... 
}

定时器的到期时间往往是在目前jiffies的基础上添加一个时延,若为HZ,则表示1s.

在定时器处理函数中,在做完相应的工作后,往往会延后expires并将定时器再次添加到内核定时器链表,以便能再次被触发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值