内核定时器使用--定时器底层驱动

来源:https://zhuanlan.zhihu.com/p/629349072

Linux内核时间管理

 Linux系统在运行的时候有大量的函数需要时间管理,比如调度程序、延时程序等。并且我们在驱动开发的时候很要用各种定时器。硬件系统在系统运行时会周期性产生中断,系统使用定时中断来提供时钟源。时钟源的频率可以设置,设置好以后就会产生定时中断,系统通过这个定时中断来定时。中断周期产生的频率叫做系统频率(节拍率tick rate)。系统频率在编译内核的时候可以根据需求设置(设置路径为Kernel Features--->Timer frequency).

 默认情况下系统节拍率是100HZ。如果选择较高的节拍率会提高系统时间精度,但是会导致中断产生的频繁,会产生不必要的开销.

系统节拍数

 Linux内核中有个全局变量jiffies,用来记录系统自启动以来的运行的节拍数,系统在启动时会将jiffies初始化为0,变量会根据节拍率自增。jiffies的定义在内核文件include/linux/jiffies.h中.

 Linux内核中有个全局变量jiffies,用来记录系统自启动以来的运行的节拍数,系统在启动时会将jiffies初始化为0,变量会根据节拍率自增。jiffies的定义在内核文件include/linux/jiffies.h中

extern u64 __jiffy_data jiffies_64;
extern unsigned long volatile __jiffy_data jiffies;

 可以从数据类型看出来,其中第一个是一个64位的整形变量,第二个是个32为的长整型变量。所以第一个是供64位系统使用的,并且为了兼容不同的硬件,jiffies是jiffies_64的低32位。数据结构是这样的

 当我们访问变量jiffies的时候,其实是访问了jiffies_64的低32位。所以不管是32位的系统还是64位的系统,我们都可以使用jiffies来获取值。

内核定时器

 知道了内核的时间管理,就可以使用超时来实现定时功能了。

struct timer_list {
    /*
     * All fields that change during normal runtime grouped to the
     * same cacheline
     */
    struct list_head entry;
    unsigned long expires;
    struct tvec_base *base;

    void (*function)(unsigned long);
    unsigned long data;

    int slack;

#ifdef CONFIG_TIMER_STATS
    int start_pid;
    void *start_site;
    char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
    struct lockdep_map lockdep_map;
#endif
};
  • expiers,就是超时时间,但注意这个参数的单位是节拍数。需要在使用的过程中将指定的时间换算成对应的节拍数。

  • function是定时器的回调函数。注意是个函数指针。

常用API

posted @ 2023-11-13 13:18  caseyzz  阅读(51)  评论(0)    收藏  举报