我是靠谱客的博主 完美茉莉,最近开发中收集的这篇文章主要介绍linux 驱动之定时器编程1、jiffies和HZ2、时间比较3、时间转换4、延时操作5、定时器编程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Table of Contents

1、jiffies和HZ

1.1、jiffies

1.2、HZ

2、时间比较

3、时间转换

4、延时操作

4.1、忙等待机制延时

4.2、让出cpu机制延时

5、定时器编程


1、jiffies和HZ


1.1、jiffies

  1. jiffies 是内核滴答定时器的计数值,每发生定时中断jiffies值就更新一次
  2. 内核源码针对32位和64位设计了jiffiesjiffies_64
  3. 正常一般都是使用jiffies,而设计jiffies的目的是考虑到32位jiffies会溢出
  4. 如果要读取jiffies_64的值必须使用get_jiffies_64函数,因为如果直接读取的话,jiffies_64的地32位值很快已经更新了,而那个函数保证的原子性

1.2、HZ

  1. 系统定时器频率,与体系结构相关,系统启动根据HZ设置定时器硬件
  2. HZ = (100) (ARM 平台 即周期是10ms)

使用实例:


unsigned long j,t1,t2;

j = jiffies ; //读取当前计数值

t1 = jiffies + 2*HZ; //未来2秒
t2 = jiffies + 2;    //未来20毫秒

2、时间比较


unsigned long cmp_time;

cmp_time = jiffies + HZ; //未来一秒

while(jiffies<cmp_time)
{

    //do things
}

以上代码看似合理,但是如果jiffies溢出就会出问题。

因此需要使用内核提供的时间比较函数才能更安全稳定

time_after(a,b) //如果a在b之后(a的时间点还没到达b的时间点)则返回true

time_before(a,b); //如果a在b之前(即a已经超过了b的时间点)则返回true

time_after_eq(a,b) //如果a在b之后或者相等则返回true

time_before_eq(a,b); //如果a在b之前或者相等则返回true

正确实例:

unsigned long cmp_time;

cmp_time = jiffies + HZ; //未来一秒

while(time_after(jiffies,cmp_time))
{

    //do things
}

 

3、时间转换


	int jiffies_to_msecs(const unsigned long j)
	int jiffies_to_usecs(const unsigned long j)
	u64 jiffies_to_nsecs(const unsigned long j)


	long msecs_to_jiffies(const unsigned int m)
	long usecs_to_jiffies(const unsigned int u) 
	unsigned long nsecs_to_jiffies(u64 n)

 

4、延时操作


4.1、忙等待机制延时

延时原理就是自加/减操作,类似于单片机裸机编程延时机制,这是牺牲cpu为代价的延时操作

内核提供的函数:

		//纳秒、微秒和毫秒延时函数。
	void ndelay(unsigned long nsecs)
	void udelay(unsigned long usecs) 
	void mdelay(unsigned long mseces)

 

4.2、让出cpu机制延时

让出cpu即延时的时候休眠,不占用cpu资源

内核提供的函数:

void msleep(usigned int msecs); //延时多少毫秒

 

5、定时器编程


 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <asm/gpio.h>
#include <plat/gpio-cfg.h>

//分配定时器
static struct timer_list mytimer;
static int mydata = 0x5555;

//超时处理函数
static void mytimer_func(unsigned long data)
{
    int *pdata = (int *)data;
    
    printk("hello,kernel, data = %#xn", *pdata);

    //重新添加定时器,如果不添加,定时器处理函数只执行一次
    mod_timer(&mytimer, jiffies + msecs_to_jiffies(2000));
}

static int mytimer_init(void)
{
    //初始化定时器
    init_timer(&mytimer);
    //指定定时器超时时候的时间
    mytimer.expires = jiffies + msecs_to_jiffies(2000); //2s
    mytimer.function = mytimer_func; //超时处理函数
    mytimer.data = (unsigned long)&mydata; //给超时处理函数传递参数

    //启动定时器
    add_timer(&mytimer);
    
    printk("add timer ok!n");
    return 0;
}

static void mytimer_exit(void)
{
    del_timer(&mytimer); 
    printk("del timer ok!n");
}
module_init(mytimer_init);
module_exit(mytimer_exit);
MODULE_LICENSE("GPL");

 

 

最后

以上就是完美茉莉为你收集整理的linux 驱动之定时器编程1、jiffies和HZ2、时间比较3、时间转换4、延时操作5、定时器编程的全部内容,希望文章能够帮你解决linux 驱动之定时器编程1、jiffies和HZ2、时间比较3、时间转换4、延时操作5、定时器编程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部