首页 > > > Linux内核定时器
Linux内核定时器是非常关键的一个部分,大家从学单片机开始,到后面的多任务系统,到RTOS,到Linux,发现延时这个东西是必不可少的,所以这个章节是非常关键的。
1、mdelay和msleep
我们在编写Linux内核驱动的时候,肯定避免不了用延迟函数,为了等待硬件到达一定的状态,下面来讨论一下Linux内核里面的几个延迟函数
ndelay(unsigned long nsecs)
udelay(unsigned long usecs)
mdelay(unsigned long msecs)
msleep()
msleep()是让当前进程休眠,让出CPU给其它进程使用,等到时间到了之后再唤醒。由此看来,msleep()不能用于中断上下文中。
mdelay()是一个让CPU空转,一直等待到给定的时间后才退出。
所以内核里面有这样一段话,大家自行体会一下:
mdelay is macro wrapper around udelay, to account for possible overflow when passing large arguments to http://udelay.In general, use of mdelay is discouraged and code should be refactored to allow for the use of msleep
!!!内核建议使用msleep,而不是mdelay
2、定时器基础
2.1、struct timer_list
一个struct timer_list对应了一个定时器。
#include
以下列出常用的接口:
struct timer_list
{
/*....*/
unsigned long expires;//定时器服务函数开始执行时间
void (*function)(unsigned long);//定义一个指向定时器服务函数的指针function,服务函数有一个 unsigned long的参数,并且返回void
unsigned long data;//定时时间到时,data参数会传入服务函数
}
2.2、jiffies
全局变量jiffies用来记录自系统启动以来产生的节拍的总数。启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。一秒内时钟中断的次数等于Hz,所以jiffies一秒内增加的值也就是Hz。
HZ:这个可以认为是一个频率,一秒内系统时钟中断的次数
Jiffies/HZ:我想知道从系统开机到现在系统运行了多少秒,可以这样计算
jiffies类型为无符号长整型(unsigned long)
当jiffies的值超过它的最大存放范围后就会发生溢出。对于32位无符号长整型,最大取值为(2^32)-1,即429496795。如果节拍计数达到了最大值后还要继续增加,它的值就会回绕到0。
2.3、使用定时器步骤
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.4、实例分析
#include
#include
#include
#include /*timer*/
#include /*jiffies*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Qifa");
MODULE_DESCRIPTION("Timer Module");
MODULE_ALIAS("timer module");
struct timer_list timer;
void timer_function(int para)
{
static int i = 0;
printk("#########%d########Timer Expired and para is %d !!\n",i++,para);
printk("jiffies:%lu jiffies/Hz: %lu HZ:%d\n",jiffies,(jiffies/HZ),HZ);
mod_timer(&timer,jiffies+(2*HZ));
}
int timer_init(void)
{
init_timer(&timer);
timer.data = 5;
timer.expires = jiffies + (1 * HZ);
timer.function = timer_function;
add_timer(&timer);
return 0;
}
void timer_exit(void)
{
del_timer( &timer );
}
module_init(timer_init);
module_exit(timer_exit);

原文作者:;如有侵权,请联系管理员删除。