Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1841201
  • 博文数量: 134
  • 博客积分: 2488
  • 博客等级: 大尉
  • 技术积分: 7554
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-26 21:19
个人简介

1.每日自省; 2.享受人生; 3.尽力而为; 4.坚持不懈; 5.切莫急躁; 6.慎言敏行; 7.动心忍性; 8.上善若水。

文章分类

全部博文(134)

文章存档

2014年(38)

2013年(42)

2012年(15)

2011年(39)

分类: 嵌入式

2013-12-25 09:28:01

一、HZ、jiffies
        HZ值是一个与体系结构有关的常数。其值表示每秒有多少次时钟中断。
        每次当时钟中断发生时,内核内部计数器的值就增加1,这个计数器的值在系统引导时被初始化为0,因此,它的值就是自上次操作系统引导以来的时钟滴答数,这个计数器是一个64位的变量(即使在32位架构上也是64位),称为“jiffies_64”,但是驱动程序开发者通常访问的是jiffies变量,它是unsigned long型变量,要么和jiffies_64相同,要么仅仅是jiffies_64的低32位,通常首选使用jiffies,因为它的访问很快,从而对64位jiffies_64值的访问并不需要在所有架构上都是原子的。jiffies和jiffies_64均应被看作只读变量。

点击(此处)折叠或打开

  1. #include <linux/jiffies.h>
  2. unsigned long j, stamp_1, stamp_half, stamp_n;
  3. j = jiffies; //读取当前值
  4. stamp_1 = j + HZ; //未来1秒
  5. stamp_half = j + HZ / 2; //半秒
  6. stamp_n = j + n *HZ / 1000; //n毫秒
二、短延迟

点击(此处)折叠或打开

  1. #include <linux/jiffies.h>
  2. int time_after(unsigned long a, unsigned long b);
  3. int time_before(unsigned long a, unsigned long b);
  4. int time_after_eq(unsigned long a, unsigned long b);
  5. int time_before_eq(unsigned long a, unsigned long b)
        如果a(jiffies的某个快照)所代表的时间比b靠后,则第一个宏返回真;如果a比b靠前,则第二个宏返回真;后面两个宏分别用来比较“靠后或者相等”及“靠前或者相等”。
        用等待队列实现延时:

点击(此处)折叠或打开

  1. wait_queue_head_t wait;
  2. init_waitqueue_head(&wait);
  3. wait_event_interruptible_timeout(wait, 0, delay)

点击(此处)折叠或打开

  1. #include <linux/delay.h>
  2. void ndelay(unsigned long nsecs);
  3. void udelay(unsigned long usecs);
  4. void mdelay(unsigned long msecs);
        这三个延迟函数均是忙等待函数,因而在延迟过程中无法运行其他任何任务。
三、定时器

3.1、内核timer定时器

        首先需要定义一个timer_list变量timer
        先初始化timer:

        init_timer(&timer);

        然后对timer的相关参数赋值:

        timer.function = fun;

        timer.expires = jiffies + TIMER_DELAY;
        timer.data = (unsigned long)dev;

        add_timer(&timer);

        在定时器时间到的时候,会执行fun,如果继续定时,可以通过在fun中执行:

        mod_timer(&timer, jiffies + TIMER_DELAY);

        在不需要的时候通过调用:

        del_timer(&timer);删除定时器。

        这样一个简单的定时器就完成了。

        内核定时器常常是作为“软件中断”的结果而运行的。在这种原子性的上下文中运行时,代码会受到许多限制,定时器函数必须以原子方式运行。
        任何通过定时器函数访问的数据结构都应该针对并发访问进行保护。

点击(此处)折叠或打开

  1. include <linux/timer.>

  2. struct timer_list {
  3. struct list_head list;
  4. unsigned long expires;
  5. unsigned long data;
  6. void (*function)(unsigned long);
  7. };
3.2、tasklet(小任务)和queue机制
        在第十章中讲述。
阅读(3192) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~