linux kernel 内核定时器

本文介绍了一个使用Linux内核定时器与工作队列相结合的例子。通过两个定时器周期性地触发工作队列中的任务,并统计任务执行次数及失败情况。展示了如何初始化定时器、设置超时函数以及如何在超时函数中调度工作队列。
摘要由CSDN通过智能技术生成

1.涉及函数

// 1. 初始化定时器队列结构
    init_timer(&buttons_timer);

// 2. 定时器超时函数
    buttons_timer.function = buttons_timer_function; 

// 3.或者初始化定时器和超时函数作为一步(data作为fn的参数)
setup_timer(timer, fn, data)    

// 4. 添加定时器 
    add_timer(&buttons_timer); 

// 5. 设置定时器超时时间 1\100 s(修改一次超时时间只会触发一次定时器)
mod_timer(&buttons_timer, jiffies+HZ/100); 

// 6.删除定时器
del_timer(&timer);

2.demo

工作队列通过定时器超时函数自动调度工作

#include linux/init.h>
#include linux/module.h>
#include linux/moduleparam.h>
#include linux/time.h>
#include linux/timer.h>
#include linux/workqueue.h>
#include asm/atomic.h>
MODULE_AUTHOR("lcw");
MODULE_LICENSE("GPL");

struct timer_data {
        struct timer_list timer;
        struct workqueue_struct *work_queue;
        unsigned long prev_jiffies;
        unsigned int loops;
};

static struct timer_list timer1;
static struct timer_list timer2;

static void do_work(void *);
static DECLARE_WORK(test_work, do_work, NULL);
static DECLARE_WORK(test_work1, do_work, NULL);
static struct workqueue_struct *test_workqueue;
atomic_t wq_run_times;
unsigned int failed_cnt = 0;


// 定时器1超时函数
void test_timer_fn1(unsigned long arg)
{
        struct timer_data *data = (struct timer_data *)arg;

        mod_timer(&timer1, jiffies+HZ/100); // 设置超时时间 1\100s 


        if (queue_work(test_workqueue, &test_work)== 0) {
                printk("Timer (0) add work queue failed\n");
                (*(&failed_cnt))++;
        }
        data->loops++;
        printk("timer-0 loops: %u\n", data->loops);
}


// 定时器2超时函数
void test_timer_fn2(unsigned long arg)
{
        struct timer_data *data = (struct timer_data *)arg;

        mod_timer(&timer2, jiffies+HZ/100); // 设置超时时间 1\100s 


        //if (queue_work(test_workqueue, &test_work)== 0) {
        if (queue_work(test_workqueue, &test_work1)== 0) {
                printk("Timer (1) add work queue failed\n");
                (*(&failed_cnt))++;
        }
        data->loops++;
        printk("timer-1 loops: %u\n", data->loops);
}



// work func
void do_work(void*arg)
{
        //原子计数值加一
        atomic_inc(&wq_run_times);
        printk("====work queue run times: %u====\n", atomic_read(&wq_run_times));
        printk("====failed count: %u====\n",*(&failed_cnt));
}





// init
int wq_init(void)
{

//原子计数值初始化
        atomic_set(&wq_run_times, 0);

// work queue        
        test_workqueue = create_singlethread_workqueue("test-wq");

// timer1
        init_timer(&timer1);
        timer1.function= test_timer_fn1;
        add_timer(&timer1);


// timer2
        init_timer(&timer2);
        timer2.function= test_timer_fn1;
        add_timer(&timer2);

//设置超时时间,启动定时器
       mod_timer(&timer1, jiffies+HZ/100); // 设置超时时间 1\100s 
        mod_timer(&timer2, jiffies+HZ/100); // 设置超时时间 1\100s 


        return 0;
}

void wq_exit(void)
{
        del_timer(&test_data.timer);
        del_timer(&test_data1.timer);
        destroy_workqueue(test_workqueue);
        printk("wq exit success\n");
}

module_init(wq_init);
module_exit(wq_exit)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值