Linux内核定时功能

  • 配置内核系统节拍率
  1. 图形化界面配置 -> Kernel Features
                                ->Timer frequencey (<choise> [=y])
  2. in .config 文件
    CONFIG_HZ_100=y
    CONFIG_HZ=100
  3. in include/asm-generic/param.h
    #define HZ CONFIG_HZ
  4. 高节拍和低节拍的优缺点:
    ①、高节拍率会提高系统时间精度,如果采用 100Hz 的节拍率,时间精度就是 10ms,采用
    1000Hz 的话时间精度就是 1ms,精度提高了 10 倍。高精度时钟的好处有很多,对于那些对时
    间要求严格的函数来说,能够以更高的精度运行,时间测量也更加准确。
    ②、高节拍率会导致中断的产生更加频繁,频繁的中断会加剧系统的负担,1000Hz 和 100Hz
    的系统节拍率相比,系统要花费 10 倍的“精力”去处理中断。中断服务函数占用处理器的时间
    增加,但是现在的处理器性能都很强大,所以采用 1000Hz 的系统节拍率并不会增加太大的负
    载压力。根据自己的实际情况,选择合适的系统节拍率,本教程我们全部采用默认的 100Hz 系
    统节拍率。
  • jiffies
    Linux 内核使用全局变量 jiffies 来记录系统从启动以来的系统节拍数,系统启动的时候会
    将 jiffies 初始化为 0,jiffies 定义在文件 include/linux/jiffies.h 中,定义如下:
    示例代码 50.1.1.2 include/jiffies.h 文件
    jiffies_64 和 jiffies 其实是同一个东西,jiffies_64 用于 64 位系统,而 jiffies 用于 32 位系统。
    为了兼容不同的硬件,jiffies 其实就是 jiffies_64 的低 32 位
    #include "include/linux/jiffies.h"
    
    extern u64 __jiffy_data jiffies_64;
    extern unsigned long volatile __jiffy_data jiffies;
    
    /*unkown通常为jiffies,known通常是需要对比的值*/
    time_after(unkown, known)
    time_before(unkown, known)
    time_after_eq(unkown, known)
    time_before_eq(unkown, known)
  •  Linux内核提供了几个jiffies和ms,us,ns之间的转换函数
     
    
    /*将jiffies类型的参数j分别转换为对应的毫秒,微秒,纳秒*/
    int jiffies_to_msecs(const unsigned long j)
    int jiffies_to_usecs(const unsigned long j)
    u64 jiffies_to_nsecs(const unsigned long j)
    /*将毫秒,微秒,纳秒转换为jiffies类型*/
    long msecs_to_jiffies(const unsigned int m)
    long usecs_to_jiffies(const unsigned int u)
    unsigned long nsecs_to_jiffies(u64 n)
    
  • 内核短延时函数
    
    /*纳秒,微秒和毫秒延时函数*/
    void ndelay(unsigned long nsecs)
    void udelay(unsigned long usecs)
    void mdelay(unsigned long mseces)
  • 内核定时器
    定时器是一个很常用的功能,需要周期性处理的工作都要用到定时器。Linux 内核定时器
    采用系统时钟来实现,并不是我们在裸机篇中讲解的 PIT 等硬件定时器。Linux 内核定时器使
    用很简单,只需要提供超时时间(相当于定时值)和定时处理函数即可,当超时时间到了以后设
    置的定时处理函数就会执行,和我们使用硬件定时器的套路一样,只是使用内核定时器不需要
    做一大堆的寄存器初始化工作。
    在使用内核定时器的时候要注意一点,内核定时器并不是周期
    性运行的,超时以后就会自动关闭,因此如果想要实现周期性定时,那么就需要在定时处理函
    数中重新开启定时器。
    #include "include/linux/timer.h"
    
    struct timer_list {
      struct list_head entry;
      unsigned long expires;           /* 定时器超时时间,单位是节拍数*/
      struct tvec_base *base;
    
      void (*function)(unsigned long); /*定时处理函数*/
      unsigned long data;              /*要传递给function函数的参数*/
    
      int slack;
    };
    
    void init_timer(struct timer_list *timer)
    
    /*向 Linux 内核注册定时器,使用 add_timer 函数向内核注册定时器以后,
    定时器就会开始运行
    */
    void add_timer(struct timer_list *timer)
    
    /*删除一个定时器,不管定时器有没有被激活,都可以使用此函数删除。
    在多处理器系统上,定时器可能会在其他的处理器上运行,因此在调用 del_timer 函数删除定时
    器之前要先等待其他处理器的定时处理器函数退出
    返回值:0,定时器还没被激活;1,定时器已经激活。
    */
    int del_timer(struct timer_list *timer)
    
    /*del_timer 函数的同步版,会等待其他处理器使用完定时器再删除,
    返回值:0,定时器还没被激活;1,定时器已经激活
    del_timer_sync 不能使用在中断上下文中
    */
    int del_timer_sync(struct timer_list *timer)
    
    /*用于修改定时值,如果定时器还没有激活的话,mod_timer 函数会激活定时
    器
    expires:修改后的超时时间
    返回值:0,调用 mod_timer 函数前定时器未被激活;1,调用 mod_timer 函数前定时器已
    被激活
    */
    int mod_timer(struct timer_list *timer, unsigned long expires)
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值