linux内核定时器编程
生活随笔
收集整理的這篇文章主要介紹了
linux内核定时器编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.linux內核定時器基本結構和函數
1)struct timer_list 一個struct timer_list對應了一個定時器。
#include <linux/timer.h>
以下列出常用的接口:
struct timer_list{/*....*/unsigned long expires;//定時器服務函數開始執行時間void (*function)(unsigned long);//定義一個指向定時器服務函數的指針function,服務函數有一個 unsigned long的參數,并且返回voidunsigned long data;//定時時間到時,data參數會傳入服務函數}void init_timer(struct timer_list* timer)//初始化一個定時器?
?
-----------使用定時器的步驟-------------- struct timer_list my_timer_list;//定義一個定時器,可以把它放在你的設備結構中 init_timer(&my_timer_list);//初始化一個定時器 my_timer_list.expire=jiffies+HZ;//定時器1s后運行服務程序 my_timer_list.function=timer_function;//定時器服務函數 add_timer(&my_timer_list);//添加定時器 void timer_function(unsigned long);//寫定時器服務函數 del_timer(&my_timer_list);//當定時器不再需要時刪除定時器 del_timer_sync(&my_timer_list);//基本和del_timer一樣,比較適合在多核處理器使用,一般推薦使用del_timer_sync?
-------------------------------------------------
2.以下是一個定時1s的驅動程序,直接上代碼
/***************************************************************** 原子操作,就是不能被更高等級中斷搶奪優先的操作。你既然提這個問題,我就說深一點。 由于操作系統大部分時間處于開中斷狀態,所以,一個程序在執行的時候可能被優先級更高的線程中斷。 而有些操作是不能被中斷的,不然會出現無法還原的后果,這時候,這些操作就需要原子操作。就是不能被中斷的操作。1.atomic_read與atomic_set函數是原子變量的操作,就是原子讀和原子設置的作用. 2.原子操作,就是執行操作的時候,其數值不會被其它線程或者中斷所影響 3.原子操作是linux內核中一種同步的方式 typedef struct { volatile int counter; } atomic_t;#define ATOMIC_INIT(i) { (i) }#define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) ******************************************************************/ #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> //#include <mach/regs-gpio.h> //#include <mach/hardware.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #include <asm/io.h> #include <asm/system.h> #include <asm/uaccess.h> #define TIMER_MAJOR 300 #define TIMER_MINOR 0 dev_t timer_dev_t;//設備號 dev_t timer_dev_major=TIMER_MAJOR; dev_t timer_dev_minor=TIMER_MINOR; struct TIMER_DEV { struct cdev cdev; atomic_t count; struct timer_list timer_list; }; struct TIMER_DEV* timer_dev; //---------timer interrupt function---------------- static void timer_function(unsigned long data) { mod_timer(&(timer_dev->timer_list),jiffies+HZ);//重新設置時間 printk("current jiffies is %ld,count=%d\n",jiffies,timer_dev->count); //(timer_dev->count)++; atomic_inc(&(timer_dev->count)); } //--------timer release function-------------------- static int timer_release(struct inode* inode, struct file* filp) { del_timer_sync(&(timer_dev->timer_list)); return 0; } //----------------file open function----------------- static int timer_open(struct inode* inode,struct file* filp) { init_timer(&(timer_dev->timer_list));//初始化定時器 timer_dev->timer_list.function=timer_function;//設置定時器處理函數 timer_dev->timer_list.expires=jiffies+HZ;//處理函數1s后運行 add_timer(&timer_dev->timer_list);//添加定時器 atomic_set(&(timer_dev->count),0); //原子操作函數return 0; } //-------------------------------------- //----------------timer_read function--------------- static int timer_read(struct file* filp,char __user *buf,size_t count,loff_t* f_pos) { unsigned int counter=atomic_read(&(timer_dev->count)); if(copy_to_user(buf,(unsigned int*)&counter,sizeof(unsigned int))) { printk("copy to user error\n"); goto out; } return (sizeof(unsigned int)); out: return (-EFAULT); } struct file_operations timer_ops={ .owner=THIS_MODULE, .open=timer_open, .read=timer_read, .release=timer_release, }; static int __init timer_init(void) { int ret; if(TIMER_MAJOR)//主設備號大于0,靜態申請設備號 { timer_dev_t=MKDEV(TIMER_MAJOR,TIMER_MINOR); ret=register_chrdev_region(TIMER_MAJOR,1,"timer_dev");//first,count,name } else { ret=alloc_chrdev_region(&timer_dev_t,0,1,"time_dev"); timer_dev_major=MAJOR(timer_dev_t); } if(ret<0) { printk("can't get major %d\n",timer_dev_major); return ret; } //----------------------------------------------------------- timer_dev=kmalloc(sizeof(struct TIMER_DEV),GFP_KERNEL); memset(timer_dev,0,sizeof(struct TIMER_DEV)); cdev_init(&(timer_dev->cdev),&timer_ops); //linux字符設備的注冊cdev_add(&(timer_dev->cdev),timer_dev_t,1); //添加字符設備printk("init timer_dev success\n"); return 0; } static void __exit timer_exit(void) { kfree(timer_dev); cdev_del(&(timer_dev->cdev)); unregister_chrdev_region(MKDEV(TIMER_MAJOR,0),1); } module_init(timer_init); module_exit(timer_exit);?
?
測試程序
[cpp] view plaincopy
測試結果 添加模塊后使用dmesg查看內核信息
[ 1239.176994] current jiffies is 235468,count=123
[ 1240.174459] current jiffies is 235718,count=124
[ 1241.171920] current jiffies is 235968,count=125
[ 1242.169383] current jiffies is 236218,count=126
測試程序的結果
second=1
second=2
second=3
second=4
second=5
second=6
second=7
second=8
second=9
second=10
second=11
?
總結
以上是生活随笔為你收集整理的linux内核定时器编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一键获取阿里巴巴主图视频细节图评论图的步
- 下一篇: linux tar压缩文件命令,tar打