linux 定时器_LINUX内核定时器

3e1d0823fbd0738381b6b073aae01d06.gif嵌入式linux QQ交流群:175159209,欢迎爱好者加入交流技术问题!

引言:linux从内核2.6.16开始引入了高精度定时器,达到ns级别。自此,内核拥有两套并行计时器,低精度和高精度。如果高精度没有开启,即使使用高精度函数,默认使用的仍旧是低精度。

高精度: 

虽然内核已经支持高精度,但是对于不少产品而言,由于内核是裁剪的,配置的时候并没有加入编译进去,虽然对应的内核源码中有相关代码。如果想支持,那么可以进入内核源码,执行make menuconfig。去查看当前系统是否支持高精度,(备注:因为里面选项比较多,还可以直接去查看编译好的.config文件,看里面是否有CONFIG_HIGH_RES_TIMERS,如果有,就通过make menuconfig开启,没有的话,就是不支持),是否真正启用,可以在内核中对相应宏进行打印。

低精度: 

(定时精度和频率HZ相关,精度为(1000/HZ ) ms)

#include  

void do_gettimeofday(struct timeval *tv);//获取精确时间函数 

//内核相关定义

struct timeval { 

  time_t tv_sec;       /* seconds */

  suseconds_t tv_usec; /* microseconds */ 

};

#define TIMER_TOTAL_NUM  2   //定义定时器总数

struct  timeval   tv;

struct  timer_list  funTimer[TIMER_TOTAL_NUM ]; //定义定时器相关结构体数组

short int siTimeInitFlag[TIMER_TOTAL_NUM  ]; //定时器初始化标志

short int siTimeoutFlag[TIMER_TOTAL_NUM  ];//定时器启动标志

typedef void (*pfTimerFunction)(unsigned long ulData);  //定义定时器处理函数指针,方便处理多个定时器

//定时器初始化

void timer_init(int iIndex, int iMs, pfTimerFunction pTimerFunction) 

{

    init_timer(&funTimer[iIndex]);//初始化

    funTimer[iIndex].function = pTimerFunction;//处理函数

    funTimer[iIndex].data = (unsigned long)iMs;//参数传递,在处理函数中可以不使用

    funTimer[iIndex].expires = jiffies + HZ; //定时时长设置为1s

    add_timer(&funTimer[iIndex]);//开启定时器

    siTimeInitFlag[iIndex] = 1;//初始标志置为1

    siTimeoutFlag[iIndex] = 1;//定时器启动标志

}

//定时器处理函数

static void timer_function(unsigned long ulData)

{

    /*

    这里写自己需要执行的功能.........

    .................

    //定时是否准确测试

    do_gettimeofday(&tv);//获取时间

    printk("time------%d:%d\n", tv.tv_sec, tv.tv_usec);//查看间隔,看定时时间是否精准

    */

    //循环定时器实现,如果不实现循环,可执行自己要实现的,再进行定时器删除,也可以不删除,到时后自动删除

    if(1 == siTimeoutFlag[0])

    {

        del_timer_sync(&funTimer[0]);//用del_timer_sync代替了del_timer

    }

    funTimer[0].function = timer_function;

    funTimer[0].expires = jiffies + HZ;//重新设置定时时间

    add_timer(&funTimer[0]);//启动定时器

    siTimeoutFlag[0] = 1;

}

//简单例子调用

int main(void)

{

    timer_init(0, 3, timer_function);

    return 0;

}

使用注意: 

1、加入初始化标志siTimeInitFlag[iIndex] 是防止定时器在运行时,再次初始化,这样会导致内核崩溃; 

2、使用循环定时器时, funTimer[0].expires = jiffies + HZ; funTimer的成员expires 必须重新赋值,且要执行 , 

add_timer(&funTimer[0]); 

3、定时时长funTimer[iIndex].expires = jiffies + HZ; //宏定义HZ可以查看源码,或者打印出来,jiffies 为节拍数,系统最高 

精度为(1000/HZ)ms。 

jiffies + HZ————-设置定时时长为1s; 

jiffies + 1—————设置定时时长为(1000/HZ)ms,是系统最高精度 

4、内核添加printk后,由于打印函数耗时,会导致执行时间延长,一个打印延长一般为ms级别

嵌入式Linux中文站

最专业的中文嵌入式Linux网站,8年磨剑,注册用户数万人

分享 嵌入式 & Linux 技术干货、教程、资讯、高薪职位

订阅点击标题下方“嵌入式Linux中文站”

分享点击右上角分享按钮

投稿admin@embeddedlinux.org.cn

交流QQ群:175159209

c308b8ba57c4ffe6bf1cb9f066bf81f9.gif

       点击下方“ 阅读原文 ”查看更多 296b2f712057705fbd1b2bc12873b60b.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值