《原子Linux驱动开发》基础阅读5:Linux内核定时器
[复制链接]
定时器是我们最常用到的功能,一般用来完成定时功能。Linux内核提供的定时器API函数,通过这些定时器API函数可以完成很多要求定时的应用。Linux内核也提供了短延时函数,比如微秒、纳秒、毫秒延时函数。
Linux内核中有大量的函数需要时间管理,比如周期性的调度程序、延时程序、对于驱动程序最常用的定时器。硬件定时器提供时钟源,时钟源的频率可以设置,设置好以后就周期性地产生定时中断,系统使用定时中断来计时。中断周期性产生的频率就是系统频率,也叫作系统节拍率(tick rate),单位是Hz,比如1000Hz、100Hz等就是指系统频率。
系统频率是可以设置的,我们在编译Linux内核的时候可以通过图形化界面设置系统节拍率,按照如下路径打开配置界面:
-> Kernel Features
->Timer frequency(<choice>[=y])
选中“Timerfrequency”,可选的系统频率为100Hz、200Hz、250Hz、300Hz、500Hz和1000Hz,认情况下选择100Hz。设置好以后打开Linux内核源码根目录下的.config文件,Linux内核会使用CONFIG_HZ来设置自己的系统时钟。
Linux 驱动的时候会常常用到 HZ,因为 HZ 表示一秒的节拍数,也就是频率,系统频率默认为 100Hz,为什么这么小? 100 Hz是系统频率里面最小的,为什么不选择大一点的呢?这里就引出了一个间题,高节拍率和低节拍率。
高节拍率和低节拍率的优缺点.
- 高节拍率会提高系统时闻精度,如果采用100 Hz 的节拍率, 时间精度就是 10ms, 采用1000Hz 的话时间精度就是1ms,精度提高了 10倍,高精度时钟的好处有很多,对于那些对时间要求严格的函数来说,能够以更高的精度运行,时间测量也更加准确;
- 高节拍率会早致中断的产生更加频繁,频繁的中断会加剧系统的负担,1000 Hz和100Hz的系统节拍率相比,系统要花费10倍的“精力”去处理中断。中断服务函数占用处理器的时间增加,但是现在的处理器性能都很强大,所以采用 1000Hz 的系统节拍率并不会增増加太大的负载压力。根据自己的实际情况,迭择合适的系统节拍率,本书全部采用默认的 100Hz 系统节拍率。 定时器是一个很常用的功能,需要周期性处理的工作都要用到定时器。Linux 内核定时器采用系统时钟来实现,并不是我们在课机篇中介绍的硬件定时器,Linux 内核定时器使用很简单,只需要提供超时时间(相当子定时值)和定时处理函数即可,当超时到了以后,设置的定时处理函数就会执行,和我们使用硬件定时器的套路一样,只是使用内核定时器不需要做一大堆的寄存器初始化工作,在使用内核定时器的时侯要注意一点:内核定时器并不是周期性运行的,超时以后就会自动关闭,因此如果想要实现周期性定时,那么就需要在定时处理函数中重新开启定时器,Linux 内核使用timer_list结构体表示内核定时器, timer_list 定义在文件 include/ linux/timer. h中0
前面说了HZ表示每秒的节拍数,jifies表示系统运行的jiffies节拍数,所以jiffies/HZ就是系统运行时间,单位为秒。不管是32位还是64位的jifies,都有溢出的风险,溢出以后会重新从0开始计数,相当于绕回来了,因此有些资料也将这个现象也叫作绕回。假如HZ为最大值1000的时候,32位的jiffies只需要49.7天就发生了绕回,对于64位的jiffies来说大概需要5.8亿年才能绕回,因此jiffies_64的绕回可以忽略不计。处理32位jiffies的绕回显得尤为重要,Linux内核提供了API函数来处理绕回。
处理绕回的API函数:
|