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;
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)
{
}
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