嵌入式Linux热门培训内容之Linux内核定时器

时间:2018-12-13 17:39:24

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 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 <linux/timer.h>

以下列出常用的接口:

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