linux内核定时器编程

来源:互联网 发布:域名再长狼也能记住 编辑:程序博客网 时间:2024/05/23 21:47

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的参数,并且返回void   unsigned 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
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <fcntl.h>  
  5. int main()  
  6. {  
  7. int fd;  
  8. int i;  
  9. int counter=0;  
  10. int old_counter=0;  
  11. fd=open("/dev/timer_dev",O_RDWR);  
  12. if(fd<0)  
  13. {  
  14. printf("open file error\n");  
  15. exit(1);  
  16. }  
  17. for(i=0;i<30;)//运行30s  
  18.   {  
  19.   read(fd,&counter,sizeof(int));  
  20.  if(counter!=old_counter)  
  21.     {  
  22.      printf("second=%d\n",counter);  
  23.      old_counter=counter;  
  24.     i++;  
  25.     }  
  26.   
  27.   }  
  28. close(fd);  
  29. exit (0);  
  30.   
  31. }  

测试结果 添加模块后使用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
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 穿抹胸很容易掉怎么办 抹胸衣服老掉怎么办 群里有低俗的人怎么办 老师不收礼物怎么办 发票跨年了怎么办 一用力就头疼怎么办 小孩天天玩游戏怎么办 手机分期人死了怎么办 人死了手机欠费怎么办 晚上想玩手机怎么办 孩子溺水后发烧怎么办 去台湾多次签证怎么办 怀孕不能玩手机怎么办 孕期天天玩手机怎么办 小孩子在家偷钱怎么办 小朋友被鸡抓伤怎么办 宝宝在学校不说怎么办? 宝宝不和小朋友玩怎么办 初中孩子不想上学怎么办 孩子装病不想上学怎么办 中学生叛逆不愿意上学怎么办 孩子去幼儿园哭闹怎么办 孩子哭闹不上学怎么办 孩子中班还哭怎么办 小孩子不爱上幼儿园怎么办 小孩子不爱去幼儿园怎么办 宝宝去幼儿园哭闹怎么办 宝宝上幼儿园哭闹怎么办 小朋友上幼儿园哭闹怎么办 迷路了怎么办幼儿故事 大班迷路了怎么办故事 玩手机眼睛干涩怎么办 宝睡觉不踏实怎么办 觉得自己老了怎么办 微信没自动扣费怎么办 东西放在家找不到怎么办 刚怀孕同房流产怎么办 开车遇上送葬的怎么办 流水钓鱼走漂怎么办 水库里小鱼太多怎么办 英国留学生怎么办澳签