Linux驱动timer定时器实例分析

1,相关头文件:

#include <linux/timer.h>

#include <linux/jiffies.h>

#include <linux/module.h>

2,相关函数介绍:

定义定时器结构体变量:

static struct timer_list test_timer;

初始化内核定时器:

init_timer(struct  timer_list *timer)

init_timer(&test_timer);

对timer_list成员变量进一步初始化:

 test_timer.function=&timer_func;

 test_timer.expires=jiffies + 100*(1000/HZ);

激活定时器

void add_timer(struct  timer_list *timer)

add_timer(&test_timer);

停止定时器

int del_timer(struct  timer_list *timer)

del_timer(&test_timer);

修改定时器expires
int mod_timer(struct timer_list * timer,unsigned long expires)//修改定时器的到期时间

mod_timer(&test_timer, jiffies + 100*(1000/HZ));

3,驱动例子:

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/cdev.h>

#include <linux/time.h>

#include <linux/timer.h>

#include <linux/jiffies.h>

#include <linux/miscdevice.h>

static struct timer_list test_timer;

static void timer_func(unsigned long data)

{

mod_timer(&test_timer,jiffies+100*(1000/HZ));

printk("test timer_func ++\n");

}

static int init_test_timer(void)

{

memset((void*)&test_timer,0,sizeof(test_timer));

test_timer.function=&timer_func;

test_timer.expires=jiffies+100*(1000/HZ);

init_timer(&test_timer);

add_timer(&test_timer);

return 0;

}

2 完整驱动实例:

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>

#include <linux/timer.h> 

#include <linux/time.h>

#include <linux/miscdevice.h>

#include <linux/jiffies.h>

#inlcude <linux/slab.h>

#include <asm/atomic.h> 
#define DEVICE_NAME "timertest"
/*test结构体*/
struct test_dev
{
  atomic_t counter;/* 一共经历了多少秒?(定义为原子量)*/
  struct timer_list test_timer; /*设备要使用的定时器*/ 
};


struct test_dev *test_devp; /*设备结构体指针*/

/*定时器处理函数*/
static void test_timer_handle(unsigned long arg)
{
  mod_timer(&test_devp->test_timer,jiffies + HZ);//定义定时器到期时间为1秒后 
  atomic_inc(&test_devp->counter);//该函数对原子类型变量v原子地增加1
  printk("current jiffies is %ld\n", jiffies);
}

/*文件打开函数*/
int test_open(struct inode *inode, struct file *filp)
{
  /*初始化定时器*/ 

  init_timer(&test_devp->test_timer);

  //进一步初始化定时器 

  test_devp->test_timer.function = &test_timer_handle;

  test_devp->test_timer.expires = jiffies + HZ;

 //激活定时器 

  add_timer(&test_devp->test_timer); /*添加(注册)定时器*/
  atomic_set(&test_devp->counter,0); //计数清0(原子操作之设置原子量counter为0)  
  return 0;
}
/*文件释放函数*/
int test_release(struct inode *inode, struct file *filp)
{
  del_timer(&test_devp->test_timer);//删除定时器 
   return 0;
}
/*test读函数*/
static ssize_t test_read(struct file *filp, char __user *buf, size_t count,
  loff_t *ppos)
{  
  int counter;
   counter = atomic_read(&test_devp->counter);//读取原子量counter的整数值
  if(put_user(counter, (int*)buf))//将counter写入用户空间
  return - EFAULT;
  else
  return sizeof(unsigned int);  
}
/*文件操作结构体*/
static const struct file_operations test_fops =
{
  .owner = THIS_MODULE, 
  .open = test_open, 
  .release = test_release,
  .read = test_read,
};

static struct miscdevice misc_test={

    .minor = MISC_DYNAMIC_MINOR,

    .name= DEVICE_NAME,

    .fops=&test_fops,

};


/*设备驱动模块加载函数*/
int test_init(void)
{
  int ret;
 ret=misc_register(&misc_test);
  if (ret < 0)
    return ret;
  /* 动态申请设备结构体的内存*/
  test_devp = kmalloc(sizeof(struct test_dev), GFP_KERNEL);
  if (!test_devp)    /*申请失败*/
  {
    ret =  - ENOMEM;
  }
  
  //清空设备结构
  memset(test_devp, 0, sizeof(struct test_dev));
  return 0;

}

/*模块卸载函数*/
void test_exit(void)
{
  misc_deregister(&misc_test);
  kfree(test_devp);     /*释放设备结构体内存*/
}


MODULE_AUTHOR("mhao");
MODULE_LICENSE("Dual BSD/GPL");
module_init(test_init);

module_exit(test_exit);


3,测试实例:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
int main(int argc char **argv)
{

  int fd;

  int counter = 0;

  int old_counter = 0;
  /*打开/dev/timertest设备文件*/
  fd = open("/dev/timertest", O_RDONLY);
  if (fd !=  - 1)
  {
  while (1)
   {
      read(fd,&counter, sizeof(unsigned int));//读目前经历的秒数

      if(counter!=old_counter)

      { 

      printf("seconds after open /dev/timertest :%d\n",counter);
      old_counter = counter;
      } 
    }    
  }
  else
  {
    printf("Device open failure\n");

  }

close(fd);

return 0;

4,运行结果:

seconds after open /dev/timertest :1
seconds after open /dev/timertest :2
seconds after open /dev/timertest :3
seconds after open /dev/timertest :4
seconds after open /dev/timertest :5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值