内核定时器使用--定时器底层驱动
来源: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


浙公网安备 33010602011771号