我是靠谱客的博主 完美茉莉,最近开发中收集的这篇文章主要介绍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
- jiffies 是内核滴答定时器的计数值,每发生定时中断jiffies值就更新一次
- 内核源码针对32位和64位设计了jiffies和jiffies_64
- 正常一般都是使用jiffies,而设计jiffies的目的是考虑到32位jiffies会溢出
- 如果要读取jiffies_64的值,必须使用get_jiffies_64函数,因为如果直接读取的话,jiffies_64的地32位值很快已经更新了,而那个函数保证的原子性
1.2、HZ
- 系统定时器频率,与体系结构相关,系统启动根据HZ设置定时器硬件
- 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、定时器编程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复