1. 程式人生 > >linux kernel 核心定時器

linux kernel 核心定時器

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)